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

dev*_*ull 4 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)
Run Code Online (Sandbox Code Playgroud)

但所有这些变种都不起作用.

在标签中添加gdb希望相同的语义(如果存在)也可以在lldb上运行.

Jim*_*ham 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"
Run Code Online (Sandbox Code Playgroud)

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

现在我想打电话给那个地址.我分两步完成这项工作,因为它使铸造更容易,例如:

(lldb) expr typedef int (*$printf_type)(const char *, ...)
(lldb) expr $printf_type $printf_function = ($printf_type) 0x00007fff91307948
Run Code Online (Sandbox Code Playgroud)

现在我有一个我可以反复调用的函数:

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

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