Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mac OS X上GDB中使用strcmp()的条件断点与Objective-C运行时冲突_Objective C_C_Macos_Gdb - Fatal编程技术网

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

Mac OS X上GDB中使用strcmp()的条件断点与Objective-C运行时冲突,objective-c,c,macos,gdb,Objective C,C,Macos,Gdb,我正试图调试一个在Mac OS X上没有源代码的程序。我想知道它调用的参数是什么,并检查两个不同卷的返回值(以便比较和了解为什么它允许您使用一个卷而不是另一个卷) 我第一次尝试了dtruss;但是这对于getattrlist()是没有用的;它只显示传递到getattrlist()的指针(甚至不知道getattrlist()需要多少参数) 所以我尝试了GDB。我可以在getattrlist()上设置一个无条件断点,并查看它的第一个参数,但它的调用过于频繁,因此不太有用 (gdb) break ge

我正试图调试一个在Mac OS X上没有源代码的程序。我想知道它调用的参数是什么,并检查两个不同卷的返回值(以便比较和了解为什么它允许您使用一个卷而不是另一个卷)

我第一次尝试了dtruss;但是这对于
getattrlist()
是没有用的;它只显示传递到
getattrlist()
的指针(甚至不知道
getattrlist()
需要多少参数)

所以我尝试了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()
”,所以我决定再次尝试
关闭objc非阻塞模式。还是不走运:

(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

在GDB的最新版本中:

(gdb) start
(gdb) break a_leg if $_streq(foo, "foobar")

我不确定这是在哪个版本中引入的,但它至少在7.7.1中出现了。

这是一个很好的建议,但不起作用。我已经用细节更新了我的问题。啊!再加上使用
将objc非阻塞模式设置为off
,似乎达到了目的,尽管我不知道它使应用程序处于什么状态。我说得太快了。很抱歉简单地接受了你的回答;但问题仍然存在。@BrianCampbell np,我没有这么难尝试的mac/mac gdb,如果您想尝试最近的FSF gdb,有新的$_streq()便利函数,祝您找到解决方案好运(否则可能是永远丑陋的((char*)$rdi)[0]=='/'&…我认为FSF gdb在Mac OS X上不起作用;苹果已经改变太多了。
((char*)$rdi[0]
方法确实有效;实际上,我可以走一点捷径,只看几个独特的字符。谢谢!为了防止rdi寄存器出现不必要的错误,
如果$\u streq((char*),则断开位置$rdi,“foobar”)
(gdb) start
(gdb) break a_leg if $_streq(foo, "foobar")