首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >gdb:为SIGBUS处理程序设置断点

gdb:为SIGBUS处理程序设置断点
EN

Stack Overflow用户
提问于 2010-01-12 03:04:41
回答 4查看 4.1K关注 0票数 10

我正在尝试使用GDB调试一个简单的停止复制垃圾收集器(用C编写)。GC通过处理SIGBUS来工作。我在SIGBUS信号处理程序的顶部设置了一个断点。我已经告诉GDB将SIGBUS传递给我的程序。然而,它似乎不起作用。

下面的程序(内联解释)显示了我的问题的本质:

代码语言:javascript
复制
#include <stdio.h>
#include <sys/mman.h>
#include <assert.h>
#include <signal.h>

#define HEAP_SIZE 4096

unsigned long int *heap;

void gc(int n) {
  signal(SIGBUS, SIG_DFL); // just for debugging
  printf("GC TIME\n");
}

int main () {

  // Allocate twice the required heap size (two semi-spaces)
  heap = mmap(NULL, HEAP_SIZE * 2, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED,
              -1, 0);
  assert (heap != MAP_FAILED);
  // 2nd semi-space is unreadable. Using "bump-pointer allocation", a SIGBUS
  // tells us we are out of space and need to GC.
  void *guard = mmap(heap + HEAP_SIZE, HEAP_SIZE, PROT_NONE, MAP_ANON |
                     MAP_SHARED | MAP_FIXED, -1, 0);
  assert (guard != MAP_FAILED);
  signal(SIGBUS, gc);
  heap[HEAP_SIZE] = 90; // pretend we are out of heap space
  return 0;
} 

我在Mac OS X 10.6上编译并运行该程序,得到了我期望的输出:

代码语言:javascript
复制
$ gcc debug.c
$ ./a.out
GC TIME
Bus error

我想运行和调试这个程序使用GDB。特别是,我想在gc函数(实际上是gc信号处理程序)上设置一个断点。当然,我也需要告诉GDB不要在SIGBUS上停顿:

代码语言:javascript
复制
$ gdb ./a.out 
GNU gdb 6.3.50-20050815 (Apple version gdb-1346) (Fri Sep 18 20:40:51 UTC 2009)
... snip ...
(gdb) handle SIGSEGV SIGBUS nostop noprint
Signal        Stop  Print   Pass to program Description
SIGBUS        No    No  Yes     Bus error
SIGSEGV       No    No  Yes     Segmentation fault
(gdb) break gc
Breakpoint 1 at 0x100000d6f

然而,我们永远不会到达断点:

代码语言:javascript
复制
(gdb) run
Starting program: /snip/a.out 
Reading symbols for shared libraries +. done

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x0000000100029000
0x0000000100000e83 in main ()
(gdb) 

显然,信号处理程序没有被调用(GC时间没有打印出来)。此外,我们仍然在main()中,在出错的移动中:

代码语言:javascript
复制
0x0000000100000e83 <main+247>:  movq   $0x5a,(%rax)

有什么想法吗?

谢谢。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-01-12 05:18:25

相同的代码(修改后也可以处理SIGSEGV )在Linux上的GDB中可以正常工作;它可能是OS或GDB到该平台的端口中的错误。

谷歌在10.1版本中找到的broken OS X behavior和你的一样,有一种变通方法(在运行程序之前使用set inferior-bind-exception-port off)。

(这里有一个similar bug on Windows。)

票数 5
EN

Stack Overflow用户

发布于 2011-07-29 05:50:35

在内部,错误的内存访问会导致将马赫异常EXC_BAD_ACCESS发送到程序。通常,这会转换为SIGBUS UNIX信号。然而,gdb在信号转换之前直接拦截Mach异常。解决方案是在运行程序之前向gdb提供命令set dont-handle-bad-access 1。然后使用普通机制,并支持信号处理程序中的断点。

票数 6
EN

Stack Overflow用户

发布于 2010-01-12 03:26:13

for( ;; );放在printf()之后,正常运行程序,然后在GC时间打印输出后使用gdb连接到进程,如何?

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2044179

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档