GDB:调试死锁

一、代码

        2个线程,加锁后轮流输出数据,其中1个线程,误将pthread_mutex_unlock(),写成pthread_mutex_lock()代码如下:

 

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

int g_tickets = 100;
pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;

void* thread_proc1(void* arg)
{
        while (1)
        {
                pthread_mutex_lock(&g_mutex);
                if (g_tickets > 0)
                        printf("thread 1 sell tickets:%d\n", g_tickets--);
                else
                {
                        //pthread_mutex_unlock(&g_mutex);
                        pthread_mutex_lock(&g_mutex);
                        break;
                }
                //pthread_mutex_unlock(&g_mutex);
                pthread_mutex_lock(&g_mutex);
        }

        return (void*)1;
}

void* thread_proc2(void* arg)
{
        while (1)
        {
                pthread_mutex_lock(&g_mutex);
                if (g_tickets > 0)
                        printf("thread 2 sell tickets:%d\n", g_tickets--);
                else
                {
                        pthread_mutex_unlock(&g_mutex);
                        break;
                }
                pthread_mutex_unlock(&g_mutex);
        }

        pthread_exit((void*)2);
}

int main(int argc, char*argv[])
{
        pthread_t tid1, tid2;
        void *ret1, *ret2;

        pthread_create(&tid1, NULL, thread_proc1, NULL);
        pthread_create(&tid2, NULL, thread_proc2, NULL);

        pthread_join(tid1, &ret1);
        pthread_join(tid2, &ret2);

        printf("ret1:%d\n",(int)ret1);
        printf("ret2:%d\n",(int)ret2);

        return 0;
}


二、编译运行

 

2.1 编译

        gcc -g test.c -lpthread -o test

2.2 运行

        ./test 

2.3 输出结果

三、调试 -- 方法1

3.1 查看 test进程号

        ps aux|grep test

3.2 查看进程中的所有线程

        pstree -p 13006

3.3 gdb调试定位bug位置

        gdb

        attach 进程号

        bt 【thread apply all bt】

如下图:

        thread apply all bt

四、调试 --  方法2

4.1 查看 test进程号

        ps -e|grep test

4.2 gdb调试定位bug位置

        gdb test 进程号   启动gdb attach 进程

        info threads         显示所有线程信息

        thread 2               调到第2个线程

        bt                           查看第2个线程的堆栈,即可可以看到线程死锁的地方

 

 

参考资料:

      使用gdb调试死锁线程:http://blog.csdn.net/atinybirdinit/article/details/41550149

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《debugging with gdb》是一本关于使用GDB进行调试的指南。GDB(GNU调试器)是一个强大的调试工具,可以用于调试各种编程语言,如C、C++、Fortran等。 这本书详细介绍了GDB的安装和配置,并提供了许多示例来说明如何使用它来调试程序。它从基本的调试命令开始,如设置断点、单步执行、查看变量的值等。然后,它介绍了更高级的调试功能,如条件断点、观察点、跟踪函数调用等。 书中还介绍了如何使用GDB调试多线程程序和动态库。它解释了如何设置线程断点、查看线程状态和跟踪线程的执行路径。此外,它还介绍了如何对动态链接库进行调试,包括加载和卸载库、查看库中的符号和调用库中的函数等。 此外,《debugging with gdb》还介绍了如何使用GDB进行内存调试。它涵盖了诸如检测内存泄漏、跟踪指针问题和查找内存错误等主题。通过这本书,读者可以学习如何使用GDB来诊断和解决各种程序错误和问题。 总之,《debugging with gdb》是一本全面而详细的关于使用GDB进行调试的指南。无论是有经验的开发人员还是初学者,都可以从中学习到如何使用GDB来快速定位和解决程序中的错误。 ### 回答2: GDB是一个调试器,用于帮助开发者在程序中找出错误并进行调试。它提供了许多功能和命令,可以让开发者在程序运行过程中获取各种有用的信息。 在使用GDB进行调试之前,首先需要将程序编译成可调试的二进制文件。可以使用编译器的参数“-g”来生成包含调试信息的可执行文件。编译完成后,可以通过终端命令"gdb <可执行文件名>"启动GDB,并载入要调试的程序。 一旦进入GDB调试界面,可以使用各种命令来控制程序的执行。例如,可以使用"break <函数名>"命令在特定的函数内设置断点,当程序执行到该函数时会触发断点,并暂停程序的执行。可以使用"run"命令来运行程序,当程序遇到断点时会暂停,并在终端显示相关的调试信息。 一旦程序暂停在断点处,就可以使用GDB提供的许多命令来检查程序状态和寻找错误。例如,可以使用"print <变量名>"命令来打印特定变量的值,以确定其是否符合预期。还可以使用"step"命令来逐行执行程序,并跟踪程序的执行流程,以查找错误所在。 在调试过程中,还可以使用其他命令来查看函数调用栈,设置条件断点,监视特定变量的值等。通过这些命令的使用,可以逐步分析程序的执行过程,找出其中的问题,并进行修复。 在调试完成后,可以使用"quit"命令退出GDB调试界面。调试信息和步骤可以记录下来并与其他开发者共享,以便更好地协作解决问题。 总之,GDB是一个功能强大的调试器,它可以帮助开发者定位和修复程序中的错误。通过使用GDB,开发者可以更加高效地进行程序调试,提高开发效率。 ### 回答3: 《debugging with gdb》是一本介绍使用GDB进行调试的书籍。GDB是GNU工具链中的一个强大的调试工具,用于分析和修复程序中的错误。 该书详细介绍了GDB的各种功能和用法,并通过实例演示了如何利用GDB进行程序调试。它提供了许多实用技巧和建议,帮助读者快速定位和解决程序中的bug。 书中首先介绍了GDB的基本用法,包括启动程序、设置断点、执行程序、查看变量值等。接着,它详细阐述了GDB的高级功能,例如条件断点、观察点、内存调试等。 此外,书中还介绍了GDB调试多线程程序、动态链接程序和嵌入式程序的方法。针对不同的调试需求,它还介绍了GDB的执行控制、堆栈跟踪和源代码级别的调试等高级特性。 《debugging with gdb》还提供了一些常见问题的解决方案,如内存泄漏、数组越界、死锁等。它还解释了一些常见错误的原因和调试技巧,帮助读者更好地理解和定位程序中的问题。 通过阅读《debugging with gdb》,读者可以更好地理解和掌握GDB的使用方法,提高程序调试的效率和准确性。无论是新手还是有经验的程序员,都可以从中受益,提升自己的调试能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值