Excellent, thanks!

Jim

On Dec 7, 2012, at 9:58 AM, "Kaylor, Andrew" <[email protected]> wrote:

> The solution Jim suggested below also fixes the problem.  I've committed this 
> as r169618.
> 
> -Andy
> 
> -----Original Message-----
> From: Pierre-Andre Saulais [mailto:[email protected]] 
> Sent: Friday, December 07, 2012 3:36 AM
> To: Jim Ingham
> Cc: Kaylor, Andrew; [email protected]
> Subject: Re: [lldb-dev] Continue misfiring after expression evaluation
> 
> I have run into the same problem with duplicated 'breakpoint stops' when 
> using expression evaluation on Linux. When setting the thread plans to 
> private in InferiorCallPOSIX.cpp as Andrew suggested, the issue does go away.
> 
> Thanks Andrew!
> 
> Pierre
> 
> On 07/12/12 01:57, Jim Ingham wrote:
>> Ah, right, that seems like another good way to do this (wonder who 
>> thought of and then forgot it...)
>> 
>> I can't see a reason why function calling thread plans should ever be 
>> public.  Even if you stop in the middle of one (because you called a 
>> function to break in it and step around) when you continue to finish the 
>> call you don't want the call function plan to be the reason you stopped back 
>> in normal code.
>> 
>> So a better fix would be to set ThreadPlanCallFunction's to private in their 
>> constructor.
>> 
>> BTW, We added an "allocate memory" packet to debugserver, so we don't need 
>> to use InferiorCallMmap.  That's why we didn't see this on OSX.
>> 
>> Jim
>> 
>> 
>> On Dec 6, 2012, at 5:28 PM, "Kaylor, Andrew" <[email protected]> wrote:
>> 
>>> Alright, this feels a lot better.
>>> 
>>> After further investigation, I learned that Thread::GetStopInfo() only gets 
>>> the stop info from completed thread plans that aren't marked private.  
>>> Looking around at some examples in the code, it seemed that the thread 
>>> plans involved in the expression evaluation should have been marked 
>>> private, at least before the Process object started executing them.  I 
>>> verified that Process::RunThreadPlan was saving and restoring the 
>>> ThreadPlan's 'private' state correctly but that my ThreadPlanRunFunction 
>>> was entering with 'private' set to false.
>>> 
>>> I was able to track this thread plan back to InferiorCallMmap in 
>>> InferiorCallPOSIX.cpp.  I'm guessing that Mac OS X doesn't use that for 
>>> whatever reason.
>>> 
>>> The attached patch fixes the problem I was investigating and it seems like 
>>> a reasonable change.  Can you review this, Jim?
>>> 
>>> Thanks,
>>> Andy
>>> 
>>> -----Original Message-----
>>> From: Jim Ingham [mailto:[email protected]]
>>> Sent: Thursday, December 06, 2012 2:28 PM
>>> To: Kopec, Matt
>>> Cc: Kaylor, Andrew; [email protected]; Malea, Daniel
>>> Subject: Re: [lldb-dev] Continue misfiring after expression 
>>> evaluation
>>> 
>>> I don't see this fail, even for function calls:
>>> 
>>> (lldb) b s -n main
>>> Breakpoint 1: 3 locations.
>>> (lldb) run
>>> Process 96310 launched: 
>>> '/Users/jingham/Projects/Sketch/build/Debug/Sketch.app/Contents/MacOS
>>> /Sketch' (x86_64) Process 96310 stopped
>>> * thread #1: tid = 0x1c03, function: main , stop reason = breakpoint 1.1
>>>    frame #0: 0x000000010001a74e Sketch`main at SKTMain.m:11
>>>   8         
>>>   9         
>>>   10        int main(int argc, const char *argv[]) {
>>> -> 11           NSLog (@"Added for testing rebuilds.");
>>>   12            const char *names[20];
>>>   13            for (int i = 0; i < argc; i++)
>>>   14            {
>>> (lldb) expr (int) printf ("Some text here.\n")
>>> (int) $0 = 16
>>> Some text here.
>>> (lldb) log enable lldb step
>>> (lldb) c
>>> <lldb.driver.main-thread> Pushing plan: "Single stepping past breakpoint 
>>> site 3 at 0x10001a74e", tid = 0x1c03.
>>> <lldb.driver.main-thread> ThreadPlanCallFunction(0x7f8eb4189540): 
>>> DoTakedown called as no-op for thread 0x1c03, m_valid: 1 complete: 1.
>>> 
>>> <lldb.driver.main-thread> WillResume Thread #1: tid = 0x1c03, pc = 
>>> 0x10001a74e, sp = 0x7fff5fbff4a0, fp = 0x7fff5fbff5e0, plan = 'Step over 
>>> breakpoint trap', state = stepping, stop others = 1 
>>> <lldb.process.internal-state(pid=96310)> Current Plan for thread 1 
>>> (0x1c03): Step over breakpoint trap being asked whether we should report 
>>> run.
>>> Process 96310 resuming
>>> <lldb.process.internal-state(pid=96310)>
>>> <lldb.process.internal-state(pid=96310)> ThreadList::ShouldStop: 1 threads 
>>> <lldb.process.internal-state(pid=96310)> Thread::ShouldStop for tid = 
>>> 0x1c03, pc = 0x000000010001a751 <lldb.process.internal-state(pid=96310)> 
>>> ^^^^^^^^ Thread::ShouldStop Begin ^^^^^^^^ 
>>> <lldb.process.internal-state(pid=96310)> Plan stack initial state:
>>>  Plan Stack for thread #1: tid = 0x1c03, stack_size = 2
>>>    Element 1: Single stepping past breakpoint site 3 at 0x10001a74e
>>>    Element 0: Base thread plan.
>>> 
>>> <lldb.process.internal-state(pid=96310)> Plan Step over breakpoint trap 
>>> explains stop, auto-continue 1.
>>> <lldb.process.internal-state(pid=96310)> Plan Step over breakpoint trap 
>>> should stop: 0.
>>> <lldb.process.internal-state(pid=96310)> Completed step over breakpoint 
>>> plan.
>>> <lldb.process.internal-state(pid=96310)> Popping plan: "Step over 
>>> breakpoint trap", tid = 0x1c03.
>>> <lldb.process.internal-state(pid=96310)> Plan stack final state:
>>>  Plan Stack for thread #1: tid = 0x1c03, stack_size = 1
>>>    Element 0: Base thread plan.
>>>  Completed Plan Stack: 1 elements.
>>>    Element 0: Single stepping past breakpoint site 3 at 0x10001a74e
>>> 
>>> The call to printf definitely ran code in the target, and yet 
>>> continue pushed the "step over breakpoint" plan rather than stopping 
>>> with another breakpoint hit (which is what I presume you are seeing?)
>>> 
>>> Jim
>>> 
>>> 
>>> On Dec 6, 2012, at 1:01 PM, "Kopec, Matt" <[email protected]> wrote:
>>> 
>>>> Daniel and I saw the same behaviour as Andy on Mac recently though we 
>>>> reproduced it differently. If I recall what was happening on Mac 
>>>> correctly, the expression to be evaluated didn't require MCJIT/executing 
>>>> in the target process (for instance, printing a register value - expr pc) 
>>>> but on Linux did require MCJIT/running in the target. However, evaluating 
>>>> a function call expression did reproduce the problem on Mac since this did 
>>>> go through the MCJIT route. Could you try this to see if it reproduces the 
>>>> problem?
>>>> 
>>>> Thanks,
>>>> Matt
>>>> ________________________________________
>>>> From: [email protected] [[email protected]] on 
>>>> behalf of Jim Ingham [[email protected]]
>>>> Sent: Thursday, December 06, 2012 2:05 PM
>>>> To: Kaylor, Andrew
>>>> Cc: [email protected]
>>>> Subject: Re: [lldb-dev] Continue misfiring after expression 
>>>> evaluation
>>>> 
>>>> Yeah, after taking a quick look at the code last night, I'm curious too.
>>>> 
>>>> I am in the middle of something right now, but as soon as I get a chance, 
>>>> I'll step through it and see what's going on.
>>>> 
>>>> Thinking about it a little bit more, I can't see any reason why 
>>>> Process::RunThreadPlan should not clear the evidence of its work from the 
>>>> plan stack.  It should only do this if the plan succeeds, or if it is 
>>>> going to unwind on error.  If you're going to stop because you hit a 
>>>> breakpoint in the middle of a function call, you don't want to change the 
>>>> plan stack state (just like you don't want to restore the old stop info.)  
>>>> And I think it would be wrong to erase the whole completed plan stack, 
>>>> better to mark the position on entry, and restore it to the state it had 
>>>> when you entered RunThreadPlan.
>>>> 
>>>> Jim
>>>> 
>>>> On Dec 6, 2012, at 10:54 AM, "Kaylor, Andrew" <[email protected]> 
>>>> wrote:
>>>> 
>>>>> I updated to the latest code and I'm still seeing the same behavior.
>>>>> 
>>>>> That is, thread_plan_sp->RestoreThreadState() is being called, and it 
>>>>> does restore the stop info for the thread to the old stop info, but when 
>>>>> Thread::SetupForResume() calls Thread::GetStopInfo() that function 
>>>>> creates stop info based on the completed thread plan stack rather than 
>>>>> using m_actual_stop_info_sp.
>>>>> 
>>>>> Any suggestions?  I'd be curious to know why this doesn't happen on Mac 
>>>>> OS X because it looks like it would.
>>>>> 
>>>>> -Andy
>>>>> 
>>>>> -----Original Message-----
>>>>> From: [email protected]
>>>>> [mailto:[email protected]] On Behalf Of Kaylor, Andrew
>>>>> Sent: Wednesday, December 05, 2012 4:38 PM
>>>>> To: Jim Ingham
>>>>> Cc: [email protected]
>>>>> Subject: Re: [lldb-dev] Continue misfiring after expression 
>>>>> evaluation
>>>>> 
>>>>> Hi Jim,
>>>>> 
>>>>> I am working with an old version of the code, so things were in a bit 
>>>>> different state for me.  I was seeing 
>>>>> Thread::RestoreThreadStateFromCheckpoint() being called.  The problem is 
>>>>> that when Thread::SetupForResume() calls Thread::GetStopInfo(), the 
>>>>> latter does this:
>>>>> 
>>>>>  ThreadPlanSP plan_sp (GetCompletedPlan());
>>>>>  if (plan_sp && plan_sp->PlanSucceeded())
>>>>>      return StopInfo::CreateStopReasonWithPlan (plan_sp, 
>>>>> GetReturnValueObject());
>>>>>  else
>>>>>  {
>>>>>      ProcessSP process_sp (GetProcess());
>>>>>      if (process_sp
>>>>>          && m_actual_stop_info_sp
>>>>>          && m_actual_stop_info_sp->IsValid()
>>>>>          && m_thread_stop_reason_stop_id == process_sp->GetStopID())
>>>>>          return m_actual_stop_info_sp;
>>>>>      else
>>>>>          return GetPrivateStopReason ();
>>>>>  }
>>>>> 
>>>>> Since the completed stop plan from the expression command is still 
>>>>> around, the stop info comes from there.  The thread's m_actual_stop_info 
>>>>> seems to be correct, but the code doesn't get to the point where it would 
>>>>> use it.
>>>>> 
>>>>> I'll update to the latest code and see if this is still happening, but I 
>>>>> wanted to tell you what I knew while I was still in a known state.  I'll 
>>>>> let you know what happens with the new code.
>>>>> 
>>>>> -Andy
>>>>> 
>>>>> -----Original Message-----
>>>>> From: Jim Ingham [mailto:[email protected]]
>>>>> Sent: Wednesday, December 05, 2012 3:50 PM
>>>>> To: Kaylor, Andrew
>>>>> Cc: [email protected]
>>>>> Subject: Re: [lldb-dev] Continue misfiring after expression 
>>>>> evaluation
>>>>> 
>>>>> I don't see this happening on Mac OS X.  That test succeeds, and I don't 
>>>>> see the behavior you describe.
>>>>> 
>>>>> You should not need to clear the completed plan stack.  The way it is 
>>>>> supposed to work is as follows:
>>>>> 
>>>>> Running functions is always done by Process::RunThreadPlan.  After the 
>>>>> ThreadPlanCallFunction gets done running in that function, we do this bit 
>>>>> of code:
>>>>> 
>>>>>      // Restore the thread state if we are going to discard the plan 
>>>>> execution.
>>>>> 
>>>>>      if (return_value == eExecutionCompleted || discard_on_error)
>>>>>      {
>>>>>          thread_plan_sp->RestoreThreadState();
>>>>>      }
>>>>> 
>>>>> That should set the StopInfo that was squirreled away in 
>>>>> Thread::CheckpointThreadState back as the current StopInfo for the 
>>>>> thread.  Is that getting called?  If not, why not?  If it is getting 
>>>>> called, why isn't it succeeding in resetting the thread's StopInfo back 
>>>>> to the old reason?
>>>>> 
>>>>> Note, up till a couple of weeks ago this work was done in the DoTakedown 
>>>>> method of ThreadPlanCallFunction, but I moved resetting the StopInfo out 
>>>>> of that function (which gets called while the stop event for the function 
>>>>> call is still being processed) to here, because otherwise it might 
>>>>> trigger the original StopInfo's PerformAction while you are in the middle 
>>>>> of handing the ThreadPlanCallFunction's execution, which isn't right.
>>>>> 
>>>>> Hope that helps.
>>>>> 
>>>>> Jim
>>>>> 
>>>>> On Dec 5, 2012, at 3:28 PM, "Kaylor, Andrew" <[email protected]> 
>>>>> wrote:
>>>>> 
>>>>>> Hi all,
>>>>>> 
>>>>>> I've been debugging a problem on Linux where if you hit a breakpoint, 
>>>>>> then evaluate an expression that requires JITing, then continue LLDB 
>>>>>> will break at the line you were already on.  I don't know if this 
>>>>>> problem is specific to Linux, but that's where I'm debugging it.  This 
>>>>>> problem appears in the 'lang/c/setvalues/TestSetValues.py' test case, 
>>>>>> but can also be reproduced manually.
>>>>>> 
>>>>>> What I'm seeing is that when the 'continue' handling calls 
>>>>>> Thread::SetupForResume() the current Thread reports its stop reason as 
>>>>>> 'eStopReasonPlanComplete' because the ThreadPlan for evaluating the 
>>>>>> expression is still on the completed plans stack.  As a result, the 
>>>>>> ThreadPlanStepOverBreakpoint plan doesn't get queued.  If I add calls to 
>>>>>> 'm_completed_plan_stack.clear()' and 'm_discarded_plan_stack.clear()' at 
>>>>>> the top of the 'if (GetResumeState() == eStateSuspended)' block in 
>>>>>> Thread::SetupForResume() then everything works as expected.
>>>>>> 
>>>>>> Obviously, that feels like a pretty risky thing to do, at best.  It 
>>>>>> seems like the expression command handling should have done something to 
>>>>>> clear the completed plan stack when it was finished, but as of yet I 
>>>>>> haven't found a place where that is appropriate.
>>>>>> 
>>>>>> Can anyone give me guidance on this issue?
>>>>>> 
>>>>>> Thanks,
>>>>>> Andy
>>>>>> _______________________________________________
>>>>>> lldb-dev mailing list
>>>>>> [email protected]
>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
>>>>> 
>>>>> _______________________________________________
>>>>> lldb-dev mailing list
>>>>> [email protected]
>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
>>>> _______________________________________________
>>>> lldb-dev mailing list
>>>> [email protected]
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
>>> <make-mmap-thread-plan-private.patch>
>> _______________________________________________
>> lldb-dev mailing list
>> [email protected]
>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
> 

_______________________________________________
lldb-dev mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev

Reply via email to