转自:http://www.cnblogs.com/li-hao/archive/2013/04/03/2997807.html

在Linux下写C/C++程序的程序员,时常与Core Dump相见。在内存越界访问,收到不能处理的信号,除零等错误出现时,我们精心或不精心写就的程序就直接一命呜呼了,Core Dump是Linux仁慈地留下的程序的尸体,帮助程序员们解决了一个又一个问题。

有时配置不给力,Linux直接毁尸灭迹,没有了Core文件;又有时,刚好磁盘空间不足,Core文件写不下了。没有Core文件的时候,如何知道程序在什么地方出错了呢?addr2line就在这时派上用场。

这是一个示例程序,func函数返回参数a除以参数b的结果。这里使用0作为除数,结果就是程序因为除以0导致错误,直接中断了。

  1. #include <STDIO h="">
  2. int func(int a, int b)
  3. {
  4. return a / b;
  5. }
  6. int main()
  7. {
  8. int x = 10;
  9. int y = 0;
  10. printf("%d / %d = %d\n", x, y, func(x, y));
  11. return 0;
  12. }
  13. </STDIO>
#include int func(int a, int b)
{return a / b;
}int main()
{int x = 10;int y = 0;printf("%d / %d = %d\n", x, y, func(x, y));return 0;
}

使用

$ gcc -o test1 -g test1.c

编译程序,test1.c是程序文件名。执行程序,结果程序异常中断。查看系统dmesg信息,发现系统日志的错误信息:

[54106.016179] test1[8352] trap divide error ip:400506 sp:7fff2add87e0 error:0 in test1[400000+1000]

这条信息里的ip字段后面的数字就是test1程序出错时所程序执行的位置。使用addr2line就可以将400506转换成出错程序的位置:

$ addr2line -e test1 400506
/home/hanfoo/code/test/addr2line/test1.c:5

这里的test1.c:5指的就是test1.c的第5行

  1. return a / b;
  return a / b;

也正是这里出现的错误。addr2line帮助我们解决了问题。

addr2line如何找到的这一行呢。在可执行程序中都包含有调试信息,其中很重要的一份数据就是程序源程序的行号和编译后的机器代码之间的对应关系Line Number Table。DWARF格式的Line Number Table是一种高度压缩的数据,存储的是表格前后两行的差值,在解析调试信息时,需要按照规则在内存里重建Line Number Table才能使用。

Line Number Table存储在可执行程序的.debug_line域,使用命令

$ readelf -w test1

可以输出DWARF的调试信息,其中有两行

  1. Special opcode 146: advance Address by 10 to 0x4004fe and Line by 1 to 5
  2. Special opcode 160: advance Address by 11 to 0x400509 and Line by 1 to 6
Special opcode 146: advance Address by 10 to 0x4004fe and Line by 1 to 5
Special opcode 160: advance Address by 11 to 0x400509 and Line by 1 to 6

这里说明机器二进制编码的0x4004fe位置开始,对应于源码中的第5行,0x400509开始就对应与源码的第6行了,所以400506这个地址对应的是源码第5行位置。

addr2line通过分析调试信息中的Line Number Table自动就能把源码中的出错位置找出来,再也不怕Linux毁尸灭迹了。

addr2line探秘(没有core怎么办)相关推荐

  1. addr2line探秘

    在Linux下写C/C++程序的程序员,时常与Core Dump相见.在内存越界访问,收到不能处理的信号,除零等错误出现时,我们精心或不精心写就的程序就直接一命呜呼了,Core Dump是Linux仁 ...

  2. .NET Core 出得云端入得本地,微软让跨平台应用勇敢表达

    地铁公交的上班路上.咖啡馆里等人的时候,这些碎片化时间都是现代人学习和充电的机会,根据第42次CNNIC中国互联网发展状况统计报告,截至2018年6月,网络文学用户规模已达4.06亿,占网民总体50. ...

  3. ⚠⚠项目时遇到的新函数新问题小记xX

    1,gethostname() : 返回本地主机的标准主机名. 原型如下: #include <unistd.h> int gethostname(char *name, size_t l ...

  4. 依赖注入的三种方式_ASP.NET Core技术研究-探秘依赖注入框架

    ASP.NET Core在底层内置了一个依赖注入框架,通过依赖注入的方式注册服务.提供服务.依赖注入不仅服务于ASP.NET Core自身,同时也是应用程序的服务提供者. 毫不夸张的说,ASP.NET ...

  5. ASP.NET Core技术研究-探秘依赖注入框架

    ASP.NET Core在底层内置了一个依赖注入框架,通过依赖注入的方式注册服务.提供服务.依赖注入不仅服务于ASP.NET Core自身,同时也是应用程序的服务提供者. 毫不夸张的说,ASP.NET ...

  6. Linux下addr2line命令用法

    Linux下addr2line命令用于将程序指令地址转换为所对应的函数名.以及函数所在的源文件名和行号.当含有调试信息(-g)的执行程序出现crash时(core dumped),可使用addr2li ...

  7. C++ 调试技术:addr2line

    最常用的调试C++程序的方法是使用IDE,比如说vs,clion.打断点,debug模式跑. 稍微先进一点的是使用gdb进行调试. gdb调试使用到的技术就比较多了,以后详细介绍. 今天看到一个神奇的 ...

  8. linux下调试core dump方式汇总,工作必备技能

    缘起 调试,是开发流程中一个非常重要的环节.每个程序员都应,具备调试代码的能力,尤其对于从事 Linux 下的开发的读者. 从事 linux 下后台开发,有时候会遇到程序突然崩溃的情况,也没有任何日志 ...

  9. addr2line命令

    ❤️强烈推荐人工智能学习网站❤️ linux下addr2line工具事一个可以将指令的地址和可执行文件映像转换成文件名,函数名和源代码行数的工具.add2line独起来就是addr to line,即 ...

最新文章

  1. java 穷举 排列组合,JavaScript递归穷举所有排列组合并找出重复值
  2. Save a tree as XML using XmlSerializer
  3. Windows server 2008 iis7/iis7.5启用父路径的方法
  4. fmincon函数求解过程中出现无解的情况
  5. Flume-NG一些注意事项(转)
  6. 深度案例 | 3 大领域 7 大场景,消费金融中的行业数据实践(以合众投资集团为例)...
  7. C#中使用FFMPEG切割、合并视频。
  8. 转行IT行业的心路历程3
  9. 腾讯位置服务+微信小程序,一文告诉你程序员为什么不会坐过站!
  10. 你只管打开这个网站,剩下的交给「卧槽」!
  11. 古风诗词选别名-欢迎留言
  12. 存储器的概述——DRAM动态存储器
  13. 阿里云盘小白羊版!你值得拥有的一款第三方阿里云盘客户端
  14. 2019UNCTF-竞技赛 部分WP
  15. HP DL380 G3服务器重做RAID
  16. Ubuntu 高性能模式
  17. 惠普暗影精灵6安装Ubuntu双系统显卡及Wi-Fi问题解决
  18. 大数据:Hadoop集群测试
  19. 2018年前端年度工作总结
  20. 华为机试(扑克牌大小3.3)

热门文章

  1. 每日程序C语言14-小球反弹高度问题
  2. python建立虚拟环境不成功_virtualenv 创建虚拟环境不成功
  3. 界面 高炉系统_首钢京唐七大系统介绍
  4. Luogu 1941 飞扬的小鸟
  5. 2018 前端面试题(不定期更新)
  6. NaN Inf(OC)
  7. @Transactional注解事务不回滚不起作用无效
  8. [c#]Dll自定义目录
  9. 【03】json使用
  10. linux 企业数据,Linux企业数据标准出炉 IBM惠普等数巨头加盟