文档章节

运行时调试-关于死循环

a
 alex_wei
发布于 2013/07/01 17:43
字数 626
阅读 584
收藏 0
对于正在运行的程序,使用gdb attach功能进行运行时调试(启动gdb后使用attach <PID>命令或在启动gdb时使用-p <PID>参数)。
以下是一段故意构造的简单死循环程序:
#include <stdio.h>
#include <unistd.h>
int main()
{
    int i;
    for (i = 0; ; ++i) {
        printf("%d\n", i);
        sleep(1);
    }
}

使用gcc -O2编译程序后运行,并在另一个虚拟终端里使用gdb attach进程:

root@bt:~# gdb -q -p 2569
Attaching to process 2569
Reading symbols from /root/test3...(no debugging symbols found)...done.
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
0x00007fbf605ac380 in nanosleep () from /lib/libc.so.6
(gdb) bt
#0 0x00007fbf605ac380 in nanosleep () from /lib/libc.so.6
#1 0x00007fbf605ac210 in sleep () from /lib/libc.so.6
#2 0x00000000004005c8 in main ()
(gdb) finish
Run till exit from #0 0x00007fbf605ac380 in nanosleep () from /lib/libc.so.6
0x00007fbf605ac210 in sleep () from /lib/libc.so.6
(gdb) finish
Run till exit from #0 0x00007fbf605ac210 in sleep () from /lib/libc.so.6
0x00000000004005c8 in main ()
(gdb) ni
0x00000000004005a8 in main ()
(gdb)
0x00000000004005aa in main ()
(gdb)
0x00000000004005af in main ()
(gdb)
0x00000000004005b4 in main ()
(gdb)
0x00000000004005b6 in main ()
(gdb)
0x00000000004005b9 in main ()
(gdb)
0x00000000004005be in main ()
(gdb)
0x00000000004005c3 in main ()
(gdb)
0x00000000004005c8 in main ()
(gdb)
0x00000000004005a8 in main ()
(gdb)
0x00000000004005aa in main ()
...
attach会使进程挂起,现象类似于插入了一个临时断点。上面的操作中使用了两次finish命令使程序运行至返回到main()函数中。

对于使用-O2选项编译的程序,无法简单的进行源代码级别的调试,next/step命令不可用。对于此类程序,可以使用nexti/stepi命令,它们大体与next/step相同,分别表示步过与步入,不同之处在于前者针对单条汇编指令。上述示例中连续使用ni(nexti)命令,从指令地址(rip寄存器值)可以比较容易的发现死循环,指令地址始终徘徊在0x00000000004005a8-0x00000000004005c8。

这一招数对于后台daemon程序相当有效。我曾经维护过一个带有守护进程的deamon程序,对于出现问题的运行中子进程,守护进程会将其杀死重启,但并不会记录详细原因。一日,某版本频繁重启,领导下了死命令:必须在XXX之前解决!于是动用重量级上古神器gdb挂上守护进程,让运行中子进程自生自灭。。。天可怜见,终于在一周后重现了问题,并使用上述方法确认了死循环问题及其位置。。。

那晚我梦见了花团锦簇。。。

© 著作权归作者所有

共有 人打赏支持
a
粉丝 2
博文 6
码字总数 2777
作品 0
海淀
程序员
私信 提问
Linux 下段错误产生的原因

用C写了一个小程序,运行时前面部分正常,之后出现段错误提示,网上查了一下资料,明白了原因。 产生段错误就是访问了错误的内存段,一般是你没有权限,或者根本就不存在对应的物理内存,尤其...

曾赛
2009/11/21
125
0
关于 for 循环和 while 循环?

下列关于for循环和while循环的说法中哪个是正确的(  ) A while循环能实现的操作,for循环也都能实现 B while循环判断条件一般是程序结果,for循环判断条件一般是非程序结果 C 两种循环任何...

举个_栗子
2017/12/19
0
0
Android中为什么主线程不会因为Looper.loop()里的死循环卡死?

在知乎上的问题,觉得很好,就转载过来记录一下。 Android程序的运行入口是android.app.ActivityThread类的main()方法。(android-23) 而根据Looper.loop()源码可知里面是一个死循环在遍历消息...

xingjm8511
2016/06/12
114
0
RunLoop运行循环 和 RunTime运行时消息机制的介绍和使用

一.Runloop —运行循环 1)用来干嘛的? 是一个死循环,保证程序不退出。程序默认一个线程执行一个任务,执行完任务后该线程就over掉了,但主线程不行,主线程一over掉程序就没有了。主线程没...

如若初见
2016/04/08
113
0
Emscripten教程之如何调试代码(六)

翻译:云荒杯倾 本文是Emscripten-WebAssembly专栏系列文章之一,更多文章请查看专栏。 也可以去作者的博客阅读文章。 调试Emscripten代码的主要优点之一是,源代码既可以在本地平台上进行调...

云荒杯倾
2017/09/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周二乱弹 —— 其实我在地板也睡不着

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @witt-z :分享歌词: 阴天 在不开灯的房间,当所有思绪都一点一点沉淀。 分享莫文蔚的单曲《阴天》: 《阴天》- 莫文蔚 手机党少年们想听歌,...

小小编辑
6分钟前
9
1
微服务分布式事务实现

https://www.processon.com/view/link/5b2144d7e4b001a14d3d2d30

WALK_MAN
今天
3
0
《大漠烟尘》读书笔记及读后感文章3700字

《大漠烟尘》读书笔记及读后感文章3700字: 在这个浮躁的社会里,你有多久没有好好读完一本书了? 我们总觉得自己和别人不一样,所以当看到别人身上的问题时,很少有“反求诸己”,反思自己。...

原创小博客
今天
4
0
大数据教程(9.5)用MR实现sql中的jion逻辑

上一篇博客讲解了使用jar -jar的方式来运行提交MR程序,以及通过修改YarnRunner的源码来实现MR的windows开发环境提交到集群的方式。本篇博主将分享sql中常见的join操作。 一、需求 订单数据表...

em_aaron
今天
3
0
十万个为什么之什么是resultful规范

起源 越来越多的人开始意识到,网站即软件,而且是一种新型的软件。这种"互联网软件"采用客户端/服务器模式,建立在分布式体系上,通过互联网通信,具有高延时(high latency)、高并发等特点...

尾生
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部