gdb 调试多线程

多线程程序

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

void* thread_entry_funcA(void* arg){
    int i = 0;
    for(; i < 10; i++){
        printf("[thread_entry_funcA]: %d\n", i);
        sleep(1);
    }
    return NULL;
}

void* thread_entry_funcB(void* arg){
    int i = 0;
    for(; i < 10; i++){
        printf("[thread_entry_funcB]: %d\n", i);
        sleep(1);
    }
    return NULL;
}

int main(){
    pthread_t tidA, tidB;

    int ret = pthread_create(&tidA, NULL, thread_entry_funcA, NULL);
    if(ret < 0){
        perror("pthread_create");
        return 0;
    }

    ret = pthread_create(&tidB, NULL, thread_entry_funcB, NULL);
    if(ret < 0){
        perror("pthread_create");
        return 0;
    }

    pthread_join(tidA, NULL);
    pthread_join(tidB, NULL);
    return 0;
}

编译

gcc thread_gdb.c -o thread_gdb -lpthread -g

pstack命令 观察多线程

查看多线程信息

(gdb) info threads

切换线程

t [线程ID]

image-20240520213157159

切换到每一层堆栈

查看调用堆栈

打印堆栈信息

bt #查看调用堆栈

切换堆栈

f 0 # 切换到0号堆栈
image-20240520213456485

这时(gdb) n会让所有线程继续运行。我只想让一个线程继续运行,使用调度器锁模式

调度器锁模式

调试时除了当前线程在运行,想要规定其他线程的运行情况, 可以使用**set scheduler-locking [mode]**命令来进行设置

  1. set scheduler-locking off 不锁定任何线程,所有线程都可以继续执行。

  2. set scheduler-locking on 只有当前线程可以执行,其他线程暂停运行。

  3. set scheduler-locking step

    • 当单步执行某一线程时,保证在调试过程中当前线程不会发生切换(B线程在调试,A线程也会运行,但是不会A运行就会切换到A)。其他线程也会随着被调试线程的单步执行而执行。
    • 但如果该模式下执行 continue、until、finish 命令,则其它线程也会执行,并且如果某一线程执行过程遇到断点,则 GDB 调试器会将该线程作为当前线程。

    必须在线程创建之后,在一开始设置是不成功的

show scheduler-locking