我可以告诉LLDB删除活动断点吗?

时间:2015-02-13 23:02:15

标签: debugging breakpoints lldb

当LLDB触发断点X时,是否有一个命令可以禁用或删除X然后继续?

1 个答案:

答案 0 :(得分:2)

这是一个有趣的想法。在lldb中没有内置命令来执行此操作,但它很容易实现为用Python编写的用户定义命令。如果该线程因断点而停止,则SBThread::GetStopReason()将为eStopReasonBreakpointSBThread::GetStopReasonDataCount()将返回2 - 表示断点ID和位置ID可用。 SBThread::GetStopReasonDataAtIndex(0)会为您提供断点ID,SBThread::GetStopReasonDataAtIndex(1)会为您提供位置ID。 (单个用户指定的断点可以解析为多个位置。例如内联函数,或单个程序中多个库中出现的函数名称。)

这是一个快速的&执行此操作的python命令的脏示例。我把它放在~/lldb我保存lldb用户定义命令的位置,然后在我的~/.lldbinit文件中我有一行command script import ~/lldb/disthis.py

在使用中,它看起来像这样:

% lldb a.out
(lldb) target create "a.out"
Current executable set to 'a.out' (x86_64).
(lldb) br s -n main
Breakpoint 1: where = a.out`main + 15 at a.c:4, address = 0x0000000100000f4f
(lldb) r
Process 67487 launched: '/private/tmp/a.out' (x86_64)
Process 67487 stopped
* thread #1: tid = 0x290c51, 0x0000000100000f4f a.out`main + 15 at a.c:4, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    #0: 0x0000000100000f4f a.out`main + 15 at a.c:4
   1    #include <stdio.h>
   2    int main()
   3    {
-> 4        puts ("HI");
   5        puts ("HI");
   6    }
(lldb) com scr imp ~/lldb/disthis.py
(lldb) disthis
Breakpoint 1.1 disabled.
(lldb) br li
Current breakpoints:
1: name = 'main', locations = 1
  1.1: where = a.out`main + 15 at a.c:4, address = 0x0000000100000f4f, unresolved, hit count = 1  Options: disabled 

(lldb) 

非常简单。

# import this into lldb with a command like
# command script import disthis.py

import lldb

def disthis(debugger, command, *args):
    """Usage: disthis
Disables the breakpoint the currently selected thread is stopped at."""

    target = None
    thread = None

    if len(args) == 2:
        # Old lldb invocation style
        result = args[0]
        if debugger and debugger.GetSelectedTarget() and debugger.GetSelectedTarget().GetProcess():
            target = debugger.GetSelectedTarget()
            process = target.GetProcess()
            thread = process.GetSelectedThread()
    elif len(args) == 3:
        # New (2015 & later) lldb invocation style where we're given the execution context
        exe_ctx = args[0]
        result = args[1]
        target = exe_ctx.GetTarget()
        thread = exe_ctx.GetThread()
    else:
        print "Unknown python function invocation from lldb."
        return

    if thread == None:
        print >>result, "error: process is not paused, or has not been started yet."
        result.SetStatus (lldb.eReturnStatusFailed)
        return

    if thread.GetStopReason() != lldb.eStopReasonBreakpoint:
        print >>result, "error: not stopped at a breakpoint."
        result.SetStatus (lldb.eReturnStatusFailed)
        return

    if thread.GetStopReasonDataCount() != 2:
        print >>result, "error: Unexpected number of StopReasonData returned, expected 2, got %d" % thread.GetStopReasonDataCount()
        result.SetStatus (lldb.eReturnStatusFailed)
        return

    break_num = thread.GetStopReasonDataAtIndex(0)
    location_num = thread.GetStopReasonDataAtIndex(1)

    if break_num == 0 or location_num == 0:
        print >>result, "error: Got invalid breakpoint number or location number"
        result.SetStatus (lldb.eReturnStatusFailed)
        return

    bkpt = target.FindBreakpointByID (break_num)
    if location_num > bkpt.GetNumLocations():
        print >>result, "error: Invalid location number"
        result.SetStatus (lldb.eReturnStatusFailed)
        return

    bkpt_loc = bkpt.GetLocationAtIndex(location_num - 1)
    if bkpt_loc.IsValid() != True:
        print >>result, "error: Got invalid BreakpointLocation"
        result.SetStatus (lldb.eReturnStatusFailed)
        return

    bkpt_loc.SetEnabled(False)
    print >>result, "Breakpoint %d.%d disabled." % (break_num, location_num)
    return


def __lldb_init_module (debugger, dict):
    debugger.HandleCommand('command script add -f %s.disthis disthis' % __name__)