<div dir="ltr">Thanks. That's fine, just want to confirm the behavior and my understanding. I can definitely deal with the difference between attach/launch myself.</div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jan 29, 2016 at 1:41 PM, Jim Ingham <span dir="ltr"><<a href="mailto:jingham@apple.com" target="_blank">jingham@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">I don’t think we can change this behavior, since other clients are relying on the way it is now.<div><br></div><div>In any case, attach won't return till it is successful, and presumably you know you are attaching, so I don’t think there’s any ambiguity about what is going on, even if you don’t get a stop event.</div><span class="HOEnZb"><font color="#888888"><div><br></div><div>Jim</div></font></span><div><div class="h5"><div><br></div><div><div><div><blockquote type="cite"><div>On Jan 29, 2016, at 11:50 AM, Jeffrey Tan <<a href="mailto:jeffrey.fudan@gmail.com" target="_blank">jeffrey.fudan@gmail.com</a>> wrote:</div><br><div><div dir="ltr">Jim/Pavel, my toy code works reliably after using SBListener with SBTarget.Launch/Attach. <div>One thing I noticed is:</div><div>If I set "stop_at_entry=True" for SBTarget.Launch(), I will get a stop event of eStopReasonSignal at loader breakpoint. However SBTarget.AttachXXX() will pause the target process without a stop event. Is this expected? This may cause a bit state issue in our IDE since we rely on the stop event from debugger to update UI in IDE. Is there any way to tell lldb to emit a stop event during attach? </div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jan 29, 2016 at 11:22 AM, Jim Ingham <span dir="ltr"><<a href="mailto:jingham@apple.com" target="_blank">jingham@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">I can’t comment on Windows, I don’t know what requirements the Windows API’s place on the debugger. <div><br></div><div>Its been a while since I’ve worked on Linux, but I don’t remember anything that would privilege one thread over another.</div><div><br></div><div>lldb supports running multiple targets and processes in one debugger, and also supports multiple debuggers running each one target or any combination. Since each Debugger gets a separate script interpreter (and all its state) by running multiple processes in one SBDebugger you could offer users the possibility of having scripted commands to control a set of processes (e.g. hitting a breakpoint in one process could trigger actions in the other.) It might be possible to do some interesting things that way. </div><div><br></div><div>OTOH, keeping to one process per debugger is a much simpler programming model. So if you were planning to have YOUR code that runs the debugger handle the possible interactions among processes, then it is probably going to be easier to manage doing it that way.</div><span><font color="#888888"><div><br></div><div>Jim</div></font></span><div><div><div><br></div><div><br></div><div><br></div><div><div><blockquote type="cite"><div>On Jan 29, 2016, at 10:43 AM, Jeffrey Tan <<a href="mailto:jeffrey.fudan@gmail.com" target="_blank">jeffrey.fudan@gmail.com</a>> wrote:</div><br><div><div dir="ltr">Thanks Jim. Is this true for other platforms? Our IDE is going to support Mac and Linux and may extend to Windows some time later. <div>Just curious, why does Xcode create multiple SBDebuggers assuming it is debugging a single process? Are you talking about multiple-processes scenario(One SBDebugger for one process)? </div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jan 29, 2016 at 9:21 AM, Jim Ingham <span dir="ltr"><<a href="mailto:jingham@apple.com" target="_blank">jingham@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">There is no requirement that the lldb API’s be called on a particular thread on OS X. LLDB tries to be robust against being called from multiple threads simultaneously for the same debugger, but you can still make it fall over if you try hard, particularly if you allow multiple threads to restart the process you are debugging. Running multiple SBDebuggers on separate threads works fine, that’s the mode Xcode uses, and we haven’t had problems with this in quite a while.<br>
<span><font color="#888888"><br>
Jim<br>
</font></span><div><div><br>
> On Jan 29, 2016, at 8:54 AM, Jeffrey.fudan via lldb-dev <<a href="mailto:lldb-dev@lists.llvm.org" target="_blank">lldb-dev@lists.llvm.org</a>> wrote:<br>
><br>
> Great, this is very helpful, will give a try.<br>
> Btw: is there any threading requirement of lldb API? For example, are all the Apis must be called on the event thread or they are free to be called on any thread? I know windows debug API has some limitation on this.<br>
><br>
> Sent from my iPad<br>
><br>
>> On Jan 29, 2016, at 2:59 AM, Pavel Labath <<a href="mailto:labath@google.com" target="_blank">labath@google.com</a>> wrote:<br>
>><br>
>> Hi Jeffrey,<br>
>><br>
>> I see a couple of problems with the way you are using the lldb's API.<br>
>> The main problem is you are launching the target via the command-line<br>
>> API, which does not allow you to specify the listener upon creation.<br>
>> When you start it this way all events go to the default debugger<br>
>> listener (debugger.GetListener()), and by the time you connect your<br>
>> own listener, some of these events have already been broadcast, and<br>
>> that is why you get nondeterministic behavior. You should use the<br>
>> SBTarget.Launch function to specify the listener from the start.<br>
>><br>
>> The second problem is the handling of the Stopped events. Sometimes<br>
>> LLDB needs to stop the inferior do to some internal work, but this the<br>
>> program is immediately resumed. This event is broadcast as a "stopped"<br>
>> event with a special "restarted" bit set (see<br>
>> SBProcess.GetRestartedFromEvent, and<br>
>> <<a href="http://lists.llvm.org/pipermail/lldb-dev/2016-January/009291.html" rel="noreferrer" target="_blank">http://lists.llvm.org/pipermail/lldb-dev/2016-January/009291.html</a>>)<br>
>><br>
>> hope that helps,<br>
>> pl<br>
>><br>
>><br>
>><br>
>> On 29 January 2016 at 03:53, Jeffrey Tan via lldb-dev<br>
>> <<a href="mailto:lldb-dev@lists.llvm.org" target="_blank">lldb-dev@lists.llvm.org</a>> wrote:<br>
>>> Hi,<br>
>>><br>
>>> On mac OS, I am having difficulty understanding the launch debugger events<br>
>>> sequence of lldb. I used the following code to play around LLDB. I found,<br>
>>> for some binaries, debugger will enter stopped/paused mode, waiting for my<br>
>>> further input, print stack shows:<br>
>>> dbg> bt<br>
>>> * thread #1: tid = 0x15153e, 0x00007fff5fc0d2af<br>
>>> dyld`gdb_image_notifier(dyld_image_mode, unsigned int, dyld_image_info<br>
>>> const*) + 1<br>
>>> * frame #0: 0x00007fff5fc0d2af dyld`gdb_image_notifier(dyld_image_mode,<br>
>>> unsigned int, dyld_image_info const*) + 1<br>
>>> frame #1: 0x000000000000401d<br>
>>><br>
>>> But some other binaries, it just print "Process event: stopped, reason: 1"<br>
>>> and inferior just exits immediately without waiting for debugger's further<br>
>>> input.<br>
>>><br>
>>> Questions:<br>
>>> 1. When I launch a binary, is there supposed to be a loader breakpoint<br>
>>> waiting for debugger continue? Any other debug events do I expect to get and<br>
>>> continue?<br>
>>> 2. What about attach?<br>
>>> 3. What is the dyld`gdb_image_notifier() debugger break above? Why does it<br>
>>> happen for some binary but not others?<br>
>>><br>
>>> Thanks for any information!<br>
>>><br>
>>> # Should be first for LLDB package to be added to search path.<br>
>>> from find_lldb import lldb<br>
>>> from lldb import eStateStepping, eStateRunning, eStateExited, SBBreakpoint,<br>
>>> SBEvent, SBListener, SBProcess, SBTarget<br>
>>> import sys<br>
>>> import os<br>
>>> import subprocess<br>
>>> from sys import stdin, stdout<br>
>>> from threading import Thread<br>
>>><br>
>>> class LLDBListenerThread(Thread):<br>
>>> should_quit = False<br>
>>><br>
>>> def __init__(self, process):<br>
>>> Thread.__init__(self)<br>
>>> self.listener = SBListener('Chrome Dev Tools Listener')<br>
>>> self._add_listener_to_process(process)<br>
>>> self._broadcast_process_state(process)<br>
>>> self._add_listener_to_target(process.target)<br>
>>><br>
>>> def _add_listener_to_target(self, target):<br>
>>> # Listen for breakpoint/watchpoint events<br>
>>> (Added/Removed/Disabled/etc).<br>
>>> broadcaster = target.GetBroadcaster()<br>
>>> mask = SBTarget.eBroadcastBitBreakpointChanged |<br>
>>> SBTarget.eBroadcastBitWatchpointChanged |<br>
>>> SBTarget.eBroadcastBitModulesLoaded<br>
>>> broadcaster.AddListener(self.listener, mask)<br>
>>><br>
>>> def _add_listener_to_process(self, process):<br>
>>> # Listen for process events (Start/Stop/Interrupt/etc).<br>
>>> broadcaster = process.GetBroadcaster()<br>
>>> mask = SBProcess.eBroadcastBitStateChanged<br>
>>> broadcaster.AddListener(self.listener, mask)<br>
>>><br>
>>> def _broadcast_process_state(self, process):<br>
>>> state = 'stopped'<br>
>>> if process.state == eStateStepping or process.state ==<br>
>>> eStateRunning:<br>
>>> state = 'running'<br>
>>> elif process.state == eStateExited:<br>
>>> state = 'exited'<br>
>>> self.should_quit = True<br>
>>> thread = process.selected_thread<br>
>>> print 'Process event: %s, reason: %d' % (state,<br>
>>> thread.GetStopReason())<br>
>>><br>
>>> def _breakpoint_event(self, event):<br>
>>> breakpoint = SBBreakpoint.GetBreakpointFromEvent(event)<br>
>>> print 'Breakpoint event: %s' % str(breakpoint)<br>
>>><br>
>>> def run(self):<br>
>>> while not self.should_quit:<br>
>>> event = SBEvent()<br>
>>> if self.listener.WaitForEvent(1, event):<br>
>>> if event.GetType() == SBTarget.eBroadcastBitModulesLoaded:<br>
>>> print 'Module load: %s' % str(event)<br>
>>> elif SBProcess.EventIsProcessEvent(event):<br>
>>><br>
>>> self._broadcast_process_state(SBProcess.GetProcessFromEvent(event))<br>
>>> elif SBBreakpoint.EventIsBreakpointEvent(event):<br>
>>> self._breakpoint_event(event)<br>
>>><br>
>>> def _interctive_loop(debugger):<br>
>>> process = debugger.GetSelectedTarget().process<br>
>>> event_thread = LLDBListenerThread(process)<br>
>>> event_thread.start()<br>
>>><br>
>>> while (True):<br>
>>> stdout.write('dbg> ')<br>
>>> command = stdin.readline().rstrip()<br>
>>> if len(command) == 0:<br>
>>> continue<br>
>>> debugger.HandleCommand(command)<br>
>>><br>
>>><br>
>>> def main():<br>
>>> debugger = lldb.SBDebugger.Create()<br>
>>><br>
>>> print('Working Directory: %s' % os.getcwd())<br>
>>> debugger.HandleCommand('target create /usr/bin/find')<br>
>>> debugger.HandleCommand('run .')<br>
>>> _interctive_loop(debugger)<br>
>>><br>
>>> if __name__ == '__main__':<br>
>>> main()<br>
>>><br>
>>><br>
>>> _______________________________________________<br>
>>> lldb-dev mailing list<br>
>>> <a href="mailto:lldb-dev@lists.llvm.org" target="_blank">lldb-dev@lists.llvm.org</a><br>
>>> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev</a><br>
>>><br>
> _______________________________________________<br>
> lldb-dev mailing list<br>
> <a href="mailto:lldb-dev@lists.llvm.org" target="_blank">lldb-dev@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev</a><br>
<br>
</div></div></blockquote></div><br></div>
</div></blockquote></div><br></div></div></div></div></blockquote></div><br></div>
</div></blockquote></div><br></div></div></div></div></div></blockquote></div><br></div>