一、GDB基礎?
1.?啟動調試
gdb ./your_program # 啟動調試
gdb --args ./prog arg1 # 帶參數啟動
gdb -p <pid> # 附加到正在運行的進程
?2.?斷點管理
b main # 在main函數設斷點
b file.c:20 # 在file.c第20行設斷點
b *0x4005a0 # 在內存地址設斷點
info breakpoints # 查看所有斷點
delete <num> # 刪除斷點
disable/enable <num> # 禁用/啟用斷點
3.?執行控制
run # 啟動程序
continue (c) # 繼續執行到下一個斷點
next (n) # 單步執行(跳過函數)
step (s) # 單步進入函數
finish # 執行完當前函數并返回
until <line> # 執行到指定行
?4.?查看變量和內存
print (p) x # 打印變量x
p *ptr@10 # 打印ptr指向的10個元素
p/x var # 十六進制格式打印
x/4xg 0x4000 # 查看內存:4個8字節十六進制值
info registers # 查看寄存器值
二、GDB進階?
1.?加載可執行程序和core dump文件
#include <stdio.h>int main(void) {int *p = NULL;printf("hello world\n");*p = 0;return 0;
}
例子程序訪問了一個空指針,所以程序會crash并產生core dump文件。用gdb調試core dump文件,通常用這個命令形式:
gdb path/to/the/executable path/to/the/coredump
然后gdb會顯示程序crash的位置。
2.?調試正在運行的進程
# 查找目標進程PID
ps aux | grep 程序名# 附加調試
gdb -p <PID>
(gdb) bt # 查看當前調用棧
(gdb) info threads # 查看所有線程
(gdb) thread <ID> # 切換線程
(gdb) frame <N> # 選擇棧幀
(gdb) p variable # 打印變量
三、其他問題?
1. 怎么debug,怎么看內存泄漏。
2. gdb 使用 -> 多線程程序切換到某線程棧幀 -> 如何查看寄存器值
# 在malloc/free處設斷點
(gdb) break malloc
(gdb) break free# 記錄所有內存分配
(gdb) set logging file mem.log
(gdb) set logging on# 運行后對比malloc/free調用次數
(gdb) info breakpoints
3. 怎么分析C++的core文件
啟用core dump生成:
# 臨時生效(當前會話)
ulimit -c unlimited # 解除大小限制
echo "/tmp/core.%e.%p" | sudo tee /proc/sys/kernel/core_pattern # 設置存儲路徑# 永久生效(需root)
echo "ulimit -c unlimited" >> /etc/profile
echo "/tmp/core.%e.%p" > /etc/sysctl.d/core.conf
sysctl -p /etc/sysctl.d/core.conf
g++ -g -O0 -rdynamic -o program program.cpp # 必須包含-g選項
?加載core文件
gdb ./program /tmp/core.1234 # program是崩潰的可執行文件
查看崩潰位置:
(gdb) bt full # 顯示完整調用棧(包含局部變量)
(gdb) frame N # 切換到指定棧幀(N為bt顯示的編號)
(gdb) list # 顯示崩潰點附近的源代碼
?
4. GDB有哪些命令
1.?啟動與退出
命令 | 說明 |
---|
gdb ./program | 啟動GDB調試程序 |
run [args] | 運行程序(可帶參數) |
quit | 退出GDB |
2.?斷點管理
命令 | 說明 |
---|
break main | 在main函數設斷點 |
break file.cpp:20 | 在指定文件的第20行設斷點 |
break *0x4005a0 | 在內存地址設斷點 |
info breakpoints | 查看所有斷點 |
delete 2 | 刪除編號為2的斷點 |
disable/enable 1 | 禁用/啟用編號1的斷點 |
3.?執行控制
命令 | 說明 |
---|
next ?(n) | 單步執行(不進入函數) |
step ?(s) | 單步進入函數 |
continue ?(c) | 繼續執行到下一個斷點 |
finish | 執行完當前函數并暫停 |
until 30 | 運行到第30行 |
4. 變量與內存
命令 | 說明 |
---|
print x | 打印變量x的值 |
print *ptr@10 | 打印指針ptr指向的10個元素 |
x/4xw 0x4000 | 以16進制顯示內存(4個word) |
info registers | 查看所有寄存器值 |
info locals | 顯示當前棧幀的局部變量 |
5.?調用棧與線程
命令 | 說明 |
---|
backtrace ?(bt) | 查看調用棧 |
frame 2 | 切換到調用棧第2幀 |
info threads | 查看所有線程 |
thread 3 | 切換到線程3 |
?6.?多進程/線程調試
命令 | 說明 |
---|
set follow-fork-mode child | 調試子進程 |
set scheduler-locking on | 鎖定當前線程 |
thread apply all bt | 打印所有線程的調用棧 |
7. 實用輔助命令
命令 | 說明 |
---|
set logging on | 記錄調試輸出到文件 |
define hook-run | 定義啟動時自動執行的命令 |
shell ls | 執行shell命令 |
help [command] | 查看命令幫助 |
?
5. gcc和g++的區別
特性 | gcc ?(GNU C Compiler) | g++ ?(GNU C++ Compiler) |
---|
默認語言標準 | C11 (可通過?-std= ?指定其他版本) | C++17 (可通過?-std= ?指定其他版本) |
鏈接階段行為 | 默認不鏈接 C++ 標準庫 | 自動鏈接?libstdc++ ?(C++ 標準庫) |
文件擴展名處理 | 將?.c ?文件視為 C 代碼 | 將?.cpp /.cxx ?視為 C++,.c ?仍視為 C |
6. Linux下程序有問題,如何調試?(答GDB打開,打上Breakpoint進行調試)