我最近从 Mac OS X 10.7 升级到 10.9。由于 OS X 不再支持 gdb,我通过 macports 安装了 GNU gdb。在能够使用它之前,我必须按照这里的描述对其进行代码设计。现在我可以使用 gdb 作为调试器,但是在附加到进程时设置断点时遇到问题。我给你举个例子。我拿了这个示例 C 代码
#include <unistd.h>
#include <stdio.h>
void f() {
printf("f()\n");
}
int main() {
printf("sleeping 30 seconds...\n");
sleep(30);
printf("invoking f()\n");
f();
}
并编译它
gcc -g a.c
如果我现在尝试通过做调试
gdb a.out
并在 gdb 中运行它,结果如下(如预期的那样)
GNU gdb (GDB) 7.6
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin13.0.0".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /private/tmp/a.out...Reading symbols from /private/tmp/a.out.dSYM/Contents/Resources/DWARF/a.out...done.
done.
(gdb) break f
Breakpoint 1 at 0x100000ee0: file a.c, line 5.
(gdb) r
Starting program: /private/tmp/a.out
sleeping 30 seconds...
invoking f()
Breakpoint 1, f () at a.c:5
5 printf("f()\n");
(gdb) c
Continuing.
f()
[Inferior 1 (process 78776) exited with code 012]
(gdb)
所以我所做的就是打开 gdb,在函数 f() 处设置断点,运行程序,然后在 f() 内停止时简单地发出 continue 命令。如果我现在执行相同操作但附加到已运行的进程,则无法设置断点,并且在发出 continue 命令以使进程在附加后继续时也会出错。结果如下:
GNU gdb (GDB) 7.6
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin13.0.0".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) attach 78794
Attaching to process 78794
Reading symbols from /private/tmp/a.out...Reading symbols from /private/tmp/a.out.dSYM/Contents/Resources/DWARF/a.out...done.
done.
0x00007fff8516da3a in ?? ()
(gdb) break f
Cannot access memory at address 0x100000edc
(gdb) c
Continuing.
warning: Mach error at "darwin-nat.c:726" in function "void darwin_resume_thread(struct inferior *, darwin_thread_t *, int, int)": (os/kern) failure (0x5)
[Inferior 1 (process 78794) exited normally]
(gdb)
因此,首先在附加时,gdb 没有提供有关代码中当前位置的任何信息(0x00007fff8516da3a in ?? ()),这可能没问题,因为我很可能在进程处于 sleep() 函数时停止了该进程.
但是,当我尝试在 f() 处设置断点时,出现“无法访问内存”错误,并且断点显然没有设置。事实上,当我发出 continue 命令时,该过程会照常继续并终止,而不会在 f() 处停止。
此外,在尝试继续时,我还会收到此“Mach error at [...] (os/kern) failure (0x5)”。即使使用设置断点也不起作用
(gdb) break a.c:5
Cannot access memory at address 0x100000edc
我也尝试搜索网络和stackoverflow,但我没有找到这个问题的答案。任何帮助表示赞赏。