当LLDB触发断点X时,是否有一个命令可以禁用或删除X然后继续?
答案 0 :(得分:2)
这是一个有趣的想法。在lldb中没有内置命令来执行此操作,但它很容易实现为用Python编写的用户定义命令。如果该线程因断点而停止,则SBThread::GetStopReason()
将为eStopReasonBreakpoint
。 SBThread::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__)