lldb:如何从特定的库/框架中调用函数

时间:2014-01-13 16:16:22

标签: macos gdb lldb

问题:在项目中,我们拥有特定于框架/动态库的本地化功能。也就是说,它们具有相同的名称,但从不同的包/文件夹中获取资源

我想调用特定库中的函数,类似于:

lldb> p my_audio_engine.framework::GetL10nString( stringId );
lldb> expr --shlib my_audio_engine.framework -- GetL10nString();
lldb> p my_audio_engine`L10N_Utils::GetString(40000)

但所有这些变体都不起作用。

在标签中添加gdb希望相同的语义(如果存在)也适用于lldb。

1 个答案:

答案 0 :(得分:12)

lldb的表达式解析器当前没有等效的gdb的foo.c :: function元符号来编码来自特定源文件的函数。

请随时在bugreporter.apple.com上提交错误请求。它会被骗到我前面提到的那个,但是复制品是功能的投票,我们还没有找到这个但是因为除了我之外没有人要求它......

对于nonce,你必须手动完成。这是调用printf的一个愚蠢的例子,我碰巧知道它是在OS X上的libsystem_c.dylib中。首先,我找到了我感兴趣的共享库中的地址:

(lldb) image lookup -vn printf libsystem_c.dylib
1 match found in /usr/lib/system/libsystem_c.dylib:
        Address: libsystem_c.dylib[0x0000000000042948] (libsystem_c.dylib.__TEXT.__text + 266856)
        Summary: libsystem_c.dylib`printf
         Module: file = "/usr/lib/system/libsystem_c.dylib", arch = "x86_64"
         Symbol: id = {0x00000653}, range = [0x00007fff91307948-0x00007fff91307a2c), name="printf"

第一个地址(地址下的那个)是dylib中函数的地址,而不是它在正在运行的程序中加载的地址。这不是立即有用的。我可以计算库的负载偏移量,如果我想将其应用到文件地址,但幸运的是,符号地址范围中的第一个地址是正在运行的程序中的地址,所以我没有必要。 0x00007fff91307948是我想要的地址。

现在我想打电话给那个地址。我分两步这样做,因为它使铸造更容易,如:

(lldb) expr typedef int (*$printf_type)(const char *, ...)
(lldb) expr $printf_type $printf_function = ($printf_type) 0x00007fff91307948

现在我有一个我可以反复调用的功能:

(lldb) expr $printf_function("Hello world %d times.\n", 400)
Hello world 400 times.
(int) $2 = 23

如果你要反复这样做,你可以编写一个Python函数,从感兴趣的库中找到符号,并构造调用正确函数的表达式。 Python API包括从特定模块获取符号的调用(lldb-代表可加载的二进制图像),获取它们的地址,计算表达式等。