6

两大绝招debug core dump?

 2 years ago
source link: https://zhuanlan.zhihu.com/p/444389626
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

两大绝招debug core dump?

CrackingOysters——源于编程珠玑

每个人都不希望程序莫名奇妙的奔溃,但是当程序崩溃的时候,我们该怎么做呢?

写C/C++经常要面对core dump——没有调试过core的C/C++程序员要么是新手,要么写的程序就是比较小的。

没有人希望调试core dump,但是但程序奔溃的时候,有core dump有时反而是一种幸事。

我写过一篇gdb调试的文章(一千多个赞),现在讨论讨论束手无撤时候,我们还可以尝试什么来破局。

文章也发于https://mp.weixin.qq.com/s/dxFiopnf9jnwwYwrHHaDgw

core dump是什么?

core dump是程序在被操作系统杀掉以后,保留的一份内存快照,就像是犯罪现场,罪犯已经不见了,留下的是犯罪现场。

(注,并不是所有时候都会有core dump,需要操作系统开启和相应的设置。如果是Linux,可以通过命令sysctl kernel.core_pattern查看存储的位置,命令ulimit查看是否开启。)

(本文集中论述Linux有关,但是原理在Windows Mac也是类似的)

那么如何debug core dump呢?

v2-e405d13baa80159e3d0c5bf289a513b9_720w.png

首先要做的是看日志,如果没有日志或者日志不管用,那么我们就会看看有没有core 产生,如果产生了,那么我们就会用gdb 加载core,然后查看到底是在哪里crash了。

新手程序员在完成上面的几个步骤以后,如果找不到原因,就不知道怎么办了?觉得这就是尽头了。

而实际上,我们还有办法来继续寻找真凶!

回到犯罪的类比,当我们赶到现场的时候,我们可以用如下的方法来寻找真凶:

  1. 通过现场的蛛丝马迹,来寻找
  2. 罪犯可能会再犯,在特定的位置蹲点或者是安装摄像头。

调式程序崩溃,道理也是类似的。但是从方便的角度,我们会先采取在特定的位置蹲点和安装摄像头。

在特定的位置蹲点,就是用gdb 调式程序,在特定位置打断点。

这个方法适用于开发环境。生产环境一般不这么用。

似乎大部分bug我们都可以用gdb来调试,我们这里聚焦的bug是使得程序崩溃的那些bug。

C/C++使得程序崩溃的bug却很多时候不能用这种方式来寻找原因。

因为C/C++程序奔溃的bug大部分是memory corruption/内存破坏。

内存破坏的bug具有随机性,并不是在特定的位置发生,所以这个蹲点往往不可靠。

安装摄像头

正因为memory corruption的bug十分难解决,耗费精力,业界推出了许多工具来帮助调试。

而这里我特别推荐google address sanitizer

有了google address sanitizer (GAS),memory corruption没那么面目可憎了。

什么是address sanitizer?

它其实就是安装摄像头,通过在你的程序里面安装摄像头,那么罪犯在犯罪的时候就会被抓住。

哇,世界变得美好许多了!

google 用这个工具发现了许多bug,我们公司也是,这个工具可以说是C/C++程序必备的了。

这个工具厉害的地方,一个是安装了摄像头,让犯罪无处遁形,二是程序变慢不是非常厉害。

(具体的操作,可以发现的bug,以后再补充一下,现在主要记录思路)

既然可以安装摄像头,那么是不是我们程序员就完全不用怎么伤脑筋了?

假设我们有100个bug,那么gdb调试可以解决60,GAS可以解决30个,我们还有10个还需要借助其他手段。

为什么gdb调试和GAS不能把100个bug都解决呢?

因为gdb和GAS很多时候只能在开发环境和测试环境使用,生产环境使用会有一定的性能影响。

所以有些bug是在生产环境发生的。这时候我们能可以利用的信息,只能从犯罪现场寻找了。(有一些工具也可以用在生产环境中,按下不表)

而当程序崩溃的时候,除了日志,我们能发掘的现场,就是core dump。

入门的程序员会使用gdb调试core dump,但是面对memory corruption,却不知如何更好地利用gdb。

而gdb有时候也提供不了犯罪的全部信息,怎么确定是memory corruption,而不是其他类型的bug呢?

我们这时候可以怎么做呢?

Core Analyzer

这里介绍一下我们公司的大牛写的工具,GitHub - yanqi27/core_analyzer: A power tool to debug memory-related issues

大牛是调试core dump的专家,而且写过一本书叫<<effective debugging>>(不是市面上的那本,我准备翻译为中文)

core analyzer的强大功能可以看连接的github。这里简短说一下,它可以遍历整个内存,告诉你是不是有memory corruption,如果有就会告诉你哪里出错了;可以告诉你一块内存区域的pattern是什么;可以帮助你找出被多线程共享的变量;可以寻找某个类型的对象等等

我开这篇文章的一个目的是讲讲它的实现原理。先开个坑,后面补上。

当我们使用了以上所有的手段,还有一些bug无法解决?这时候怎么办呢?

如果对本系列文章感兴趣,可以移步CrackingOysters:如何debug crash 系列

或者关注我知乎和公众号CrackingOysters


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK