首页 > 编程语言 >gdb 调试技巧:定位程序卡死问题

gdb 调试技巧:定位程序卡死问题

时间:2023-04-18 19:23:42浏览次数:36  
标签:printf 程序 gdb pthread 卡死 NULL 调试

 

gdb 调试技巧:定位程序卡死问题

 

最近遇到一个程序卡死的问题,借助 gdb 轻松定位,供大家参考。

遇到程序卡死不退处,可能不知道卡死在什么地方,如果程序非常简单,也许 printf 大法就可以很快定位。但是对于大型程序,尤其是一些框架程序,printf 大法可能就力不从心了。

实际的程序很复杂,这里给出一个极简版,一个多线程程序:

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

void* pthread_run1()
{
    printf("=== thread 1\n");
    while(1)
    {
        sleep(1);
    }
    return NULL;
}

void* pthread_run2()
{
    printf("=== thread 2\n");
    while(1)
    {
        sleep(1);
        return NULL;
    }
    return NULL;
}


int main()
{

    pthread_t tid1;
    pthread_t tid2;

    pthread_create(&tid1, NULL, pthread_run1, NULL);
    pthread_create(&tid2, NULL, pthread_run2, NULL);

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

    return 0;
}

 

编译(gcc hello.c -g -pthread)后运行:

xxx:~/code/multithread$ ./a.out 
=== thread 1
=== thread 2

 

程序卡住不退处,当然我这里的例子使用 ctrl-c 信号可以让程序退出,而我实际的程序是这里会卡死。不过这不是重点,重点是怎么知道程序卡死(或卡住)在哪里呢?当然这个简单的例子,你直接 review 代码就能看出,或者简单加几个 printf 就能定位出卡死的位置。上面也说过这个是极简版,review 和 printf 很难发现问题。这个时候我们就可以借助 gdb 了。

首先,查看当前程序的进程号(pid),使用 ps 命令:ps aux | grep a.out,得到 pid 为 1801781。

xxx 1801781  0.0  0.0  84576   476 pts/1    Sl+  21:24   0:00 ./a.out

然后,启动 gdb,接着 attach 该 pid:

GNU gdb (Ubuntu 9.1-0ubuntu1) 9.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb) attach 1801781
Attaching to process 1801781
[New LWP 1801782]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
__pthread_clockjoin_ex (threadid=140508208416512, thread_return=0x0, clockid=<optimized out>, abstime=<optimized out>, block=<optimized out>) at pthread_join_common.c:145
145	pthread_join_common.c: No such file or directory.
(gdb) up
#1  0x0000564d11e93274 in main () at hello.c:38
38	    pthread_join(tid1, NULL);
(gdb)

可以看到程序卡在源码的 38 行。 卡住的原因是线程 join 的时候等不到线程函数返回。

注意事项:

  • 如果启动 gdb 后 attach pid 没有权限,比如信息如下,则可以使用 sudo gdb。
GNU gdb (Ubuntu 9.1-0ubuntu1) 9.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb) attach 1801781
Attaching to process 1801781
Could not attach to process.  If your uid matches the uid of the target
process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try
again as the root user.  For more details, see /etc/sysctl.d/10-ptrace.conf
ptrace: Operation not permitted.
(gdb)
  • 如果你的程序不是 -g 编译的,只会看到最底层代码位置,这个时候因为没有调试信息,使用 up 命令也无法显示源码。建议编译 debug 版本来定位,可以获取丰富的信息。

建议大家在调试过程中将 gdb 用起来,gdb 有很多功能值得探索!

 

标签:printf,程序,gdb,pthread,卡死,NULL,调试
From: https://www.cnblogs.com/lidabo/p/17330783.html

相关文章

  • stm32文件系统读写操作调试总结
    一问题最近使用到了文件系统的读写,中间遇到了一些问题值得深思。 二源码解析创建文件:FRESULTres;do{sprintf(filename,"/sensor_signal/sensor_%d.bin",file_num++);mprintf("filenameis:%s\n\r",filename);res=f_open(&file,fi......
  • 基于ads1299的可穿戴脑电信号采集之性能调试总结
    一前言问题背景:最近做项目,遇到了一个问题,就是采集的信号有噪声,在这里做了很多尝试。 二测试步骤A内部方波信号质量,通过测试发现内部方波信号质量特别好。这个说明了软件和存储这块,没啥问题的,还有干扰,那就是前端的硬件引入的干扰了。 B这个是空采的......
  • Java环境与Eclipse SDK安装涉及的环境变量调试,java环境配置
    资源包请自己下载。文本太大,我传到百度了。https://pan.baidu.com/s/1p6aFDOeXWULnK8STdQkwmw  这是地址资源地址小白师从高中老班长祯淮大哥,偷师于网页中的他人经验,因此,先说声谢谢他人的经验分享,为了记录学习过程,方便整理知识,做了以下学习分享。有错请大神指出。 这是我装好的......
  • Apifox 更新 | WebSocket 接口调试功能上线!
    Apifox 新版本上线啦!欢迎升级使用:界面右上角【设置】-> 【关于Apifox】->【检查更新】看看本次版本更新主要涵盖的重点内容,有没有你所关注的功能特性:支持WebSocketAPI;自动化测试功能升级;Web端新增部分功能快捷键;支持自定义设置版本更新及安装提醒。01支持WebSocketAPI最新......
  • Java-Day-10(Object 常用类 + JDK 源码 + 断点调试)
    Java-Day-10Object常用类equals方法==与equals==是一个比较运算符既可以判断基本类型,又可以判断引用类型如果判断基本类型,判断的是值是否相等如果判断引用类型,判断的就是地址是否相同,即判断是否是一个对象equals是Object类中的方法,只能判断引用类型默认......
  • vscode调试 vue
    1.配置vue.config.js加上devtool:'source-map'//开发环境可以加,生产环境,别人可以看到源代码,不完全不要加 2.添加launch.jsonvscode打开调试窗口,在下图箭头指向的位置点击打开配置文件launch.json:   3.配置远程调试1)浏览器快捷方式设置浏览器桌面快捷方式......
  • 【FPGA 仿真和调试脚本】常用系统任务
    一、显示任务$display和$write系统显示任务$display和$write在仿真测试中是最为常用的信息显示方式。$display和$write任务最主要的区别在于,$display在一次输出后会自动换行,而$write则不会,他们的其他用法格式基本类似。【语法结构】【任务名】(“【可选字符串】+【格式】”,【信......
  • 从零开始学习MySQL调试跟踪(2)
    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。GreatSQL是MySQL的国产分支版本,使用上与MySQL一致。作者:Yejinrong/叶金荣文章来源:GreatSQL社区投稿启用coredump制造一个coredump场景真实故障场景分析跟踪上一篇文档介绍了如何构建gdb跟踪调......
  • NumPy 秘籍中文第二版:七、性能分析和调试
    在本章中,我们将介绍以下秘籍:使用timeit进行性能分析使用IPython进行分析安装line_profiler使用line_profiler分析代码具有cProfile扩展名的性能分析代码使用IPython进行调试使用PuDB进行调试简介调试是从软件中查找和删除错误的行为。分析是指构建程序的概要文件,以便收集有关......
  • gdbusmessage.c
    /*GDBus-GLibD-BusLibrary**Copyright(C)2008-2010RedHat,Inc.**Thislibraryisfreesoftware;youcanredistributeitand/or*modifyitunderthetermsoftheGNULesserGeneralPublic*LicenseaspublishedbytheFreeSoftwareFounda......