linux下使用gdb除錯崩潰丶死鎖例項
阿新 • • 發佈:2019-01-01
gdb是linux下一款功能強大的除錯工具,windows下對應的有windbg,下面舉例說明常見程式錯誤解決方法
1.gdb啟動
要想使用gdb除錯,編譯時指定-g選項加入除錯資訊,gdb可以啟動執行檔案,attach正在執行程式,除錯程式崩潰產生core檔案
啟動gdb後輸入run執行,continue繼續,quiet退出,下面是除錯一段崩潰和死鎖的原始碼
#include <pthread.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <string.h> pthread_mutex_t mutex; int count = 0; void print_pid_tid() { pid_t pid; pthread_t tid; pid = getpid(); tid = pthread_self(); printf("pid %u tid %u (0x%x)\n", (unsigned int)pid, (unsigned int)tid, (unsigned int)tid); } void callback_func() { pthread_mutex_lock(&mutex); printf("count:%d\n",count); } void *thread_func1(void *arg) { while (1) { int n = *((int *)arg); pthread_mutex_lock(&mutex); print_pid_tid(); count += 2; for (int i=0 ; i < 5; ++i ) { count += n; } callback_func(); pthread_mutex_unlock(&mutex); sleep(1); } return 0; } void *thread_func2(void *arg) { while (1) { pthread_mutex_lock(&mutex); printf("thread_func2 run\n"); pthread_mutex_unlock(&mutex); sleep(1); } return 0; } void *thread_func3(void *arg) { while(1) { char *str = NULL; //strcpy(str,"hello world"); sleep(1); } return 0; } int main(void) { pthread_t ntid; int count = 10; pthread_mutex_init(&mutex, NULL); int err = pthread_create(&ntid, NULL, thread_func1, &count); if ( 0 != err ) { printf("pthread_create1:%s\n", strerror(err)); } err = pthread_create(&ntid, NULL, thread_func2, &count); if ( 0 != err ) { printf("pthread_create2:%s\n", strerror(err)); } err = pthread_create(&ntid, NULL, thread_func3, &count); if ( 0 != err ) { printf("pthread_create3:%s\n", strerror(err)); } getchar(); int **ret = NULL; pthread_join(ntid, (void**)ret); printf("pthread_join:%p\n", *ret); pthread_mutex_destroy(&mutex); return 0; }
2.除錯崩潰
gdb繫結程式執行崩潰時,gdb會停留在程式最後執行棧位置,一般輸入bt檢視堆疊,frame n切換棧幀,print列印是否空指標導致崩潰,where檢視對於原始碼位置或者list列出原始碼,崩潰一般有空指標,陣列越界,記憶體非法訪問
3.除錯死鎖
程式出現死鎖時會是卡死狀態,如果gdb繫結執行使用ctrl+c中斷程式,輸入info threads檢視所有執行緒,使用thread n切換執行緒,線上程中輸入bt檢視執行緒堆疊,定位程式停留位置,一般比較多個執行緒鎖或者是否有死迴圈
4.斷點除錯
設定斷點,如b main.cpp:31,執行到斷點後next單步,step進入函式,continue繼續執行