这个问题基本上是Import class-dump info into GDB的克隆,但是使用LLDB而不是GDB。
使用上述问题答案中描述的方法,我可以创建包含名为test.stabs
的符号的符号文件。
要在LLDB中导入和使用此信息,我尝试执行以下操作:
$ lldb test
(lldb) target module add test.stabs
(lldb) b +[TestClass randomNum]
Breakpoint 1: where = test.stabs`+[TestClass randomNum]:F(0,1), address = 0x0000000100000ed0
正如您所见,LLDB可以加载地址,但在实际运行目标时,LLDB不会中断:
(lldb) r
Process 40430 launched: '/Users/Tyilo/test' (x86_64)
num: 4
Process 40430 exited with status = 0 (0x00000000)
您当然可以直接指定断点的地址:
(lldb) b -a 0x0000000100000ed0
它会起作用。
有没有办法让LLDB中的b +[TestClass randomNum]
工作得到断点?
答案 0 :(得分:4)
我已经创建了一个可以用来实现我想要的python函数,但它只在程序运行时才有效。将下面的代码保存为break_message.py
,然后运行command script import break_message.py
将其导入lldb。现在你可以像这样使用它:
$ lldb -p $(pgrep Finder)
(lldb) command script import break_message.py
(lldb) break_message -[TApplicationController cmdEmptyTrash:]
(lldb) continue
现在在Finder中打开废纸篓并清空它(如果它已经是空的,则放入一些东西)。断点将在lldb中命中。
import lldb
import re
def lldb_run(command):
res = lldb.SBCommandReturnObject()
lldb.debugger.GetCommandInterpreter().HandleCommand(command, res)
return res
def lldb_call(command):
res = lldb_run('call ' + command)
out = res.GetOutput()
r = re.compile(r'^[^=]*= (.*)\n$')
m = r.search(out)
return m.groups()[0]
def __lldb_init_module(debugger, internal_dict):
lldb_run('command script add -f break_message.{0} {0}'.format('break_message'))
def break_message(debugger, command, result, internal_dict):
r = re.compile(r'([+-])\s*\[\s*(\S+)\s+([^\]]+)\]')
m = r.search(command)
if not m:
print 'Error in message format!'
return
typ, cls, sel = m.groups()
sel = re.sub(r'\s+', '', sel)
meta = typ == '+'
clsptr = lldb_call('(id)objc_getClass("{}")'.format(cls))
if clsptr == 'nil':
print "Couldn't find class: " + cls
return
selptr = lldb_call('(id)sel_registerName("{}")'.format(sel))
if selptr == 'nil':
print "Couldn't register selector: " + sel
return
func = 'class_getClassMethod' if meta else 'class_getInstanceMethod'
method = lldb_call('(id){}({}, {})'.format(func, clsptr, selptr))
if method == 'nil':
print "Couldn't find method for: " + sel
return
imp = lldb_call('(id)method_getImplementation({})'.format(method))
lldb_run('breakpoint set -a {}'.format(imp))
答案 1 :(得分:1)
lldb认为您的方法名称是+[TestClass randomNum]:F(0,1)
?你的文件名test.stabs
让我觉得它是用stabs调试信息构建的 - 看起来像刺。
lldb对stabs调试格式一无所知 - 你甚至无法用clang生成它 - 我们在Mac OS X和iOS上使用DWARF。您可能会更成功地从您的二进制文件中删除stabs调试信息(请参阅strip(1)
)命令 - 然后lldb不会分心。