Hopefully making the backtracer smart enough on Windows will be sufficient.  Either way, it seems like the first step, so we'll see.  I have some ideas about cases that might be difficult to handle, but we can get into it more after the backtracer works well enough on Windows to see how much of a problem it will be.<br><div class="gmail_quote">On Mon, Jan 19, 2015 at 4:19 PM Greg Clayton <<a href="mailto:gclayton@apple.com">gclayton@apple.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I would vote to try and get Windows stack backtracking working using all built in code and not having to resort to using the Windows native DLL which aids in backtracing. This would allow remote debugging to work seamlessly and not have a really bad remote debugging to windows experience, but local debugging is just fine. We can probably use the native DLL to help us track down cases that we get wrong and it can help us train our windows backtracer to make sure it works as well as possible.<br>
<br>
Although I would be ok with having support for Windows PDB files in a new SymbolFileWindowsPDB only happen on windows because the DLL is the only way to access the debug info and the file format is not documented...<br>
<br>
Greg<br>
<br>
> On Jan 16, 2015, at 7:05 PM, Jason Molenda <<a href="mailto:jmolenda@apple.com" target="_blank">jmolenda@apple.com</a>> wrote:<br>
><br>
> Yeah, good point.  In that case, you could just update RegisterContextLLDB::<u></u>SavedLocationForRegister().  Add a little code near the top that looks to see if there is the thread has an UnwindHint saying we've just stepped-in, and this is frame 0, then we use the CreateFunctionEntryUnwindPlan(<u></u>) unwind plan instead of whatever plan we would normally use here.<br>
><br>
><br>
><br>
><br>
>> On Jan 16, 2015, at 6:27 PM, <a href="mailto:jingham@apple.com" target="_blank">jingham@apple.com</a> wrote:<br>
>><br>
>> So the steps I was thinking of were:<br>
>><br>
>> 1) ThreadPlan notices it is on a branch<br>
>> 2) ThreadPlan calls  Thread::SetUnwindHint() which calls into the ABI to write down whatever hints it thinks are appropriate and stuff them into the thread.<br>
>> 3) ThreadPlan causes the process to step one instruction<br>
>> 4) Whoever goes to create the RegisterContexts & Frames for that thread will have access to the Thread, and thus to the UnwindHint.  So the ThreadPlan doesn't have to get involved.<br>
>><br>
>> I think that should work.<br>
>><br>
>> Jim<br>
>><br>
>><br>
>>> On Jan 16, 2015, at 5:43 PM, Jason Molenda <<a href="mailto:jmolenda@apple.com" target="_blank">jmolenda@apple.com</a>> wrote:<br>
>>><br>
>>> The details will be a little tricky on this one.  Frame 0 is probably created as soon as the process stops - before the ThreadPlan does anything -- and we need to install the UnwindHint in that frame 0 RegisterContextLLDB before we start asking anything about frame 1.<br>
>>><br>
>>> StackFrameList is where we call the Unwinder to get stack frames -- e.g. see StackFrameList::<u></u>GetFrameAtIndex().<br>
>>><br>
>>> If the ThreadPlan had a chance to execute code before we try to retrieve stack frame 1 (which it seems like it would -- this is a private stop event and the ThreadPlan is the guy who is going to ask about stack frame 1 itself), we'd need some way to say give me the RegisterContext for frame 0 and stuff the UnwindHints in that object.<br>
>>><br>
>>> e.g. see how RegisterContextLLDB::<u></u>InitializeZerothFrame() sets its m_full_unwind_plan_sp.  This is the UnwindPlan that will be used to find frame 1's pc, stack pointer, frame pointer, etc, when requested.<br>
>>><br>
>>><br>
>>> J<br>
>>><br>
>>><br>
>>>> On Jan 16, 2015, at 4:55 PM, <a href="mailto:jingham@apple.com" target="_blank">jingham@apple.com</a> wrote:<br>
>>>><br>
>>>> One thing to be careful about if you do this is that there's no guarantee that the ThreadPlan will be the first person to ask for the unwind, so there might be a bad unwind sitting around.  It would actually be a shame if anybody else got their hands on a bad unwind when we knew how to make a better one.  So maybe the UnwindHint should hang off the Thread instead, so anybody who goes to unwind will see it.<br>
>>>><br>
>>>> Jim<br>
>>>><br>
>>>><br>
>>>>> On Jan 16, 2015, at 4:17 PM, Reid Kleckner <<a href="mailto:rnk@google.com" target="_blank">rnk@google.com</a>> wrote:<br>
>>>>><br>
>>>>> Cool, that seems reasonable.<br>
>>>>><br>
>>>>> Sent from phone<br>
>>>>><br>
>>>>> On Jan 16, 2015 4:04 PM, <<a href="mailto:jingham@apple.com" target="_blank">jingham@apple.com</a>> wrote:<br>
>>>>><br>
>>>>>> On Jan 16, 2015, at 3:55 PM, Reid Kleckner <<a href="mailto:rnk@google.com" target="_blank">rnk@google.com</a>> wrote:<br>
>>>>>><br>
>>>>>> On Fri, Jan 16, 2015 at 2:53 PM, Jason Molenda <<a href="mailto:jmolenda@apple.com" target="_blank">jmolenda@apple.com</a>> wrote:<br>
>>>>>> In my opinion, expending a lot of energy on making the ThreadPlans know how to unwind from the first instruction is ignoring the real problem of being able to unwind accurately from all instruction locations.  It's not worth doing.  Make the unwinder work from any location on your platform - if it can't, that's the problem that needs to be fixed.  I agree I think it would be interesting if the ThreadPlans could identify to the Unwinder that it has just stepped in to a function for even better reliability in a particularly tricky unwind scenario.  But it's not a panacea, if that's the only thing you fix and rely on "walk the frame chain on the stack" to backtrace, you're going to have a horrible debugger experience.  Even if you can accurately walk the stack you won't get register save locations, for instance, so when the debug info says a variable is stored in rbx in the middle of the stack, and rbx was saved by the callee function to the stack, you won't be able to r!<br>
 e!<br>
> trieve it for the user.<br>
>>>>>><br>
>>>>>> I don't think it's practical to expect the unwinder to *always* work, but I agree it needs to work most of the time. There are situations when unwind data just isn't available, like when trying to step over a call to a function JITed by something you don't control.<br>
>>>>>><br>
>>>>>> Personally, I think it will be a lot more work to make the unwinder understand PDB information than it will to let ThreadPlan know what looks a call instruction looks like. Clang will also be generating DWARF for the forseeable future, so adding PDB reading only helps us debug third party code, which not very interesting. Adding the call-recognition code to ThreadPlan will solve the cross-platform problem of stepping over a call to a function with no CFI. Would you be OK with patches in that direction?<br>
>>>>>><br>
>>>>>> We do eventually want to use PDBs to support unwinding, but we expected to get by with just DWARF for some time to come.<br>
>>>>><br>
>>>>><br>
>>>>> We crossed paths...  See the "UnwindHint" notion I sent in another mail on this thread.  I like that approach better than having the ThreadPlans know about calls because it not only gets stepping right, but passing the hint to the unwinder would not only get the step in to stop as it should, but would also set the unwinder on the right path so that the backtrace at this point would also be correct...  That's important for the user when we do step-in rather than step-over.<br>
>>>>><br>
>>>>> Jim<br>
>>>>><br>
>>>>><br>
>>>><br>
>>><br>
>><br>
><br>
><br>
> ______________________________<u></u>_________________<br>
> lldb-dev mailing list<br>
> <a href="mailto:lldb-dev@cs.uiuc.edu" target="_blank">lldb-dev@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev" target="_blank">http://lists.cs.uiuc.edu/<u></u>mailman/listinfo/lldb-dev</a><br>
<br>
<br>
______________________________<u></u>_________________<br>
lldb-dev mailing list<br>
<a href="mailto:lldb-dev@cs.uiuc.edu" target="_blank">lldb-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev" target="_blank">http://lists.cs.uiuc.edu/<u></u>mailman/listinfo/lldb-dev</a><br>
</blockquote></div>