使用gdb調試多進程多線程程序

其實,我們在VS編譯器中用的調試工具是集成的軟件,但是在Linux中有特定的工具GDB,其實這是一個很強的工具,我其實用的不是很6,其實這個真的強,希望大家和我一樣努力的來學習使用GDB調試;在這先推薦一個大神陳皓,博客已經不更新了但是還是有很多內容比如GDB調試

其實在陳皓大神的這個系列中,我們可以get很多的技能;

GDB調試多進程

在GDB調試中,默認的調試是父進程,當我們在程序中fork出一個子進程後,就不能達到調試子進程的目的,因此,GDB中肯定就會設置調試子進程的

    set follow-fork-mode child/parent

上述的命令就是在gdb中調試的時候可以選擇gdb調試的是父進程還是子進程;

    set follow-fork-mode child     //GDB調試子進程
    set follow-fork-mode parent    //GDB調試父進程

我們先展示一下我們的測試代碼:

//test.c

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

int main()
{
    pid_t id = fork();
    if(id == 0)//child
    {
        int a = 0, i;
        for(i = 0; i < 5; i++)
        {
            a += i;
        }
    }
    else
    {
        int b = 1, j;
        for(j = 1; j < 5; ++j)
        {
            b *= j;
        }
    }
    return 0;
}

在GDB調試之前,我們隊目標文件編譯的時候必須在 編譯後面加 -g才能正確的進入GDB的調試:
這裏寫圖片描述
在上圖中,我們可以看到我什麼也沒有添加的調試後,直接進入的父進程,跳過了子進程;所以:GDB默認調試的父進程;
這裏寫圖片描述
這裏寫圖片描述
結合上圖,我們可以看到的是,在子程序調試完後,直接就到24行退出;
其實在我們這個GDB調試中,父進程也可以用 set follow-fork-mode parent,也可以直接調試,畢竟默認的也是調試父進程;
在GDB調試多進程中還有一個調試的命令: set detach-on-fork on/off;
兩個命令的聯繫如下:

follow-fork-mode detach-on-fork 說明
parent on GDB默認的調試方式;值調試主進程
child on 只調試子進程
parent off 同時調試兩個進程,gdb跟主進程,子進程block在fork位置
child off 同時調試兩個進程,gdb跟子進程,主進程block在fork位置

所以,我們可以用上述命令調試多進程的程序:
這裏寫圖片描述
我們在看到所有運行的進程後,可以選擇調試那個進程:
這裏寫圖片描述

GDB調試多線程

//thread.c

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>

void* thread1(void* arg)
{
    while(1)
    {
        sleep(5);
        printf("Hello\n");
    }
}

void* thread2(void* arg)
{
    while(1)
    {
        sleep(5);
        printf("world\n");
    }
}

int main()
{
    pthread_t tid1;
    pthread_t tid2;

    pthread_create(&tid1, NULL, thread1, NULL);
    pthread_create(&tid2, NULL, thread2, NULL);

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    return 0;
}

線程創建提醒

在GNU/Linux上,如果gdb檢測一個新的線程,會給出如下通知:
這裏寫圖片描述
查詢已經創建的線程
這裏寫圖片描述
線程切換

thread threadno可以切換到指定的線程,threadno就是上面gdb分配的線程id號
這裏寫圖片描述
鎖定一個線程

默認情況下,gdb不鎖定任何線程:在切換到線程2中後,打印的不只是線程2中的數據,也還有線程3中的內容:
這裏寫圖片描述
可以使用set scheduler-locking on來鎖定只有當前線程的操作:不會執行其他線程的結果
這裏寫圖片描述

scheduler-locking on off step
調試某個線程是其他線程是否執行 鎖定其他線程,只有當前線程執行 不鎖定任何線程,默認值 在單步時,只有被調試線程運行

線程調試的其他命令:

thread apply ID command:讓ID線程執行命令command;
thread apply all command:讓所有線程執行命令command;
這裏寫圖片描述

發佈了63 篇原創文章 · 獲贊 50 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章