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

歡迎訪問 生活随笔!

生活随笔

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

linux

Linux gdb多进程、多线程调试

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

目錄

常用命令

堆棧相關命令

更為詳細的斷點調試

gdb多進程調試

gdb多線程調試


前言

gdb 是?linux?平臺下進行程序調試的最常用的工具。簡單的程序調試就是加斷點,然后一步一步讓程序運行,直到找到 bug 。一般的程序調試起來比較簡單,但是在多進程或多線程情況下調試起來就比較麻煩。

若 test.c 是你想要調試的程序,那么在編譯時需要加 -g,即 gcc test.c -g -o test。完成編譯后使用命令:gdb test。

?

?

常用命令

命令

命令縮寫及例子

說明

list + n

l + n

顯示源碼第n行前后的代碼,顯示范圍有限。

break + n

b + n

在第n行設置斷點

info

i

描述程序狀態

run

r

開始運行程序

display

disp

跟蹤查看某個變量的值

info display

?

用于顯示當前所有要顯示值的表達式的情況

undisplay

undisplay + 編號

用于結束某個表達式值的顯示

step

s

執行下一條語句,如果該語句為函數調用,則進入函數執行其中的第一條語句

next

n

執行下一條語句,如果該語句為函數調用,不會進入函數內部執行

print

p

打印內部變量的值

continue

c

繼續運行,直到遇到下一個斷點

start

st

開始執行程序,在main函數的第一條語句前面停下來

kill

k

終止正在調試的程序

quit

q

退出gdb

set args

set args arg1 arg2

設置運行參數

show args

show args

查看運行參數

finish

finish

一直運行到函數返回并打印函數返回時的堆棧地址和返回值及參數值等信息

?


堆棧相關命令

命令

例子

說明

backtrace

bt

查看堆棧信息

frame

f 1

查看棧幀

info reg

info reg/ i r

查看寄存器使用情況

info stack

info stack

查看堆棧使用情況

up/down

up/down

跳到上一層/下一層函數

這里以一個簡單的程序為例,進行調試。

#include <bits/stdc++.h> using namespace std; #define M 5int fact(int n) //線性遞歸 {if (n < 0)return 0;else if(n == 0 || n == 1)return 1;elsereturn n * fact(n - 1); }int facttail(int n, int a) //尾遞歸 {if (n < 0)return 0;else if (n == 0)return 1;else if (n == 1)return a;elsereturn facttail(n - 1, n * a); }int facttail1(int n, int a) {while(n > 0){a = n * a;n--;}return a; }int main() {//printf("%p", facttail);int a = fact(M);int b = facttail(M, 1);cout << "A:" << a <<endl;cout << "B:" << b <<endl; }

?

(1)開始 gdb 調試

?

(2)設置斷點

?

(3)查看棧的使用情況

?

?

更為詳細的斷點調試

命令

例子

說明

break + 設置斷點的行號

break n

在n行處設置斷點

tbreak + 行號或函數名

tbreak n/func

設置臨時斷點,到達后被自動刪除

break + filename + 行號

break main.c:10

用于在指定文件對應行設置斷點

break + <0x...>

break 0x3400a

用于在內存某一位置處暫停

break + 行號 + if + 條件

break 10 if i==3

用于設置條件斷點,在循環中使用非常方便

info breakpoints/watchpoints [n]

info break

n表示斷點編號,查看斷點/觀察點的情況

clear + 要清除的斷點行號

clear 10

用于清除對應行的斷點,要給出斷點的行號,清除時GDB會給出提示

delete + 要清除的斷點編號

delete 3

用于清除斷點和自動顯示的表達式的命令,要給出斷點的編號,清除時GDB不會給出任何提示

disable/enable + 斷點編號

disable 3

讓所設斷點暫時失效/使能,如果要讓多個編號處的斷點失效/使能,可將編號之間用空格隔開

awatch/watch + 變量

awatch/watch i

設置一個觀察點,當變量被讀出或寫入時程序被暫停

rwatch + 變量

rwatch i

設置一個觀察點,當變量被讀出時,程序被暫停

catch

?

設置捕捉點來補捉程序運行時的一些事件。如:載入共享庫(動態鏈接庫)或是C++的異常

tcatch

?

只設置一次捕捉點,當程序停住以后,應點被自動刪除


?

gdb多進程調試

命令

例子

說明

set follow-fork-mode?[parent|child]

?

?

set follow-fork-mode?parent or child

設置調試器的模式mode參數可以是

parent fork之后調試原進程,子進程不受影響,這是缺省的方式

child fork之后調試新的進程,父進程不受影響。

?

show?follow-fork-mode

show follow-fork-mode

顯示當前調試器的模式

set detach-on-fork [on|off]

?

set detach-on-fork on or off

設置gdb在fork之后是否detach進程中的其中一個,或者繼續保留控制這兩個進程?

on子進程(或者父進程,依賴于follow-fork-mode的值)會detach然后獨立運行,這是缺省的mode

off兩個進程都受gdb控制,一個進程(子進程或父進程,依賴于follow-fork-mode)被調試,另外一個進程被掛起

info?inferiors

info?inferiors

顯示所有進程

inferiors processid

inferiors 2

切換進程

detach inferiors processid

detach inferiors processid

detach 一個由指定的進程,然后從fork 列表里刪除。這個進程會被允許繼續獨立運行。

kill?inferiors? processid

kill inferiors? processid

殺死一個由指定的進程,然后從fork 列表里刪除。

catch fork

catch fork

讓程序在fork,vfork或者exec調用的時候中斷

調試多進程時,需要設置?detach-on-fork?的值,默認值為?on設置為?off?的含義:一個進程被調試,另外一個進程被掛起,這樣就可以交替的調試進程。follow-fork-mode?默認值為?parent,即默認調試父進程。調試代碼:

#include <stdio.h> #include <unistd.h> #include <stdlib.h>int main() {int num = 0;pid_t pid = fork();if(pid == 0) //子進程{while(1){num++;printf("child:pid:[%d] num:[%d]\n", getpid(), num);sleep(2);}}else{while(1){num = num + 2;printf("parent:pid:[%d] num:[%d]\n", getpid(), num);sleep(2);}}return 0; }

?

(1)?查看系統默認的 follow-fork-mode 和 detach-on-fork 設置follow-fork-mode 和 detach-on-fork

show follow-fork-mode show detach-on-fork set follow-fork-mode [parent|child] ?? set detach-on-fork [on|off]

?

(2) 設置斷點并查看斷點信息

?

(3) 運行程序并使用?info inferiors 命令 (顯示GDB調試的所有進程,其中帶有*的進程是正在調試的進程)

?

(4) 使用 inferior + [編號]?切換進程,對子進程進行調試

?

(5) 繼續運行程序,觀察子進程的輸出

?

(6) 中斷子進程運行后,開始逐步調試

?

(7) 再次切換回父進程完成調試

?

?

gdb多線程調試

命令

例子

說明

info threads

info threads

查詢線程信息

thread + 線程號

thread 2

切換線程

thread apply [threadno] [all] + 命令

thread apply [threadno] [all] bt

線程根據相應的命令完成操作

set print thread-events

set print thread-events

控制線程開始和結束時的打印信息

show print thread-events

show print thread-events

顯示線程打印信息的開關狀態

調試代碼:

#include <stdlib.h> #include <stdio.h> #include <pthread.h> #include <errno.h> #include <unistd.h>/*全局變量*/ int sum = 0; /*互斥量 */ pthread_mutex_t mutex; /*聲明線程運行服務程序*/ void* pthread_function1 (void*); void* pthread_function2 (void*);int main (void) {/*線程的標識符*/pthread_t pt_1 = 0;pthread_t pt_2 = 0;int ret = 0;/*互斥初始化*/pthread_mutex_init (&mutex, NULL);/*分別創建線程1、2*/ret = pthread_create( &pt_1, //線程標識符指針NULL, //默認屬性pthread_function1, //運行函數NULL); //無參數if (ret != 0){perror ("pthread_1_create");}ret = pthread_create( &pt_2, //線程標識符指針NULL, //默認屬性pthread_function2, //運行函數NULL); //無參數if (ret != 0){perror ("pthread_2_create");}/*等待線程1、2的結束*/pthread_join (pt_1, NULL);pthread_join (pt_2, NULL);printf ("main programme exit!\n");return 0; }/*線程1的服務程序*/ void* pthread_function1 (void*a) {int i = 0;printf ("This is pthread_1!\n");for( i=0; i<3; i++ ){pthread_mutex_lock(&mutex); /*獲取互斥鎖*//*臨界資源*/sum++;printf ("Thread_1 add one to num:%d\n",sum);pthread_mutex_unlock(&mutex); /*釋放互斥鎖*//*注意,這里以防線程的搶占,以造成一個線程在另一個線程sleep時多次訪問互斥資源,所以sleep要在得到互斥鎖后調用*/sleep (1);}pthread_exit ( NULL ); }/*線程2的服務程序*/ void* pthread_function2 (void*a) {int i = 0;printf ("This is pthread_2!\n");for( i=0; i<5; i++ ){pthread_mutex_lock(&mutex); /*獲取互斥鎖*//*臨界資源*/sum++;printf ("Thread_2 add one to num:%d\n",sum);pthread_mutex_unlock(&mutex); /*釋放互斥鎖*//*注意,這里以防線程的搶占,以造成一個線程在另一個線程sleep時多次訪問互斥資源,所以sleep要在得到互斥鎖后調用*/sleep (1);}pthread_exit ( NULL ); }

?

(1) 設置斷點并查看信息

?

(2) 運行程序,這里可以不設第一個斷點

?

(3) 兩個線程交替運行,觀察不同線程的輸出結果

?

(4) 使用 info threads 查看線程信息,使用 thread +?[編號] 切換線程

?

(5) 使用 thread apply + [編號] + 命令?

?

鎖定其他線程,只讓當前線程運行

(1) 設置?set scheduler-locking on

?

(2)? 觀察線程 1 運行的情況并完成調試


其他命令

(1) thread apply ID1 ID2 IDN command: 讓線程編號是ID1,ID2…等等的線程都執行command命令。

(2) thread apply all command:所有線程都執行command命令。

(3)?set scheduler-locking off|on|step: 在調試某一個線程時,其他線程是否執行。在使用step或continue命令調試當前被調試線程的時候,其他線程也是同時執行的,如果我們只想要被調試的線程執行,而其他線程停止等待,那就要鎖定要調試的線程,只讓他運行。

? ? ? ? off:不鎖定任何線程,默認值。

? ? ? ? on:鎖定其他線程,只有當前線程執行。

? ? ? ? step:在step(單步)時,只有被調試線程運行。

(4)?set non-stop on/off當調試一個線程時,其他線程是否運行。

(5) set pagination on/off: 在使用backtrace時,在分頁時是否停止。

(6) set target-async on/ff: 同步和異步。同步,gdb在輸出提示符之前等待程序報告一些線程已經終止的信息。而異步的則是直接返回。

(7) show scheduler-locking: 查看當前鎖定線程的模式

?

參考:

https://blog.csdn.net/snow_5288/article/details/72982594

https://www.cnblogs.com/euphie/p/9781482.html

總結

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

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