程序调试六部曲

简介:

程序调试六部曲


0.对于简单程序的简单错误,code review复查程序

1.对于简单程序的一般错误,可以用gdb单步跟踪

2.对于应用程序的异常退出,检查是否有应用程序的core,利用core进行调试

3.对于内核程序的异常退出,根据dmesg/kernel panic、内核crash log: /var/crash 进行调试

4.对于没有任何core、vmcore产生的异常,只有出错指令IP信息的,可以利用objdump反汇编二进制,然后结合IP定位出错的汇编语句和函数:

5.对于没有任何线索的异常退出,仔细检查相关的所有日志


为此需要:

0.系统编程实现的时候尽量保证代码的可读性、可维护性;


1.对于重要的代码,尽量维护release/debug两个版本,保证后者编译生成的时候带有-g或者-ggdb选项;


2.保证系统异常时能够生成core,并且自动保存core文件到非易失性存储上去;同时在应用程序的所有异常出口,能利用类似assert(0)的机制触发core的产生;

为了配置系统,让应用程序能够产生core,可以参考下面的设置:

[root@localhost mvt]# cat /etc/sysctl.conf

kernel.core_pattern=/var/core/app/core-%e-%p-%t

kernel.core_uses_pid=1

[root@localhost mvt]# man sysctl

[root@localhost mvt]# cat /etc/systemd/system.conf

[root@localhost mvt]# sysctl -p

kernel.core_pattern = /var/core/app/core-%e-%p-%t

kernel.core_uses_pid = 1



3.设置内核让它能产生vmcore

现在较新的Linux系统都自带了vmcore的自动生成和转储功能,比如在笔者的CentOS7上已经能够在/var/crash/下自动产生vmcore、vmcore-dmesg.txt。如果系统默认不支持,可以检查/boot/grub/grub.conf文件中kernel一行最后是否有crashkernel=auto如果没有,添加上去,重启来让内核支持vmcore自动生成功能。系统起来之后,可以通过下面的命令测试一下:

echo c >/proc/sysrq-trigger  会在/var/crash 下产生一个vmcore 文件


4. 生成的二进制能够通过反汇编定位到所在的函数。

如果没有产生Core,程序里只是提示ip寄存器出错的位置,可以把产生错误的二进制利用objdump进行反汇编,然后依据IP定位出现问题的语句和函数。


5. 如果程序没有任何出错提示就异常退出了,需要仔细分析应用程序日志和系统日志。

笔者在双控系统上曾经碰到两个奇怪的问题:

应用程序中的RPC服务偶尔无法注册成功;

双控的IP心跳偶尔会丢失;


针对第一个问题,后来是通过检查系统日志,发现是因为用systemctl启动的程序中RPC函数依赖的RPC服务并没有在/etc/rc.local里面先执行完,根本原因是:现在的centOS系统启动脚本的执行流程都是基于systemd的方式了,因此传统基于init的/etc/rc.local里的脚本就没办法保证在每个服务启动之前先执行完了。


针对第二个问题,调试过程中发现系统偶尔出现心跳丢失的情况,导致出现failover切机。但是检查正常触发failover的情况,并没有发现程序主动退出的情况。正在百思不得其解的时候,检查系统日志,发现心跳网卡被其他系统服务进程服务接管,并且出现网卡停下的情况,而这刚好导致双控心跳丢失,导致切机。


根据上面的经验,当应用程序作为整个系统服务的一部分启动,出现莫名其妙退出的情况时,需要结合应用程序日志、系统日志进行分析。常用的日志有:/var/log/kernel.log; /var/log/messages;dmesg;/var/log/boot.log。当然这些只是显示内核和启动相关的日志,如果需要拿到系统启动后所有的日志,在centOS上可以通过journalctl >> all.log 抓到所有的日志输出,然后进行分析。




















本文转自存储之厨51CTO博客,原文链接:http://blog.51cto.com/xiamachao/1898772 ,如需转载请自行联系原作者



相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
2月前
|
机器人 程序员 C++
Scratch3.0——助力新进程序员理解程序(案例二、钢琴键盘)
Scratch3.0——助力新进程序员理解程序(案例二、钢琴键盘)
32 0
|
2月前
|
前端开发 JavaScript Java
童年回忆——超级玛丽(内含源码inscode一键运行)
童年回忆——超级玛丽(内含源码inscode一键运行)
|
6月前
|
Go
腥风血雨中,这招救了我的代码!
腥风血雨中,这招救了我的代码!
27 0
|
3月前
|
传感器 Linux 编译器
不同平台下的点灯代码,你在点灯的哪个段位?
不同平台下的点灯代码,你在点灯的哪个段位?
|
9月前
|
程序员 C语言 C++
电视剧里的代码真能运行吗?
虽然剧中说是“C语言期中考试”,但这位同学的代码名叫 draw2.py,一个典型的 Python 文件,再结合截图中的 pen.forward、pen.setpos 等方法来看,应该是用 turtle 海龟作图库来画爱心。
|
10月前
|
Windows
谈一谈|下载软件的门道你懂吗?
谈一谈|下载软件的门道你懂吗?
87 0
|
小程序 数据库
喜欢看球,那就手撸一个看球小程序系统
一,系统展示;二,小程序端代码;三,后端代码;四,数据库;五,手把手教你学习
92 0
喜欢看球,那就手撸一个看球小程序系统
程序人生 - 为什么大人永远不懂孩子的世界?
程序人生 - 为什么大人永远不懂孩子的世界?
92 0
程序人生 - 为什么大人永远不懂孩子的世界?
|
安全 程序员 开发者
程序人生 - 程序员接私活怎样防止做完了不给钱?
程序人生 - 程序员接私活怎样防止做完了不给钱?
140 0
程序人生 - 箴言
程序人生 - 箴言
65 0