> On Aug 13, 2014, at 1:49 AM, Matthew Gardiner <m...@csr.com> wrote:
> 
> Hi Greg,
> 
> Yes, it's clear that a planned attack is required for this. I understand the 
> need to have public and private state e.g. for source-level steps, and indeed 
> for launching a process. That's why I was a bit surprised to discover, after 
> debugging it, that the very first stop on "process launch" resulted in 
> ShouldBroadcastEvent returning true, as I thought that this would be an 
> instance where we'd like to hide this event from the user. I did spend 
> sometime trying to figure out how "ShouldStop" and "ShouldReportStop" worked, 
> but quickly found myself in the world of thread plans, a world in which I 
> know very little. So I'd certainly appreciate you guys, who have that 
> knowledge, thrashing this design out.
> 
> Having these (proposed) different ProcessState subclasses sounds to be a far 
> better solution than "broadcast hijacking + tricks". My only minor critique 
> of the design you floated being that you mentioned a "stack" of these 
> subclass instances, although when we receive an event (i.e. waitpid returns a 
> state change), it seems apparent that you'll then pass this event to (all) 
> the private and the public subclasses. (I tend to think of a stack as being a 
> system where you'd send the event to just the topmost element). Is there any 
> reason to have more just a private handler and a public handler?


I don't think Greg's description of the solution to handling driving the 
process was more than off the cuff comments.  I wouldn't parse it too closely.

Jim


> 
> Regarding simple, interim fixes, I did come up with something (which 
> addresses the observation associated with this thread's first post), which is 
> a little icky. I'll attach it though, to see if it attracts any comment. 
> Essentially, I have a flag which allows first stop to be identified, and 
> arranges that ShouldBroadcastEvent returns false for this stop. Also don't 
> push the IOHandler for launching state (I think it gets pushed later for the 
> running state), and force public state change after the first stop, which 
> seemed weird, but was required, due to the implementation of ProcessLaunch 
> waiting for the initial trap.
> 
> Anyway, thanks for you and Jim's interest in getting a good implementation 
> for this out there.
> 
> Matt
> 
> 
> Greg Clayton wrote:
>> Jim and I have discussed the right thing to do which we plan to implement as 
>> soon as we get the chance.
>> 
>> Current we have two process states: public and private. The private state is 
>> always up to date and is used to track what the process is currently doing. 
>> The public state gets set when we believe the end user should see an event 
>> that will update the GUI or TTY with the current state if needed (stopped or 
>> exited). There is a lot of tricky code that uses the private process state 
>> to manage things like the thread plans. Things like source level single step 
>> might involve starting and stopping and hitting breakpoints and single 
>> instruction stepping, but the user only wants to see the final eStateStopped 
>> when the source level step is done. Expressions are also tricky, the public 
>> state of the process is stopped, but when we run an expression, we might 
>> resume the process many times and the user will always see that the public 
>> state if stopped. Internally though the thread plans are doing a whole bunch 
>> of stuff to the process and the user never hears anything about these (no 
>> events!
  go public).
>> 
>> So the current public and private stuff uses broadcaster hijacking and all 
>> sorts of other tricks to avoid letting the end user know about the starts 
>> and stops that they shouldn't know about. We eventually want to have a new 
>> class, lets call in lldb_private::ProcessState for now, that manages the 
>> current process state and always receives the process events. There would be 
>> no more public and private events. We would have one version of the 
>> ProcessState subclass that would cause the GUI/TTY to update (replacing the 
>> public events) and one ProcessState subclass that would manage running 
>> thread plans. There would be stack of these and this will help us avoid the 
>> whole public/private/hijacking stuff we have now.
>> 
>> Launching a process would end up pushing a new ProcessState class that could 
>> handle all the necessary starts and stop we need to get the process to a 
>> quiescent state that is presentable to the user. The ProcessState subclass 
>> could eat all the events it needs to while launching and then propagate the 
>> stopped or running event when it gets popped off the stack.
>> 
>> So we should make some simple fixes for now to work around the issue and get 
>> things working, but it would also be great to get the new system up and 
>> running so we can make this easier in the future for people that want to 
>> make changes.
>> 
>> Greg
>> 
>> 
>>> On Aug 8, 2014, at 1:08 AM, Matthew Gardiner <m...@csr.com> wrote:
>>> 
>>> Folks,
>>> 
>>> Regarding "launching using the shell",  I don't think applies in the buggy 
>>> case that myself and Shawn are looking at.
>>> 
>>> I do:
>>> 
>>> (lldb) target create ./test
>>> ...
>>> (lldb) process launch
>>> ...
>>> 
>>> and when I inspected the call to exec, I see that my exe name is the 
>>> program passed.
>>> 
>>> Thanks for the insight into the broadcasting of stop events. That explains 
>>> why I see in the ShouldBroadcastEvent, the ShouldStop and ShouldReportStop 
>>> calls.
>>> 
>>> However, it would be nice to know if the first stop event should be 
>>> broadcast for "process launch".  I think it's an implementation detail, and 
>>> therefore should not. That would help to fix this issue.
>>> 
>>> However, Shawn's original suggestion to fix this issue circumvents the 
>>> above debate, by replacing the call of HandlePrivateEvent with 
>>> SetPublicState. So which fix is best? Calling SetPublicState rather than 
>>> HandlePrivateEvent is certainly more expedient, and avoids this debate... 
>>> but is it more portable/future-proof?
>>> 
>>> Matt
>>> 
>>> 
>>> jing...@apple.com wrote:
>>>> If you are launching using the shell, you'll see more stops before you get 
>>>> to the executable you are actually trying to launch.  In that case, 
>>>> instead of just running the binary directly you effectively do:
>>>> 
>>>> /bin/bash exec <binary> arg1 arg2
>>>> 
>>>> so that you can get bash (or whatever is set in $SHELL) to do the argument 
>>>> expansion for you.  GetResumeCountForLaunchInfo calculates this, then it 
>>>> is stuffed into the ProcessLaunchInfo (SetResumeCount).  On Mac OS X we 
>>>> always let the Platform launch, then attach, so in that case the 
>>>> AttachCompletionHandler does the extra resumes.  I'm not all that familiar 
>>>> with how the Linux side work, but it also seems to use the 
>>>> ProcessLaunchInfo's resume count.
>>>> 
>>>> Note that in general in lldb not all publicly broadcast stop messages are 
>>>> going to result in a stop.  For instance, all the breakpoint command & 
>>>> condition handling goes on as a result of the broadcast of the public stop 
>>>> event, but the process might just turn around an continue based on that.  
>>>> Whether to suppress the broadcast and continue from the private state 
>>>> thread or broadcast the event and let the upper levels of lldb take care 
>>>> of what happens from there on really depends on where it makes sense to 
>>>> handle the stop.  So for the case of breakpoint stops (or stop hooks, 
>>>> another example), those end up being equivalent to user typed commands, 
>>>> just done for the user automatically by the system.  So having them happen 
>>>> in a world where the public state wasn't sync'ed up to the private state 
>>>> ended up being very awkward.
>>>> 
>>>> I haven't looked at the launching code in detail recently so I am not sure 
>>>> whether it makes sense for the first stop to be handled as it is.
>>>> 
>>>> Jim
>>>> 
>>>> 
>>>>> On Aug 7, 2014, at 6:29 AM, Matthew Gardiner <m...@csr.com> wrote:
>>>>> 
>>>>> Hi Shawn,
>>>>> 
>>>>> I spent some time today looking at how to arrange for ShouldBroadcast to 
>>>>> return false for this first stop. I managed to produce a quick hack for 
>>>>> this (i.e. just counted the number of stops), but due to other 
>>>>> distractions (from the rest of my job) I didn't get that far into 
>>>>> discovering a nice way of achieving this...
>>>>> 
>>>>> What I did discover is that with my build just doing "process launch" 
>>>>> results in 3 stops (and 3 private resumes). That in itself I find 
>>>>> surprising, since I was under the impression that I should see the 
>>>>> inferior stop just once when exec is trapped by PTRACE_ME.
>>>>> 
>>>>> I then discovered that for each of these 3 stops ShouldBroadcast calls 
>>>>> Thread::ShouldStop, the Thread::ShouldStop returns true for the first 
>>>>> stop and false for the other 2. Looking into these behaviour differences 
>>>>> I then found that from within Thread::ShouldStop we then call into the 
>>>>> following:
>>>>> 
>>>>>    StopInfoSP private_stop_info (GetPrivateStopInfo());
>>>>>    if (private_stop_info && 
>>>>> private_stop_info->ShouldStopSynchronous(event_ptr) == false)
>>>>>    {
>>>>> 
>>>>> and also
>>>>> 
>>>>> bool over_ride_stop = current_plan->ShouldAutoContinue(event_ptr);
>>>>> 
>>>>> the results from either of these, it seems providing the reasoning behind 
>>>>> the different true/false returns. I'll return to spend a bit more time on 
>>>>> this tomorrow. Let me know if you get any further on a similar vein!
>>>>> 
>>>>> thanks
>>>>> Matt
>>>>> 
>>>>> 
>>>>> 
>>>>> Shawn Best wrote:
>>>>>> Matt,
>>>>>> 
>>>>>> I think you are probably right, although there are other places where it 
>>>>>> directly calls SetPublicState().   I was wondering about the possibility 
>>>>>> there could be other listeners waiting for a broadcast public Stop 
>>>>>> event.  Is that a possibility?
>>>>>> 
>>>>>> Some others here were investigating some unit tests that were failing 
>>>>>> intermittently (StopHook).  Their description of the problem sounds 
>>>>>> unrelated to the launch code, but this patch also magically fixes that.
>>>>>> 
>>>>>> Shawn.
>>>>>> 
>>>>>> On 8/6/2014 6:26 AM, Matthew Gardiner wrote:
>>>>>>> Shawn,
>>>>>>> 
>>>>>>> Like I said earlier your patch worked. However I think the right fix is 
>>>>>>> to arrange that ShouldBroadcast returns false for this first stop. I 
>>>>>>> believe this, because firstly no stops should be reported here since 
>>>>>>> the user is only interested in launching a program, and additionally 
>>>>>>> because it enables us to fix lldb without removing the call to 
>>>>>>> HandlePrivateEvent. This, I think, is important to preserve as the 
>>>>>>> central point for process state change handling.
>>>>>>> 
>>>>>>> Matt
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> Shawn Best wrote:
>>>>>>>> Hi Matthew,
>>>>>>>> 
>>>>>>>> I have also been tracking this bug.  I believe there are other bugs in 
>>>>>>>> the unit tests failing indirectly because of this.  I also have a 
>>>>>>>> patch that will fix it, but was sitting on it until the other one 
>>>>>>>> landed.  These bugs do not show up on OSX since the inferiors are 
>>>>>>>> launched separately then attached to.
>>>>>>>> 
>>>>>>>> The first odd thing the launching code does is push an IOHandler when 
>>>>>>>> it sees the state transition to 'launching'. This is odd because I 
>>>>>>>> believe the launching program will always come up in a stopped state 
>>>>>>>> which will immediately pop the IOHandler.
>>>>>>>> 
>>>>>>>> At launch, the process comes up in the stopped state.  The launch code 
>>>>>>>> manually calls HandlePrivateEvent() with the stop event, which then 
>>>>>>>> broadcasts the Event.  When HandleProcessEvent gets the public stop, 
>>>>>>>> it dumps out the current thread state just as if an executing inferior 
>>>>>>>> hit a breakpoint and stopped.
>>>>>>>> 
>>>>>>>> One way to fix this would be:
>>>>>>>> 
>>>>>>>> 1. Don't push io handler when state is 'launching'
>>>>>>>> 2. Instead of manually calling HandlePrivateEvent, call 
>>>>>>>> SetPublicState().
>>>>>>>> 
>>>>>>>> Alternately, we could try and debug why ShouldBroadcast() returns 
>>>>>>>> true, but that appears to be by design since it is expecting the 
>>>>>>>> public stop event to pop the IOHandler that had been pushed when 
>>>>>>>> launching.
>>>>>>>> 
>>>>>>>> I have attached a patch demonstrating this.  In conjunction with the 
>>>>>>>> other patch for IOHandler race condition, it will fix a bunch of this 
>>>>>>>> kind of behaviour.
>>>>>>>> 
>>>>>>>> Shawn.
>>>>>>>> 
>>>>>>>> On 8/5/2014 6:59 AM, Matthew Gardiner wrote:
>>>>>>>>> Jim,
>>>>>>>>> 
>>>>>>>>> I've been trying to debug an issue (I see it on 64-bit linux) where, 
>>>>>>>>> I do "target create" and "process launch" and despite not requesting 
>>>>>>>>> *stop at entry*, the first stop (which I believe is just the initial 
>>>>>>>>> ptrace attach stop) is reported to the lldb command line. I added 
>>>>>>>>> some fprintf to Process::HandlePrivateEvent, which counts the number 
>>>>>>>>> of eStoppedState events seen and whether ShouldBroadcastEvent returns 
>>>>>>>>> true for this event. Here's the output from my program with 
>>>>>>>>> diagnostic:
>>>>>>>>> 
>>>>>>>>> (lldb) target create ~/me/i64-hello.elf
>>>>>>>>> Current executable set to '~/me/i64-hello.elf' (x86_64).
>>>>>>>>> (lldb) process launch
>>>>>>>>> MG Process::HandlePrivateEvent launching stopped_count 0 
>>>>>>>>> should_broadcast 1
>>>>>>>>> Process 31393 launching
>>>>>>>>> MG Process::HandlePrivateEvent stopped stopped_count 1 
>>>>>>>>> should_broadcast 1
>>>>>>>>> MG Process::HandlePrivateEvent running stopped_count 1 
>>>>>>>>> should_broadcast 1
>>>>>>>>> Process 31393 launched: 'i64-hello.elf' (x86_64)
>>>>>>>>> Process 31393 stopped
>>>>>>>>> * thread #1: tid = 31393, 0x0000003675a011f0, name = 'i64-hello.elf', 
>>>>>>>>> stop reason = trace
>>>>>>>>>    frame #0: 0x0000003675a011f0
>>>>>>>>> -> 0x3675a011f0:  movq   %rsp, %rdi
>>>>>>>>>   0x3675a011f3:  callq  0x3675a046e0
>>>>>>>>>   0x3675a011f8:  movq   %rax, %r12
>>>>>>>>>   0x3675a011fb:  movl   0x21eb97(%rip), %eax
>>>>>>>>> (lldb) MG Process::HandlePrivateEvent stopped stopped_count 2 
>>>>>>>>> should_broadcast 0
>>>>>>>>> MG Process::HandlePrivateEvent running stopped_count 2 
>>>>>>>>> should_broadcast 0
>>>>>>>>> MG Process::HandlePrivateEvent stopped stopped_count 3 
>>>>>>>>> should_broadcast 0
>>>>>>>>> MG Process::HandlePrivateEvent running stopped_count 3 
>>>>>>>>> should_broadcast 0
>>>>>>>>> 
>>>>>>>>> In summary, lldb reports the inferior to be stopped (even though 
>>>>>>>>> /proc/pid/status and lldb "target list" say it is running). Clearly 
>>>>>>>>> this is wrong (hence my earlier post).
>>>>>>>>> 
>>>>>>>>> Am I correct in assuming that when  ShouldBroadcastEvent returns true 
>>>>>>>>> this means that lldb should show this event to the debug user? (And 
>>>>>>>>> thus hide other events where ShouldBroadcastEvent=false).
>>>>>>>>> 
>>>>>>>>> What puzzled me was why ShouldBroadcastEvent return true for this 
>>>>>>>>> very first stop. Is this a bug?
>>>>>>>>> 
>>>>>>>>> I also spent sometime at ShouldBroadcastEvent and saw that this:
>>>>>>>>> 
>>>>>>>>>        case eStateStopped:
>>>>>>>>>        case eStateCrashed:
>>>>>>>>>        case eStateSuspended:
>>>>>>>>>        {
>>>>>>>>>         ....
>>>>>>>>>                if (was_restarted || should_resume || 
>>>>>>>>> m_resume_requested)
>>>>>>>>>                {
>>>>>>>>> 
>>>>>>>>> evaluates as false, and hence the PrivateResume code is not called... 
>>>>>>>>> does this seem buggy to you for this very first stop?
>>>>>>>>> 
>>>>>>>>> I thought I'd try asking you, since in a previous mail from Greg, he 
>>>>>>>>> cited you as being a thread-plan expert. (Hope that's ok!). I'd 
>>>>>>>>> really appreciate your help in clarifying the above questions for me, 
>>>>>>>>> and if you have time, giving me some ideas as to how to trace this 
>>>>>>>>> one further e.g. how m_thread_list.ShouldStop and 
>>>>>>>>> m_thread_list.ShouldReportStop should behave, etc.
>>>>>>>>> 
>>>>>>>>> thanks for your help
>>>>>>>>> Matt
>>>>>>>>> 
>>>>>>>>> Matthew Gardiner wrote:
>>>>>>>>>> Folks,
>>>>>>>>>> 
>>>>>>>>>> In addition to the overlapping prompt race Shawn Best and myself are 
>>>>>>>>>> looking at, I'm seeing another issue where if I launch a process, I 
>>>>>>>>>> get a stop (presumably the in) being reported to the UI.
>>>>>>>>>> 
>>>>>>>>>> (lldb) target create ~/mydir/i64-hello.elf
>>>>>>>>>> Current executable set to '~/mydir/i64-hello.elf' (x86_64).
>>>>>>>>>> (lldb) process launch
>>>>>>>>>> Process 27238 launching
>>>>>>>>>> Process 27238 launched: '64-hello.elf' (x86_64)
>>>>>>>>>> Process 27238 stopped
>>>>>>>>>> * thread #1: tid = 27238, 0x0000003675a011f0, name = 'i64-hello.elf'
>>>>>>>>>>    frame #0:
>>>>>>>>>> (lldb) target list
>>>>>>>>>> Current targets:
>>>>>>>>>> * target #0: i64-hello.elf ( arch=x86_64-unknown-linux, 
>>>>>>>>>> platform=host, pid=27238, state=running )
>>>>>>>>>> (lldb)
>>>>>>>>>> 
>>>>>>>>>> As you can see the "target list" reflects that the process is 
>>>>>>>>>> running. Which I confirmed by looking at /proc/27238/status.
>>>>>>>>>> 
>>>>>>>>>> Anyone else seeing this?
>>>>>>>>>> 
>>>>>>>>>> thanks
>>>>>>>>>> Matt
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> Member of the CSR plc group of companies. CSR plc registered in 
>>>>>>>>>> England and Wales, registered number 4187346, registered office 
>>>>>>>>>> Churchill House, Cambridge Business Park, Cowley Road, Cambridge, 
>>>>>>>>>> CB4 0WZ, United Kingdom
>>>>>>>>>> More information can be found at www.csr.com <http://www.csr.com>. 
>>>>>>>>>> Keep up to date with CSR on our technical blog, www.csr.com/blog 
>>>>>>>>>> <http://www.csr.com/blog>, CSR people blog, www.csr.com/people 
>>>>>>>>>> <http://www.csr.com/people>, YouTube, www.youtube.com/user/CSRplc 
>>>>>>>>>> <http://www.youtube.com/user/CSRplc>, Facebook, 
>>>>>>>>>> www.facebook.com/pages/CSR/191038434253534 
>>>>>>>>>> <http://www.facebook.com/pages/CSR/191038434253534>, or follow us on 
>>>>>>>>>> Twitter at www.twitter.com/CSR_plc <http://www.twitter.com/CSR_plc>.
>>>>>>>>>> New for 2014, you can now access the wide range of products powered 
>>>>>>>>>> by aptX at www.aptx.com <http://www.aptx.com>.
>>>>>>>>>> _______________________________________________
>>>>>>>>>> lldb-dev mailing list
>>>>>>>>>> lldb-dev@cs.uiuc.edu <mailto:lldb-dev@cs.uiuc.edu>
>>>>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> To report this email as spam click 
>>>>>>>>>> https://www.mailcontrol.com/sr/EjKNgqvIx0TGX2PQPOmvUj!GOBh06pKKNwnTW0ZqkNYNbZeofOurgZMo6Cl2EgPiaCw7kl6fPUTCXaTERp6oIw==
>>>>>>>>>>  
>>>>>>>>>> <https://www.mailcontrol.com/sr/EjKNgqvIx0TGX2PQPOmvUj%21GOBh06pKKNwnTW0ZqkNYNbZeofOurgZMo6Cl2EgPiaCw7kl6fPUTCXaTERp6oIw==>
>>>>>>>>>>  .
>>>>>>>>> _______________________________________________
>>>>>>>>> lldb-dev mailing list
>>>>>>>>> lldb-dev@cs.uiuc.edu <mailto:lldb-dev@cs.uiuc.edu>
>>>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
>>> _______________________________________________
>>> lldb-dev mailing list
>>> lldb-dev@cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
> 
> <mg_launch.diff>


_______________________________________________
lldb-dev mailing list
lldb-dev@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev

Reply via email to