GDB:设置一个断点为SIGBUS处理程序 [英] gdb: set a breakpoint for a SIGBUS handler

查看:194
本文介绍了GDB:设置一个断点为SIGBUS处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图调试使用GDB简单的停止和副本垃圾收集器(用C语言编写)。该GC的工作原理是处理SIGBUS。我在我的SIGBUS信号处理程序的顶部设置一个断点。我告诉GDB传递SIGBUS我的计划。然而,它不会出现工作

I'm trying to debug a simple stop-and-copy garbage collector (written in C) using GDB. The GC works by handling SIGBUS. I've set a breakpoint at the top of my SIGBUS signal handler. I've told GDB to pass SIGBUS to my program. However, it doesn't appear to work.

以下程序(解释内嵌)显示我的问题的本质是:

The following program (explained inline) shows the essence of my problem:

#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的程序,并得到输出我预计:

I compile and run the program on Mac OS X 10.6 and get the output I expect:

$ gcc debug.c
$ ./a.out
GC TIME
Bus error

我要运行和调试使用GDB这个程序。我特别想在GC功能(说真的,GC信号处理函数)设置一个断点。当然,我需要告诉GDB不要对SIGBUS暂停,以及:

I want to run and debug this program using GDB. In particular, I want to set a breakpoint at the gc function (really, the gc signal handler). Naturally, I need to tell GDB to not halt on SIGBUS as well:

$ 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

不过,我们永远无法到达断点:

However, we never reach the breakpoint:

(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(),在断层MOV:

Apparently, the signal handler is not invoked (GC TIME is not printed). Furthermore, we're still in main(), at the faulting mov:

0x0000000100000e83 <main+247>:  movq   $0x5a,(%rax)

任何想法?

感谢。

推荐答案

在同一code(修改以处理SIGSEGV太)如预期的GDB Linux上工作;它可能会在OS X或GDB的端口的错误该平台。

The same code (modified to handle SIGSEGV too) works as expected in GDB on Linux; it may be a bug in OS X or GDB's port to that platform.

谷歌搜索发现破OS X的行为就像你回来一路在10.1,与排序的解决方法(设置逊色绑定的异常端口关闭运行程序之前)。

Googling finds broken OS X behavior just like yours all the way back on 10.1, with a sort-of workaround (set inferior-bind-exception-port off before running the program).

(有一个在Windows 类似的错误。)

(There's a similar bug on Windows.)

这篇关于GDB:设置一个断点为SIGBUS处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆