2011-04-16 33 views
1

不運行GDB,但只運行程序本身。C++獲取「Segmentation Fault」的文件名和行號Linux x64

編輯:我已經看到了這樣的程序,但我不明白怎麼做,我自己:(

+1

此問題目前無法解答。你的代碼在哪裏? – 2011-04-16 00:19:07

+0

相關:http://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes – Potatoswatter 2011-04-16 04:10:58

回答

6

Tommie值得信譽解決這一問題。

我已經使用<execinfo.h>的標準backtrace實用程序從GDB中分離出他的答案。

static void dumpstack(void){ 
    static void *backbuf[ 50 ]; 
    int levels; 

    levels = backtrace(backbuf, 50); 
    backtrace_symbols_fd(backbuf, levels, STDERR_FILENO); 

    return; 
} 

您可以嘗試打開一個文件,寫,而不是STDERR_FILENO,但我會避免在墜毀過程中這樣繁重。

在我的系統,輸出看起來是這樣的:

Shadow:code dkrauss$ ./dumpy 
0 dumpy        0x0000000100000d81 dumpstack + 25 
1 dumpy        0x0000000100000d18 signal_handler + 47 
2 libSystem.B.dylib     0x00007fff86b1766a _sigtramp + 26 
3 ???         0x0000000000000000 0x0 + 0 
4 dumpy        0x0000000100000a18 start + 52 
FATAL: Segmentation Fault 

所以,它並沒有給文件名+行號,但它確實給函數名+碼偏移,您可以輕鬆地翻譯不夠。

+0

ahhh爲榮譽歡呼...有趣的是這種回溯 - 不知道這個...從我+1! :d – t0mm13b 2011-04-16 13:12:18

0

到底爲什麼你不希望運行GDB你可以很容易的,如果檢測到段錯誤的位置?你使用它。

+1

,因爲我不希望任何人使用該程序運行GDB ..? – Tenev 2011-04-16 00:58:34

+0

在某些情況下,您無法運行gdb:1)當您構建的部分項目由Makefile運行時。 2)當嵌入低資源 – lalebarde 2014-11-21 09:14:42

5

嗯......你可以嘗試做這種方式...

struct sigaction g_sigact; 

void panic(const char *fmt, ...){ 
    char buf[PANICBUF_LEN]; 
    va_list argptr; 
    va_start(argptr, fmt); 
    vsprintf(buf, fmt, argptr); 
    va_end(argptr); 
    fprintf(stderr, "%s\n", buf); 
    exit(-1); 
} 
void init_signals(void){ 
    g_sigact.sa_handler = signal_handler; 
    sigemptyset(&g_sigact.sa_mask); 
    g_sigact.sa_flags = 0; 
    sigaction(SIGINT, &g_sigact, (struct sigaction *)NULL); 

    sigaddset(&g_sigact.sa_mask, SIGSEGV); 
    sigaction(SIGSEGV, &g_sigact, (struct sigaction *)NULL); 

    sigaddset(&g_sigact.sa_mask, SIGBUS); 
    sigaction(SIGBUS, &g_sigact, (struct sigaction *)NULL); 

    sigaddset(&g_sigact.sa_mask, SIGQUIT); 
    sigaction(SIGQUIT, &g_sigact, (struct sigaction *)NULL); 

    sigaddset(&g_sigact.sa_mask, SIGHUP); 
    sigaction(SIGHUP, &g_sigact, (struct sigaction *)NULL); 

    sigaddset(&g_sigact.sa_mask, SIGKILL); 
    sigaction(SIGKILL, &g_sigact, (struct sigaction *)NULL); 
} 

static void signal_handler(int sig){ 
    if (sig == SIGHUP) g_keepRunning = 0; 
    if (sig == SIGSEGV || sig == SIGBUS){ 
     dumpstack(); 
     panic("FATAL: %s Fault\n", (sig == SIGSEGV) ? "Segmentation" : ((sig == SIGBUS) ? "Bus" : "Unknown")); 
    } 
    if ((sig == SIGQUIT || (sig == SIGKILL) || (sig == SIGINT)) ; 
} 

static void dumpstack(void){ 
    /* Got this routine from http://www.whitefang.com/unix/faq_toc.html 
    ** Section 6.5. Modified to redirect to file to prevent clutter 
    */ 
    char dbx[160]; 
    sprintf(dbx, "echo -ne 'detach\n' | gdb --eval-command=where --pid=%d > %d.dump", getpid(), getpid()); 
    system(dbx); 
    return; 
} 

當分段故障被困,dumpstack被調用並打印最近的堆棧跟蹤到當它分段出現故障並獲得重定向時,請點特德與文件的數字pid的過程....

+0

不錯,但沒有真正的工作 – Tenev 2011-04-16 01:35:40

+0

得到它在Darwin/OS X上工作。你在'(sig == SIGQUIT'之後缺少一個關閉的paren,並且我必須調整GDB命令到' sprintf(dbx,「echo'attach%d \ nwhere \ ndetach'| gdb>%d.dump」,getpid(),getpid());' - 這看起來更具可移植性@Tenev:嘗試那些修復 – Potatoswatter 2011-04-16 01:42:40

+0

i'已經得到它與一些修改工作,不得不使用一些海灣合作委員會的選項,以啓用函數名稱:) – Tenev 2011-04-17 19:24:01

相關問題