簡體   English   中英

gdb:為SIGBUS處理程序設置斷點

[英]gdb: set a breakpoint for a SIGBUS handler

我正在嘗試使用GDB調試一個簡單的停止和復制垃圾收集器(用C語言編寫)。 GC通過處理SIGBUS來工作。 我在SIGBUS信號處理程序的頂部設置了一個斷點。 我告訴GDB將SIGBUS傳遞給我的程序。 但是,它似乎不起作用。

以下程序(內聯解釋)顯示了我的問題的本質:

#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上編譯並運行該程序並獲得我期望的輸出:

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

我想使用GDB運行和調試該程序。 特別是,我想在gc函數(實際上是gc信號處理程序)中設置斷點。 當然,我需要告訴GDB不要停止在SIGBUS上:

$ 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

但是,我們永遠不會到達斷點:

(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 TIME)。 此外,我們仍然在main(),在錯誤的mov:

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

有任何想法嗎?

謝謝。

相同的代碼(修改為處理SIGSEGV)在Linux上的GDB中按預期工作; 它可能是OS X或GDB到該平台的端口中的錯誤。

谷歌搜索破壞了OS X的行為 ,就像你的10.1一樣,有一種解決方法(在運行程序之前set inferior-bind-exception-port off )。

Windows上有類似的錯誤 。)

在內部,壞的內存訪問導致Mach異常EXC_BAD_ACCESS被發送到程序。 通常,這會轉換為SIGBUS UNIX信號。 但是,gdb在信號轉換之前直接截取Mach異常。 解決方案是在運行程序之前給gdb命令set dont-handle-bad-access 1 然后使用常規機制,並且信號處理程序內的斷點得到遵守。

怎么樣把for( ;; ); printf() ,正常運行程序,然后在GC TIME打印出來后用gdb連接到進程?

你為什么期望得到一個SIGBUS? SIGBUS通常表示對齊錯誤,在某些數據類型具有對齊要求的體系結構上。 看起來你只是試圖訪問你分配區域之外的內存,我希望你得到SIGSEGV而不是SIGBUS。

編輯:

似乎我認為SIGSEGV的Mac OS X名稱是SIGBUS。 因此,忽略這個答案。

如果有任何幫助,當我在Linux系統上嘗試該程序時,斷點按預期工作(即工作正常),SIGBUS替換為SIGSEGV。

編輯2:

你能嘗試在你的程序中捕獲SIGSEGV嗎? 似乎信號的類型可能會有所不同,具體取決於Mac OS X中內存的映射位置(我只是閱讀此處此處的討論),並且在調試器中運行時可能會拋出不同的信號?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM