日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

[Linux]gdb调试多进程多线程例程

發布時間:2023/11/30 linux 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Linux]gdb调试多进程多线程例程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

gdb相信學linux的同學已經比較熟悉了吧,它是linux下代碼調試工具。我們在寫c語言,c++的代碼時經常會用到,它有一些常用的調試命令:

run(r):運行程序,如果有斷點在下一個斷點處停止
start:開始執行程序,停在main函數第一條語句前
list(l):列出源碼,接著上次的位置向下列,每次列10行
list+行號:列出第幾行附近的10行源碼
list+函數名:列出某個函數名附近10行源碼
print(p):顯示變量或表達式值
where:哪里出錯
whatis:查看變量的類型
info(i):查看當前棧幀局部變量的值
backtrace(bt):查看各級函數調用及參數
frame(f):幀編號,選擇棧幀
break:設置斷點
break 行號
break 函數名
break 文件名:行號
break 文件名:函數名
delete 1-3: 刪除1到3斷點
info break:顯示斷點信息
set variable var = value: 修改變量的值
continue(c): 從斷點后繼續執行
finish:運行到當前函數返回為止,然后停下來
return [value]:停止執行當前函數,將value返回給調用者;
step(s):執行下一步,step將進入函數,執行函數內每條語句;
next(n):執行下一個語句,不進入函數;
enter鍵:重復執行最后一條命令;

在我們學過信號之后,我又遇到一個問題就是關于core dumped的問題。我們舉個栗子說明一下吧~

#include<stdio.h>int main() {int a = 10;a/=0;return 0; }

我們看上面的這段代碼,在代碼編譯的角度來看,顯然它的除數為0了,會出錯。那是一個什么樣的錯呢。

運行結果:

出現了core dumped,這里core dumped稱為核心轉儲。當一個進程由于發生異常終止時,可以選擇把用戶空間內存儲的數據全部保存到磁盤上,文件名通常為core,因此稱為core dump。一般情況下,異常終止是因為代碼有bug,如非法訪問內存導致的段錯誤,剛剛的錯誤就屬于段錯誤,浮點數異常。事后可以用調試器檢查core文件來查清錯誤原因,這又被稱為事后調試。默認是不允許產生core?文件的,因為core文件中可能包含用戶密碼等敏感信息,不安全。在開發調試階段可以用ulimit命令改變這個限制,允許產生core文件。

比如上述程序,我們也生成了一個core文件。

這里需要注意的是,有些同學可能說為什么自己的代碼運行后生成不了core文件,原因是:你使用命令ulimit -a檢測一下你的core文件允許的大小。

上邊的core文件顯示的是0.說明你不能生成core文件,這里需要改一下core文件的大小,我們改成1024。使用命令ulimit -c 1024

這時,就可以生成core文件了。

下面我們來使用gdb來調試一下:

gdb調試多進程程序

#include<stdio.h> #include<unistd.h> #include<stdlib.h>int main() {pid_t id = fork();int i = 0;if(id == 0){while(1){printf("I am child! i = %d\n",i++);sleep(1);}}else{while(1){printf("hello world!I am parent! i = %d\n",i);sleep(1);}}return 0; }

我們介紹一些在多進程中新增的一些調試信息:

show follow-fork-mode:查看當前的fork進程,默認為父進程,如果想設置為子進程,則只需命令:set follow-fork-mode child即可

show detach-on-fork:顯示當前調試哪個進程。默認為on,只調試父子進程中的一個。如果為off,則表示調試父子兩個進程。set detach-on-fork off來設置。

info inferiors:顯示gdb調試的所有進程。inferior [進程編號]:可以切換到特定的inferiors進行調試。其中*代表正在調試的進程。

maint info program-spaces:顯示當前gdb管理的地址空間數目。

detach inferior [進程編號]:detach掉某一進程的編號,此時進程Description部分為NULL

kill inferior [進程編號]:殺死當前的fork。比如當前為父進程,則運行時只剩下子進程,當你下次運行的時候會恢復。當前進程為null,且指向kill的進程。

remove-inferior [進程編號]:刪除某一個inferior。如果該inferior正在運行,則不能刪除,因此刪除之前必須先killdetach掉。

show schedule-multiple:默認為on。顯示所有的執行狀態的情況。為on表示所有的inferior都可以執行。為off只是當前的inferior執行

set print inferior-event on/off:用來打開和關閉inferior狀態的提示信息

gdb調試多線程

#include<stdio.h> #include<pthread.h> #include<semaphore.h>#define SIZE 64 int ring[SIZE]; sem_t blank_sem,data_sem; void *consume(void* arg) {int i = 0;while(1){sem_wait(&data_sem);int data = ring[i++];sem_post(&blank_sem);i %= SIZE;printf("consume is %d\n",data);sleep(3);} }void *product(void *arg) {int data = 0;int i = 0;while(1){sem_wait(&blank_sem);ring[i++] = data;sem_post(&data_sem);i %= SIZE;printf("product is : %d\n",data++);// sleep(1);} }int main() {sem_init(&blank_sem,0,SIZE);sem_init(&data_sem,0,0);pthread_t c,p;pthread_create(&c,NULL,consume,NULL);pthread_create(&p,NULL,product,NULL);pthread_join(c,NULL);pthread_join(p,NULL);sem_destroy(&blank_sem);sem_destroy(&data_sem);return 0; }

thread apply ID command :讓ID線程執行命令command thread apply all command :讓所有線程執行命令command info threads:顯示當前可調試的所有線程,gdb為每一個線程分配一個ID號。*表示正在調試的線程。thread [線程ID]:切換到當前要調試的線程ID。

總結

以上是生活随笔為你收集整理的[Linux]gdb调试多进程多线程例程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。