gdb結合coredump定位崩潰進程

Linux環境下經常遇到某個進程掛掉而找不到原因,我們可以通過生成core file文件加上gdb來定位。

 
如何產生core file?
我們可以使用ulimit這條命令對core file文件的大小進行設定。
一般默認情況下,core file的大小被設置爲了0,這樣系統就不dump出core file了。
這時用如下命令進行設置:
ulimit -c unlimited
這樣便把core file的大小設置爲了無限大,同時也可以使用數字來替代unlimited,對core file的上限值做更精確的設定。
 
生成的core file在哪裏?
core file生成的地方是在/proc/sys/kernel/core_pattern文件定義的。
改動到生成到自己定義的目錄的方法是:
echo "pattern" > /proc/sys/kernel/core_pattern
並且只有超級用戶可以修改這兩個文件。
"pattern"類似我們C語言打印字符串的格式,相關標識如下:
%%: 相當於%
%p: 相當於<pid>
%u: 相當於<uid>
%g: 相當於<gid>
%s: 相當於導致dump的信號的數字
%t: 相當於dump的時間
%h: 相當於hostname
%e: 相當於執行文件的名稱
這時用如下命令設置生成的core file到系統/tmp目錄下,並記錄pid以及執行文件名
echo "/tmp/core-%e-%p" > /proc/sys/kernel/core_pattern
 
測試如下代碼
?
1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
 
intfunc(int*p)
{
        *p = 0;
}
 
intmain()
{
        func(NULL);
        return0;
}
 
生成可執行文件並運行
gcc -o main a.c
root@ubuntu:~# ./main
Segmentation fault (core dumped) 
<-----這裏出現段錯誤並生成core文件了。
在/tmp目錄下發現文件core-main-10815 
 
如何查看進程掛在哪裏了?
我們可以用
gdb main /tmp/core-main-10815 
查看信息,發現能定位到函數了
Program terminated with signal 11, Segmentation fault.
#0  0x080483ba in func ()
 

如何定位到行?

在編譯的時候開啓-g調試開關就可以了
gcc -o main -g a.c
gdb main /tmp/core-main-10815 
最終看到的結果如下,好棒。
Program terminated with signal 11, Segmentation fault.
#0  0x080483ba in func (p=0x0) at a.c:5
5          *p = 0;
 
總結一下,需要定位進程掛在哪一行我們只需要4個操作,
ulimit -c unlimited
echo "/tmp/core-%e-%p" > /proc/sys/kernel/core_pattern
gcc -o main -g a.c
執行程序
gdb main /tmp/core-main-10815 
就可以啦。
 
補充說明:
相關常用gdb命令
1,(gdb) backtrace /* 查看當前線程函數棧回溯 */
以上面的例子爲例
Program terminated with signal 11, Segmentation fault.
#0  0x080483ba in func (p=0x0) at main.c:5
5*p = 0;
(gdb) backtrace
#0  0x080483ba in func (p=0x0) at main.c:5
#1  0x080483d4 in main () at main.c:10
如果是多線程環境下(gdb) thread apply all backtrace /* 顯示所有線程棧回溯 */
 
2,(gdb) print [var] /* 查看變量值 */
(gdb) print p
$1 = (int *) 0x0
(gdb) print &p
$2 = (int **) 0xbf96d4d4
 
3,(gdb) x/FMT [Address] /* 根據格式查看地址指向的值 */
其中
FMT is a repeat count followed by a format letter and a size letter.
Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),
  t(binary), f(float), a(address), i(instruction), c(char) and s(string).
Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes).
The specified number of objects of the specified size are printed
according to the format.
 
(gdb) x/d 0xbf96d4d4
0xbf96d4d4:0
(gdb) x/c 0xbf96d4d4
0xbf96d4d4:0 '\000'
 
另外能導致產生core file文件的信號有以下10種

SIGQUIT:終端退出符

SIGILL:非法硬件指令

SIGTRAP:平臺相關的硬件錯誤,現在多用在實現調試時的斷點

SIGBUS:與平臺相關的硬件錯誤,一般是內存錯誤

SIGABRT:調用abort函數時產生此信號,進程異常終止

SIGFPE:算術異常

SIGSEGV:segment violation,無效內存引用

SIGXCPU:超過了cpu使用資源限制(setrlimit)

SIGXFSZ:超過了文件長度限制(setrlimit)

SIGSYS:無效的系統調用


使用GDB可能會提示錯誤:

第二次安裝總結:
1、需要先修改“/etc/yum.repos.d/CentOS-Debuginfo.repo”文件的enable=1;
2、使用 sudo yum install glibc 安裝;
3、使用 debuginfo-install glibc-2.12-1.166.el6_7.7.x86_64安裝。
測試,安裝成功。



發佈了76 篇原創文章 · 獲贊 188 · 訪問量 184萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章