gpt4 book ai didi

objective-c - 在 Mac OS X 上的 GDB 中使用 strcmp() 的条件断点与 Objective-C 运行时冲突

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

我正在尝试调试一个我没有 Mac OS X 源代码的程序。我想知道它调用 gettattrlist() 的参数是什么,并检查两个不同卷的返回值(按顺序比较并了解为什么它会让您使用一个卷而不是另一个)。

我首先尝试了dtruss;但这对 getattrlist() 没用;它只显示传递给 getattrlist() 的指针(甚至不知道 getattrlist() 有多少参数)。

  635/0x1dc5:  getattrlist("/Volumes/MyVolume\0", 0x113FA6380, 0x113FA5FD0)                 = 0 0
635/0x1dc5: getattrlist("/Volumes/MyVolume\0", 0x113FA4F00, 0x113FA4B30) = 0 0
635/0x1dc5: getattrlist("/Volumes/MyVolume\0", 0x113FA5870, 0x113FA54C0) = 0 0
635/0x19c6: getattrlist("/Volumes/MyVolume\0", 0x7FFF5FBF9140, 0x7FFF5FBF8D70) = 0 0
635/0x19c6: getattrlist("/Volumes/MyVolume\0", 0x7FFF5FBFA8A0, 0x7FFF5FBFA4F0) = 0 0

所以我尝试了 GDB。我可以在 getattrlist() 上设置一个无条件断点,并查看它的第一个参数,但它被调用得太频繁以至于没有用。

(gdb) break getattrlist
Breakpoint 1 at 0x7fff8e90b6ac
(gdb) cont
Continuing.

Breakpoint 1, 0x00007fff8e90b6ac in getattrlist ()
(gdb) p (char *)$rdi
$1 = 0x7fff5fbfd67e "/some/random/path"

所以,我可能需要一个条件断点,它只会在第一个参数匹配我感兴趣的路径时中断。这应该不会太难,对吧?

(gdb) delete
Delete all breakpoints? (y or n) y
(gdb) break getattrlist if ((int)strcmp((char *)$rdi, "/Volumes/My Volume")) == 0
Breakpoint 2 at 0x7fff8e90b6ac
(gdb) cont
Continuing.
Canceling call as the malloc lock is held so it isn't safe to call the runtime.
Issue the command:
set objc-non-blocking-mode off
to override this check if you are sure your call doesn't use the malloc libraries or the ObjC runtime.
Error in testing breakpoint condition:
Canceling call as the malloc lock is held so it isn't safe to call the runtime.
Issue the command:
set objc-non-blocking-mode off
to override this check if you are sure your call doesn't use the malloc libraries or the ObjC runtime.

Breakpoint 2, 0x00007fff8e90b6ac in getattrlist ()
(gdb) p (char *)$rdi
$12 = 0x7fff5fbfd67e "/some/other/random/path"

这是什么? GDB 忽略了我的条件,因为它怀疑它可能会调用 malloc() 或 ObjC 运行时?好吧,strcmp() 不应该调用 malloc();它应该只是逐字节地比较字符串,直到它到达一个空字符。因此,让我们设置消息建议覆盖检查的选项:

(gdb) set objc-non-blocking-mode off
(gdb) cont
Continuing.
Segmentation fault: 11

没有骰子。 GDB 和应用程序都死了。

关于如何在 GDB 的字符串上设置条件观察点而不遇到这个问题有什么建议吗?或捕获 getattrlist() 的参数和返回值(通过输出参数存储)的其他方法,比 dtruss() 效果更好?

编辑

尝试过 matt 的解决方案,但没有成功:

(gdb) set $vol = (char *) malloc((int)strlen("/Volumes/My Volume") + 1)
(gdb) call (int)strcpy($vol, "/Volumes/My Volume")
$1 = 236411760
(gdb) break getattrlist if ((int)strcmp((char *)$rdi, $vol)) == 0
Breakpoint 1 at 0x7fff8e90b6ac
(gdb) cont
Continuing.
Unsafe to run code: malloc zone lock is held for some zone..
Error in testing breakpoint condition:
Canceling call as the malloc lock is held so it isn't safe to call the runtime.
Issue the command:
set objc-non-blocking-mode off
to override this check if you are sure your call doesn't use the malloc libraries or the ObjC runtime.

Breakpoint 1, 0x00007fff8e90b6ac in getattrlist ()
(gdb) p (char *)$rdi
$4 = 0x11a715838 "/some/other/random/path"

我决定尝试使用 memcmp() 而不是 strcmp();也没有运气:

(gdb) break getattrlist if ((int)memcmp((char *)$rdi, $vol, 18)) == 0
Breakpoint 1 at 0x7fff8e90b6ac
(gdb) cont
Continuing.
Unsafe to run code: malloc zone lock is held for some zone..
Error in testing breakpoint condition:
Canceling call as the malloc lock is held so it isn't safe to call the runtime.
Issue the command:
set objc-non-blocking-mode off
to override this check if you are sure your call doesn't use the malloc libraries or the ObjC runtime.

Breakpoint 1, 0x00007fff8e90b6ac in getattrlist ()
(gdb)

在这一点上,我想“好吧,现在真的不应该使用 malloc()”,所以我决定尝试 set objc-non-blocking-mode off 再次。仍然没有运气:

(gdb) set objc-non-blocking-mode off
(gdb) cont
Continuing.
Reading symbols for shared libraries ... done
Reading symbols for shared libraries . done
Reading symbols for shared libraries ....... done
[Switching to process 5456 thread 0x2971b]
[Switching to process 5456 thread 0x29e2f]
warning: Unable to restore previously selected frame.

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000000
[Switching to process 5456 thread 0x29e2f]
0x0000000000000000 in ?? ()
Error in testing breakpoint condition:
The program being debugged was signaled while in a function called from GDB.
GDB remains in the frame where the signal was received.
To change this behavior use "set unwindonsignal on"
Evaluation of the expression containing the function (memcmp) will be abandoned.

Breakpoint 1, 0x0000000000000000 in ?? ()
Error in testing breakpoint condition:
The program being debugged was signaled while in a function called from GDB.
GDB remains in the frame where the signal was received.
To change this behavior use "set unwindonsignal on"
Evaluation of the expression containing the function (memcmp) will be abandoned.

Breakpoint 1, 0x0000000000000000 in ?? ()

嗯。我处于什么状态?

(gdb) bt
#0 0x0000000000000000 in ?? ()
#1 0x000000011e6ec070 in ?? ()

恶心。那看起来不太好。如果我继续在这里怎么办?

(gdb) cont
Continuing.
[Switching to process 5456 thread 0x2971b]
(gdb) bt
#0 0x00007fff8e90b6ac in getattrlist ()
#1 0x00007fff897c9c4b in GetPathVolFSAttributes ()
#2 0x00007fff897c9459 in PathGetObjectInfo ()
#3 0x00007fff897c9279 in FSPathMakeRefInternal ()
#4 0x00007fff8767b3ee in FSNodePrepareFSRef ()
... snip ...
(gdb) p (char *)$rdi
$2 = 0x10db1c2b0 "/System/Library/CoreServices/CoreTypes.bundle"

没有。仍然没有真正中断对 getattrlist() 的正确调用;由于空指针取消引用,一切都在此期间死亡。

最佳答案

我相信像下面这样的东西应该有效。

(gdb) start
...
(gdb) set $x = malloc(strlen("foobar") + 1)
(gdb) call strcpy($x, "foobar")
(gdb) break a_leg if strcmp(foo, $x) == 0

关于objective-c - 在 Mac OS X 上的 GDB 中使用 strcmp() 的条件断点与 Objective-C 运行时冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13961368/

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