[lldb-dev] Understanding debugger launch events sequence

Jeffrey Tan via lldb-dev lldb-dev at lists.llvm.org
Thu Jan 28 19:53:28 PST 2016


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:
dbg> bt
* thread #1: tid = 0x15153e, 0x00007fff5fc0d2af
dyld`gdb_image_notifier(dyld_image_mode, unsigned int, dyld_image_info
const*) + 1
  * frame #0: 0x00007fff5fc0d2af dyld`gdb_image_notifier(dyld_image_mode,
unsigned int, dyld_image_info const*) + 1
    frame #1: 0x000000000000401d

But some other binaries, it just print "Process event: stopped, reason: 1"
and inferior just exits immediately without waiting for debugger's further

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?
2. What about attach?
3. What is the dyld`gdb_image_notifier() debugger break above? Why does it
happen for some binary but not others?

Thanks for any information!

# Should be first for LLDB package to be added to search path.
from find_lldb import lldb
from lldb import eStateStepping, eStateRunning, eStateExited, SBBreakpoint,
SBEvent, SBListener, SBProcess, SBTarget
import sys
import os
import subprocess
from sys import stdin, stdout
from threading import Thread

class LLDBListenerThread(Thread):
    should_quit = False

    def __init__(self, process):
      self.listener = SBListener('Chrome Dev Tools Listener')

    def _add_listener_to_target(self, target):
        # Listen for breakpoint/watchpoint events
        broadcaster = target.GetBroadcaster()
        mask = SBTarget.eBroadcastBitBreakpointChanged |
SBTarget.eBroadcastBitWatchpointChanged |
        broadcaster.AddListener(self.listener, mask)

    def _add_listener_to_process(self, process):
        # Listen for process events (Start/Stop/Interrupt/etc).
        broadcaster = process.GetBroadcaster()
        mask = SBProcess.eBroadcastBitStateChanged
        broadcaster.AddListener(self.listener, mask)

    def _broadcast_process_state(self, process):
        state = 'stopped'
        if process.state == eStateStepping or process.state ==
            state = 'running'
        elif process.state == eStateExited:
            state = 'exited'
            self.should_quit = True
        thread = process.selected_thread
        print 'Process event: %s, reason: %d' % (state,

    def _breakpoint_event(self, event):
        breakpoint = SBBreakpoint.GetBreakpointFromEvent(event)
        print 'Breakpoint event: %s' % str(breakpoint)

    def run(self):
        while not self.should_quit:
            event = SBEvent()
            if self.listener.WaitForEvent(1, event):
                if event.GetType() == SBTarget.eBroadcastBitModulesLoaded:
                    print 'Module load: %s' % str(event)
                elif SBProcess.EventIsProcessEvent(event):

                elif SBBreakpoint.EventIsBreakpointEvent(event):

def _interctive_loop(debugger):
    process = debugger.GetSelectedTarget().process
    event_thread = LLDBListenerThread(process)

    while (True):
        stdout.write('dbg> ')
        command = stdin.readline().rstrip()
        if len(command) == 0:

def main():
    debugger = lldb.SBDebugger.Create()

    print('Working Directory: %s' % os.getcwd())
    debugger.HandleCommand('target create /usr/bin/find')
    debugger.HandleCommand('run .')

if __name__ == '__main__':
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20160128/cb30560f/attachment.html>

More information about the lldb-dev mailing list