1. 程式人生 > >linux下使用gdb除錯崩潰丶死鎖例項

linux下使用gdb除錯崩潰丶死鎖例項

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繼續執行