gpt4 book ai didi

objective-c - 将类转储信息导入 GDB

转载 作者:太空狗 更新时间:2023-10-30 03:10:09 24 4
gpt4 key购买 nike

有没有办法将 class-dump 的输出导入到 GDB 中?

示例代码:

$ cat > test.m
#include <stdio.h>
#import <Foundation/Foundation.h>

@interface TestClass : NSObject

+ (int)randomNum;

@end

@implementation TestClass

+ (int)randomNum {
return 4; // chosen by fair dice roll.
// guaranteed to be random.
}

@end

int main(void) {
printf("num: %d\n", [TestClass randomNum]);
return 0;
}
^D

$ gcc test.m -lobjc -o test
$ ./test
num: 4
$ gdb test
...
(gdb) b +[TestClass randomNum]
Breakpoint 1 at 0x100000e5c
(gdb) ^D
$ strip test
$ gdb test
...
(gdb) b +[TestClass randomNum]
Function "+[TestClass randomNum]" not defined.
(gdb) ^D

$ class-dump -A test
...
@interface TestClass : NSObject
{
}

+ (int)randomNum; // IMP=0x0000000100000e50

@end

我知道我现在可以在 gdb 中使用 b *0x0000000100000e50,但是有没有办法修改 GDB 的符号表以使其接受 b +[TestClass随机数]?

编辑:如果它能与 GDB v6 而不仅仅是 GDB v7 一起工作,那将是更好的选择,因为 GDB v6 是带有 Apple 补丁的最新版本。

最佳答案

可以使用 add-symbol-file 命令在 gdb 中加载符号文件。最难的部分是生成这个符号文件。

在 libMachObjC(属于 class-dump 的一部分)的帮助下,很容易转储所有地址及其相应的 Objective-C 方法。我写了一个小工具,objc-symbols正是这样做的。

让我们以 Calendar.app 为例。如果您尝试使用 nm 工具列出符号,您会注意到日历应用程序已被删除:

$ nm -U /Applications/Calendar.app/Contents/MacOS/Calendar 
0000000100000000 T __mh_execute_header
0000000005614542 - 00 0000 OPT radr://5614542

但是使用 objc-symbols 你可以很容易地检索所有丢失的 Objective-C 方法的地址:

$ objc-symbols /Applications/Calendar.app
00000001000c774c +[CALCanvasAttributedText textWithPosition:size:text:]
00000001000c8936 -[CALCanvasAttributedText createTextureIfNeeded]
00000001000c8886 -[CALCanvasAttributedText bounds]
00000001000c883b -[CALCanvasAttributedText updateBezierRepresentation]
...
00000001000309eb -[CALApplication applicationDidFinishLaunching:]
...

然后,使用 SymTabCreator您可以创建一个符号文件,它实际上只是一个包含所有符号的空动态库。

一起使用 objc-symbolsSymTabCreator 很简单:

$ objc-symbols /Applications/Calendar.app | SymTabCreator -o Calendar.stabs

您可以检查 Calendar.stabs 是否包含所有符号:

$ nm Calendar.stabs 
000000010014a58b T +[APLCALSource printingCachedTextSize]
000000010013e7c5 T +[APLColorSource alternateGenerator]
000000010013e780 T +[APLColorSource defaultColorSource]
000000010013e7bd T +[APLColorSource defaultGenerator]
000000010011eb12 T +[APLConstraint constraintOfClass:withProperties:]
...
00000001000309eb T -[CALApplication applicationDidFinishLaunching:]
...

现在让我们看看 gdb 中发生了什么:

$ gdb --silent /Applications/Calendar.app
Reading symbols for shared libraries ................................. done

没有符号文件:

(gdb) b -[CALApplication applicationDidFinishLaunching:]
Function "-[CALApplication applicationDidFinishLaunching:]" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n

加载符号文件后:

(gdb) add-symbol-file Calendar.stabs 
add symbol table from file "Calendar.stabs"? (y or n) y
Reading symbols from /Users/0xced/Calendar.stabs...done.
(gdb) b -[CALApplication applicationDidFinishLaunching:]
Breakpoint 1 at 0x1000309f2

您会注意到断点地址与符号地址不完全匹配(0x1000309f2 vs 0x1000309eb,相差 7 个字节),这是因为 gdb 自动识别函数序言并在其后设置断点。


GDB脚本

假设剥离的可执行文件是当前目标,您可以使用此 GDB 脚本自动执行此操作。

将下面的脚本添加到您的 .gdbinit,以剥离的可执行文件为目标并在 gdb 中运行命令 objc_symbols:

$ gdb test
...
(gdb) b +[TestClass randomNum]
Function "+[TestClass randomNum]" not defined.
(gdb) objc_symbols
(gdb) b +[TestClass randomNum]
Breakpoint 1 at 0x100000ee1
(gdb) ^D

define objc_symbols
shell rm -f /tmp/gdb-objc_symbols

set logging redirect on
set logging file /tmp/gdb-objc_symbols
set logging on

info target

set logging off

shell target="$(head -1 /tmp/gdb-objc_symbols | head -1 | awk -F '"' '{ print $2 }')"; objc-symbols "$target" | SymTabCreator -o /tmp/gdb-symtab

set logging on
add-symbol-file /tmp/gdb-symtab
set logging off
end

关于objective-c - 将类转储信息导入 GDB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17554070/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com