python SBBreakpoint questions

Hi,

I'm having trouble using breakpoints with the python API... My script creates a bunch of breakpoints (by address), launches the target and then goes into an infinite loop checking 'process.GetState()'. The scripts checks for a state of 'eStateStopped', and then iterates through the threads until it finds a thread stop reason of 'eStopReasonBreakpoint'. The issue with that approach is that I can't figure out which breakpoint triggered the thread to stop. So I guess I have two questions, (1) how do I use SetCallback() to call a method when a breakpoint is triggered and (2) if I know which thread hit my breakpoint, how do I know which SBBreakpoint triggered?

BTW, I looked through all of the unit test for examples of how to do this but all I could find was a call to SetCallback(None, None). The documentation for SBBreakpoint gives a prototype of SetCallback(BreakpointHitCallback callback, void baton) but BreakpointHitCallback doesn't appear to be documented in the python docs.

Any help would be greatly appreciated. :slight_smile:

--bill

Op 19-10-2012 20:26, Bill Terwilliger schreef:

Hi,

I'm having trouble using breakpoints with the python API... My script creates a bunch of breakpoints (by address), launches the target and then goes into an infinite loop checking 'process.GetState()'. The scripts checks for a state of 'eStateStopped', and then iterates through the threads until it finds a thread stop reason of 'eStopReasonBreakpoint'. The issue with that approach is that I can't figure out which breakpoint triggered the thread to stop. So I guess I have two questions, (1) how do I use SetCallback() to call a method when a breakpoint is triggered and (2) if I know which thread hit my breakpoint, how do I know which SBBreakpoint triggered?

BTW, I looked through all of the unit test for examples of how to do this but all I could find was a call to SetCallback(None, None). The documentation for SBBreakpoint gives a prototype of SetCallback(BreakpointHitCallback callback, void baton) but BreakpointHitCallback doesn't appear to be documented in the python docs.

Any help would be greatly appreciated. :slight_smile:

There's an events sample for python. Essentially you have a thread waiting for events on a listener, the wait call returns and the SBEvent you get then can be retrieved:

SBEvent data;
while (!stop) {
if (self->m_listener.WaitForEvent(UINT32_MAX, data)) {
   if (data.getType() == SBProcess::eBroadcastBitStateChanged && m_process.GetStateFromEvent (data) == eStateStopped) {
     SBThread th = m_process.GetSelectedThread();
     if (th.GetStopReason() == eStopReasonBreakpoint) {
       // th.GetStopReasonDataAtIndex(0) should have the breakpoint id
     }
   }
}

something like that

Thanks Carlo! I am able to find the current breakpoint with GetStopReasonDataAtIndex(0).

New problem… when I find my breakpoint, I'm calling bp.SetEnabled(False) and then process.Continue(), and that seems to work as expected. But later when I use target.breakpoint_iter() to iterate over all of the breakpoints, it stops iterating after a single breakpoint. The script is setting 12 breakpoints, 9 of them are being triggered (and disabled.) My understanding of the code is that all 12 breakpoints should still be there regardless of the their 'enabled' state. When I take out the bp.SetEnabled(False) line, the iterator continues to work as expected. Is this a bug or am I doing something else wrong?

--bill

You can always just use the actual API:

    uint32_t
    SBTarget::GetNumBreakpoints () const;

    lldb::SBBreakpoint
    SBTarget::GetBreakpointAtIndex (uint32_t idx) const;

"breakpoint_iter" should be doing the right thing as it is defined in lldb.py (which is in LLDB.framework/Resources/python/lldb):

    def breakpoint_iter(self): return lldb_iter(self, 'GetNumBreakpoints', 'GetBreakpointAtIndex')

This calls lldb_iter:

# Iterator for lldb container objects
# ===================================
def lldb_iter(obj, getsize, getelem):
    """A generator adaptor to support iteration for lldb container objects."""
    size = getattr(obj, getsize)
    elem = getattr(obj, getelem)
    for i in range(size()):
        yield elem(i)

I'm an idiot. My iterator issue was because I was also checking that bp.GetNumResolvedLocations > 0. And of course that would fail if the breakpoint was disabled.

Thank you everyone for your help. :slight_smile: