首先通過命令
gdb freeswitch core.60954
進入gdb。
這里freeswitch 是產生coredump的可執行應用,core.60954是應用產生的coredump文件。
然后執行命令
bt
可以看到運行出錯的堆棧信息
(gdb) bt
#0 0x00007fd372e3344d in lua_remove () from /lib64/liblua-5.1.so
#1 0x00007fd3730635ef in docall (L=0x7fd39802dcc0, narg=<optimized out>, nresults=1, perror=1, fatal=0) at mod_lua.cpp:94
#2 0x00007fd373065d94 in LUA::Session::run_dtmf_callback (this=0x7fd3980569d0, input=0x7fd39001f9f0, itype=<optimized out>) at freeswitch_lua.cpp:332
#3 0x00007fd3be601241 in audio_bridge_thread (obj=obj@entry=0x7fd398181d20, thread=0x0) at src/switch_ivr_bridge.c:599
#4 0x00007fd3be6023c2 in audio_bridge_on_exchange_media (session=0x7fd398077058) at src/switch_ivr_bridge.c:856
#5 0x00007fd3be5925ca in switch_core_session_run (session=0x7fd398077058) at src/switch_core_state_machine.c:653
#6 0x00007fd3be58be5e in switch_core_session_thread (thread=<optimized out>, obj=0x7fd398077058) at src/switch_core_session.c:1648
#7 0x00007fd3be587b53 in switch_core_session_thread_pool_worker (thread=0x7fd398096310, obj=<optimized out>) at src/switch_core_session.c:1711
#8 0x00007fd3be842210 in dummy_worker (opaque=0x7fd398096310) at threadproc/unix/thread.c:151
#9 0x00007fd3bc653dc5 in start_thread () from /lib64/libpthread.so.0
#10 0x00007fd3bbd2bd0d in clone () from /lib64/libc.so.6
到這里還可以打印此時的各個變量信息,用法為
p file::variable
p function::variable
其中file和function分別是文件名及文件的全局變量。函數名及函數里面的變量。
比如打印下面函數:
static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
{
switch_ivr_bridge_data_t *data = obj;
int stream_id = 0, pre_b = 0, ans_a = 0, ans_b = 0, originator = 0;
switch_input_callback_function_t input_callback;
switch_core_session_message_t msg = { 0 };
void *user_data;
switch_channel_t *chan_a, *chan_b;
switch_frame_t *read_frame;
switch_core_session_t *session_a, *session_b;
里面的
session_a
的值:
p *audio_bridge_thread::session_a
*號表示指針的值,如果是普通結構體可以去掉。
為了輸出結果更好看點,可以執行
set print pretty on
然后執行結果如下:
(gdb) p *audio_bridge_thread::session_a
$5 = {
pool = 0x7fd398075048,
thread = 0x7fd398096310,
thread_id = 140546079377152,
endpoint_interface = 0xac6860,
id = 64,
flags = (SSF_WARN_TRANSCODE | SSF_THREAD_STARTED | SSF_THREAD_RUNNING | SSF_READ_TRANSCODE),
channel = 0x7fd398075130,
event_hooks = {
outgoing_channel = 0x0,
receive_message = 0x0,
receive_event = 0x0,
read_frame = 0x0,
video_read_frame = 0x0,
write_frame = 0x0,
video_write_frame = 0x0,
kill_channel = 0x0,
send_dtmf = 0x0,
recv_dtmf = 0x7fd398181778,
state_change = 0x0,
state_run = 0x0
},
read_codec = 0x7fd398088778,
real_read_codec = 0x7fd398088778,
write_codec = 0x7fd3980887d8,
real_write_codec = 0x0,
video_read_codec = 0x7fd39808d918,
video_write_codec = 0x7fd39808d978,
........
附着到一個pid為39657對應的進程
gdb attach 39657
設置某個文件里面你的斷點
break filename:linenum
break filename:func
例如: break switch_ivr_async.c:4530
常用gdb命令
gcc -g main.c //在目標文件加入源代碼的信息
gdb a.out
(gdb) start //開始調試
(gdb) n //一條一條執行
(gdb) step/s //執行下一條,如果函數進入函數
(gdb) backtrace/bt //查看函數調用棧幀
(gdb) info/i locals //查看當前棧幀局部變量
(gdb) frame/f //選擇棧幀,再查看局部變量
(gdb) print/p //打印變量的值
(gdb) finish //運行到當前函數返回
(gdb) set var sum=0 //修改變量值
(gdb) list/l 行號或函數名 //列出源碼
(gdb) display/undisplay sum //每次停下顯示變量的值/取消跟蹤
(gdb) break/b 行號或函數名 //設置斷點
(gdb) continue/c //連續運行
(gdb) info/i breakpoints //查看已經設置的斷點
(gdb) delete breakpoints 2 //刪除某個斷點
(gdb) disable/enable breakpoints 3 //禁用/啟用某個斷點
(gdb) break 9 if sum != 0 //滿足條件才激活斷點
(gdb) run/r //重新從程序開頭連續執行
(gdb) watch input[4] //設置觀察點
(gdb) info/i watchpoints //查看設置的觀察點
(gdb) x/7b input //打印存儲器內容,b--每個字節一組,7--7組
(gdb) disassemble //反匯編當前函數或指定函數
(gdb) si // 一條指令一條指令調試 而 s 是一行一行代碼
(gdb) info registers // 顯示所有寄存器的當前值
(gdb) x/20 $esp //查看內存中開始的20個數