Mac OS X Mavericks - gdb - 附加到进程时无法设置断点

Mic*_*ata 5 c debugging macos gdb attach-to-process

我最近从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();
}
Run Code Online (Sandbox Code Playgroud)

并用它编译

gcc -g a.c
Run Code Online (Sandbox Code Playgroud)

如果我现在尝试通过做调试

gdb a.out
Run Code Online (Sandbox Code Playgroud)

并在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)
Run Code Online (Sandbox Code Playgroud)

所以我做的是打开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)
Run Code Online (Sandbox Code Playgroud)

首先,当附加时,gdb没有提供有关代码中当前位置的任何信息(??()中的0x00007fff8516da3a,这可能没问题,因为我很可能在sleep()函数内停止了该过程.

但是,当我尝试将断点设置为f()时,我得到"无法访问内存"错误,并且断点明显没有设置.实际上,当我给出continue命令时,该过程只是正常进行并终止而不停在f().

此外,当我试图继续时,我也会在[...](os/kern)失败(0x5)时得到"马赫错误".即使使用,设置断点也不起作用

(gdb) break a.c:5
Cannot access memory at address 0x100000edc
Run Code Online (Sandbox Code Playgroud)

我也尝试搜索网络和stackoverflow,但我找不到这个问题的答案.任何帮助表示赞赏.

Mic*_*ata 2

我找到了一个(不太令人满意的)问题解决方案。使用MacPorts,我安装了苹果版的GDB:

sudo port install gdb-apple
Run Code Online (Sandbox Code Playgroud)

此版本的 GDB 能够附加到进程并正确设置断点,甚至在 Eclipse CDT 中也是如此。我发现的唯一缺陷是,在 Eclipse 中,我需要在附加到进程之前设置断点。如果我尝试在已连接时设置断点,则该过程将失败。我不知道为什么。

我希望这个答案可以帮助别人,如果你们中有人找到更好的解决方案,我会很高兴知道。