目錄
GDB,全稱 GNU symbolic debugger,簡稱 GDB偵錯程式,是 Linux 平臺下最常用的一款程式偵錯程式
CentOSx下安裝GDB
rpm -qa | grep gdb
[root@]# rpm -qa | grep gdb
gdbm-1.10-8.el7.x86_64
gdbm-devel-1.10-8.el7.x86_64
若安裝,則採用以下命令解除安裝
rpm -e --nodeps [軟體版本]
[root@]# rpm -e --nodeps gdbm-1.10-8.el7.x86_64
[root@]# rpm -e --nodeps gdbm-devel-1.10-8.el7.x86_64
[root@]# wget http://mirrors.ustc.edu.cn/gnu/gdb/gdb-7.9.1.tar.xz
--2020-10-19 15:05:39-- http://mirrors.ustc.edu.cn/gnu/gdb/gdb-7.9.1.tar.xz
Resolving mirrors.ustc.edu.cn (mirrors.ustc.edu.cn)... 202.141.176.110, 218.104.71.170, 2001:da8:d800:95::110
Connecting to mirrors.ustc.edu.cn (mirrors.ustc.edu.cn)|202.141.176.110|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 17867692 (17M) [application/octet-stream]
Saving to: ‘gdb-7.9.1.tar.xz’
100%[====================================================================================================================================================>] 17,867,692 36.5MB/s in 0.5s
2020-10-19 15:05:39 (36.5 MB/s) - ‘gdb-7.9.1.tar.xz’ saved [17867692/17867692]
tar -xf gdb-7.9.1.tar.xz
[root@]# tar -xf gdb-7.9.1.tar.xz
cd gdb-7.9.1
sudo yum install texinfo
./configure
make
sudo make install
[root@]# cd gdb-7.9.1
[root@]# sudo yum install texinfo
.
.
.
Dependency Installed:
perl-Text-Unidecode.noarch 0:0.04-20.el7 perl-libintl.x86_64 0:1.20-12.el7
Complete!
[root@]# ./configure
.
.
.
configure: creating ./config.status
config.status: creating Makefile
[root@]# make
.
.
.
make[1]: Nothing to be done for `all-target'.
make[1]: Leaving directory `/root/.vimplus/gdb-7.9.1'
[root@]# make install
.
.
.
make[1]: Nothing to be done for `install-target'.
make[1]: Leaving directory `/root/.vimplus/gdb-7.9.1'
gdb -v
[root@]# gdb -v
GNU gdb (GDB) 7.9.1
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
命令 簡寫形式 說明
backtrace bt、where 顯示backtrace
break b 設定斷點
continue c、cont 繼續執行
delete d 刪除斷點
finish 執行到函數結束
info breakpoints 顯示斷點資訊
next n 執行下一行
print p 顯示錶示式
run r 執行程式
step s 一次執行一行,包括函數內部
x 顯示記憶體內容
until u 執行到指定行
其他命令
directory dir 插入目錄
disable dis 禁用斷點
down do 在當前呼叫的棧幀中選擇要顯示的棧幀
edit e 編輯檔案或者函數
frame f 選擇要顯示的棧幀
forward-search fo 向前搜尋
generate-core-file gcore 生成核心轉儲存
help h 顯示幫助一覽
info i 顯示資訊
list l 顯示函數或行
nexti ni 執行下一行(以組合程式碼為單位)
print-object po 顯示目標資訊
sharelibrary share 載入共用的符號
stepi si 執行下一行
vim test.c
gcc -g -o test.exe test.c
關於vim/vi的用法這裡不再概述,推薦vim的設定程式vimplus
寫完程式碼後,gcc編譯程式碼(PS. 如果gcc編譯的時候沒有加上-g引數,那麼就不會保留偵錯引數,就不能用gdb偵錯)
測試程式碼如下:
#include<stdio.h>
#include<stdlib.h>
int main( int argc , char *argv[] )
{
int a = 1;
int i = 0;
int b[3] = {0,1,2};
for(i = 0; i < 3;i++)
b[i] = b[i] + 1;
printf("%d\n",a);
int *p;
p = b;
printf("%d\n",p[0]);
return 0;
}
在 Linux 作業系統中,當程式執行發生異常崩潰時,系統可以將發生崩潰時的記憶體資料、呼叫堆疊情況等資訊自動記錄下載,並儲存到一個檔案中,該檔案通常稱為 core 檔案,Linux 系統所具備的這種功能又稱為核心轉儲(core dump)。幸運的是,GDB 對 core 檔案的分析和偵錯提供有非常強大的功能支援,當程式發生異常崩潰時,通過 GDB 偵錯產生的 core 檔案,往往可以更快速的解決問題。
ulimit -a
[root@]# ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 7284
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 65535
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 7284
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
如果 core file size(core 檔案大小)對應的值為 0,表示當前系統未開啟 core dump 功能
ulimit -c unlimited
[root@]# ulimit -c unlimited
[root@]# ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 7284
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 65535
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 7284
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
unlimited 表示不限制 core 檔案的大小
測試程式碼:
1 #include <stdio.h>
2
3 int main()
4 {
5 char *p = NULL;
6 *p = 123;
7 return 0;
8 }
測試結果:
[root@]# vim main.c
[root@]# gcc -g -o main.exe main.c
[root@]# ls
main.c main.exe test.c test.exe
[root@]# ./main.exe
Segmentation fault (core dumped)
[root@]# ls
core.17313 main.c main.exe test.c test.exe
測試程式碼中,發生記憶體存取錯誤,程式崩潰,崩潰資訊存入core.17313檔案中
gdb test.exe
[root@]# gdb test.exe
GNU gdb (GDB) 7.9.1
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test.exe...done.
(gdb)_
根據行號設定斷點
第一種 (gdb) b 5
第二種 (gdb) b test.c:5
根據函數設定斷點
(gdb) b main
根據條件設定斷點
(gdb) b test.c:10 if a == 1
根據偏移量設定斷點
(gdb) b +12
根據地址設定斷點
(gdb) b *0x40059b
設定臨時斷點
臨時斷點只生效一次
(gdb) tbreak test.c:12
(gdb) b test.c:5
Breakpoint 1 at 0x40053c: file test.c, line 5.
(gdb) b main
Note: breakpoint 1 also set at pc 0x40053c.
Breakpoint 2 at 0x40053c: file test.c, line 6.
(gdb) b test.c:10 if a == 1
Breakpoint 3 at 0x400568: file test.c, line 10.
(gdb) b +12
Breakpoint 4 at 0x40059b: file test.c, line 13.
(gdb) b *0x40059b
Note: breakpoint 4 also set at pc 0x40059b.
Breakpoint 5 at 0x40059b: file test.c, line 13.
(gdb) tbreak test.c:12
Note: breakpoints 4 and 5 also set at pc 0x40059b.
Temporary breakpoint 6 at 0x40059b: file test.c, line 12.
顯示所有斷點
(gdb) info break
(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y 0x000000000040053c in main at test.c:5
2 breakpoint keep y 0x000000000040053c in main at test.c:6
3 breakpoint keep y 0x0000000000400568 in main at test.c:10
stop only if a == 1
4 breakpoint keep y 0x000000000040059b in main at test.c:13
5 breakpoint keep y 0x000000000040059b in main at test.c:13
6 breakpoint del y 0x000000000040059b in main at test.c:12
清除斷點
清除某個斷點 (gdb) delete 4
清除所有斷點 (gdb) delete
(gdb) delete 4
(gdb) delete
Delete all breakpoints? (y or n) y
(gdb) info break
No breakpoints or watchpoints.
清除當前行斷點 (gdb) clear
Breakpoint 3, main (argc=1, argv=0x7fffffffe508) at test.c:13
13 p = b;
(gdb) clear
Deleted breakpoint 3
執行 r
繼續單步偵錯 n
繼續執行到下一個斷點 c
檢視原始碼和行號
l
(gdb) l
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main( int argc, char *argv[])
5 {
6 int a = 1;
7 int i = 0;
8 int b[3] = {0, 1, 2};
9 for (i = 0; i < 3; i++)
10 b[i] = b[i] + 1;
(gdb) l
11 printf("%d\n", a);
12 int *p;
13 p = b;
14 printf("%d\n", p[0]);
15 return 0;
16 }
(gdb) l
Line number 17 out of range; test.c has 16 lines.
p a
p p
p 'main'::a
p *p@3
(gdb) run
Starting program: /root/daizhh/test.exe
Breakpoint 1, main (argc=1, argv=0x7fffffffe508) at test.c:11
11 printf("%d\n", a);
(gdb) p a
$1 = 1
(gdb) p b
$2 = {1, 2, 3}
(gdb) n
1
13 p = b;
(gdb) c
Continuing.
Breakpoint 2, main (argc=1, argv=0x7fffffffe508) at test.c:14
14 printf("%d\n", p[0]);
(gdb) p p
$3 = (int *) 0x7fffffffe400
(gdb) p 'main'::a
$4 = 1
(gdb) p *p@3
$5 = {1, 2, 3}
set $index = 0
p p[$index]
(gdb) set $index = 0
(gdb) p p[$index]
$6 = 1
- x 按十六進位制格式顯示變數
- d 按十進位制格式顯示變數
- u 按十六進位制格式顯示無符號整型
- o 按八進位制格式顯示變數
- t 按二進位制格式顯示變數
- a 按十六進位制格式顯示變數
- c 按字元格式顯示變數
- f 按浮點數格式顯示變數
(gdb) p/x a(按十六進位制格式顯示變數)
(gdb) p/x a
$7 = 0x1
q