<div dir="ltr">Hi,<div><br></div><div>On mac OS, I am having difficulty understanding the launch debugger events sequence of lldb. I used the following code to play around LLDB. I found, for some binaries, debugger will enter stopped/paused mode, waiting for my further input, print stack shows:</div><div><div>dbg> bt</div><div>* thread #1: tid = 0x15153e, 0x00007fff5fc0d2af dyld`gdb_image_notifier(dyld_image_mode, unsigned int, dyld_image_info const*) + 1</div><div>  * frame #0: 0x00007fff5fc0d2af dyld`gdb_image_notifier(dyld_image_mode, unsigned int, dyld_image_info const*) + 1</div><div>    frame #1: 0x000000000000401d</div></div><div><br></div><div>But some other binaries, it just print "Process event: stopped, reason: 1" and inferior just exits immediately without waiting for debugger's further input. </div><div><br></div><div>Questions:</div><div>1. When I launch a binary, is there supposed to be a loader breakpoint waiting for debugger continue? Any other debug events do I expect to get and continue?</div><div>2. What about attach? </div><div>3. What is the dyld`gdb_image_notifier() debugger break above? Why does it happen for some binary but not others?</div><div><br></div><div>Thanks for any information!</div><div><br></div><div><div># Should be first for LLDB package to be added to search path.</div><div>from find_lldb import lldb<br></div><div>from lldb import eStateStepping, eStateRunning, eStateExited, SBBreakpoint, SBEvent, SBListener, SBProcess, SBTarget</div><div>import sys</div><div>import os</div><div>import subprocess</div><div>from sys import stdin, stdout</div><div>from threading import Thread</div><div><br></div><div>class LLDBListenerThread(Thread):</div><div>    should_quit = False</div><div><br></div><div>    def __init__(self, process):</div><div>      Thread.__init__(self)</div><div>      self.listener = SBListener('Chrome Dev Tools Listener')</div><div>      self._add_listener_to_process(process)</div><div>      self._broadcast_process_state(process)</div><div>      self._add_listener_to_target(process.target)</div><div><br></div><div>    def _add_listener_to_target(self, target):</div><div>        # Listen for breakpoint/watchpoint events (Added/Removed/Disabled/etc).</div><div>        broadcaster = target.GetBroadcaster()</div><div>        mask = SBTarget.eBroadcastBitBreakpointChanged | SBTarget.eBroadcastBitWatchpointChanged | SBTarget.eBroadcastBitModulesLoaded</div><div>        broadcaster.AddListener(self.listener, mask)</div><div><br></div><div>    def _add_listener_to_process(self, process):</div><div>        # Listen for process events (Start/Stop/Interrupt/etc).</div><div>        broadcaster = process.GetBroadcaster()</div><div>        mask = SBProcess.eBroadcastBitStateChanged</div><div>        broadcaster.AddListener(self.listener, mask)</div><div><br></div><div>    def _broadcast_process_state(self, process):</div><div>        state = 'stopped'</div><div>        if process.state == eStateStepping or process.state == eStateRunning:</div><div>            state = 'running'</div><div>        elif process.state == eStateExited:</div><div>            state = 'exited'</div><div>            self.should_quit = True</div><div>        thread = process.selected_thread</div><div>        print 'Process event: %s, reason: %d' % (state, thread.GetStopReason())</div><div><br></div><div>    def _breakpoint_event(self, event):</div><div>        breakpoint = SBBreakpoint.GetBreakpointFromEvent(event)</div><div>        print 'Breakpoint event: %s' % str(breakpoint)</div><div><br></div><div>    def run(self):</div><div>        while not self.should_quit:</div><div>            event = SBEvent()</div><div>            if self.listener.WaitForEvent(1, event):</div><div>                if event.GetType() == SBTarget.eBroadcastBitModulesLoaded:</div><div>                    print 'Module load: %s' % str(event)</div><div>                elif SBProcess.EventIsProcessEvent(event):</div><div>                    self._broadcast_process_state(SBProcess.GetProcessFromEvent(event))</div><div>                elif SBBreakpoint.EventIsBreakpointEvent(event):</div><div>                    self._breakpoint_event(event)</div><div><br></div><div>def _interctive_loop(debugger):</div><div>    process = debugger.GetSelectedTarget().process</div><div>    event_thread = LLDBListenerThread(process)</div><div>    event_thread.start()</div><div><br></div><div>    while (True):</div><div>        stdout.write('dbg> ')</div><div>        command = stdin.readline().rstrip()</div><div>        if len(command) == 0:</div><div>            continue</div><div>        debugger.HandleCommand(command)</div><div><br></div><div><br></div><div>def main():</div><div>    debugger = lldb.SBDebugger.Create()</div><div><br></div><div>    print('Working Directory: %s' % os.getcwd())</div><div>    debugger.HandleCommand('target create /usr/bin/find')</div><div>    debugger.HandleCommand('run .')</div><div>    _interctive_loop(debugger)</div><div><br></div><div>if __name__ == '__main__':</div><div>    main()</div></div><div><br></div></div>