如何在没有core文件的情况下用dmesg+addr2line定位段错误
前言
在现网环境下,程序奔溃后不一定会留下core文件,原因有很多,比如存储空间不足就是其中一个常见的原因。此时我们只能依据linux记录的错误日志来定位问题。
涉及linux命令
本文涉及以下几条命令
1. dmesg命令,用于获取程序出错时的堆栈地址
1)dmesg |grep -E 'segfault|general'
可以通过该命令过滤出发生崩溃的程序,以及对应的堆栈信息。之前看网上的其他文章仅过滤segfault,但我在实践中发现"general protection"的提示信息也在告诉我们进程崩了。目前我只遇到segfault和general这两种情况,如果还有其他的过滤条件可以给我留言。
举例:
[root@vmware ~] dmesg |grep -E 'segfault|general'
[ 374.549753] a.out[57228]: segfault at 0 ip 00000000004004fd sp 00007ffe7296f610 error 6 in a.out[400000+1000]
[ 429.110096] b.out[96783]: segfault at 0 ip 00000000004004fd sp 00007ffcc3e697c0 error 6 in b.out[400000+1000]
字段说明:
1)ip:指令指针寄存器,字段后面的数字就是test程序出错时程序执行的位置
2)sp:堆栈指针寄存器
3)error:错误码,由三个字位组成的,从高到底分别为bit2 bit1和bit0
bit2: 值为1表示是用户态程序内存访问越界,值为0表示是内核态程序内存访问越界
bit1: 值为1表示是写操作导致内存访问越界,值为0表示是读操作导致内存访问越界
bit0: 值为1表示没有足够的权限访问非法地址的内容,值为0表示访问的非法地址根本没有对应的页面,也就是无效地址
4)b.out后面紧跟着的地址(这里是400000)这个在定位时也有用到,不知道该怎么描述,知道的给我留言
2)dmesg |grep 进(线)程名
通过进程或线程名来过滤。这里之所以强调线程,因为我在实践中发现dmesg里的信息可能只有线程名,所以推荐在给线程取名时使用统一前缀,比如你的主进程为Test,那么线程可以取Test_A,Test_A,这样过滤时 grep Test就能过滤出所有想要的信息
举例:
[root@vmware ~] dmesg |grep a.out
[ 374.549753] a.out[57228]: segfault at 0 ip 00000000004004fd sp 00007ffe7296f610 error 6 in a.out[400000+1000]
3)dmesg -C
dmesg命令查看到的信息在重启后将会被清空,若当前错误信息太多也可以通过该命令手动清空dmesg信息,以便下次问题的定位。-C(大写)参数为静默清空,如果清空前还想打印一次,可以通过-c(小写)参数。
注:
cat /var/log/messages |grep xxx
这里也保存进程奔溃信息,且重启后依然存在。
举例:
[root@vmware ~] cat /var/log/messages|grep b.out
May 8 09:24:04 vmware kernel: b.out[96783]: segfault at 0 ip 00000000004004fd sp 00007ffcc3e697c0 error 6 in b.out[400000+1000]
May 8 09:24:04 vmware abrt-hook-ccpp: Process 96783 (b.out) of user 0 killed by SIGSEGV - dumping core
May 8 09:24:05 vmware abrt-server: Executable '/root/b.out' doesn't belong to any package and ProcessUnpackaged is set to 'no'
2. date 用于转换dmesg信息里的时间戳
date -d "1970-01-01 UTC `echo "$(date +%s)-$(cat /proc/uptime|cut -f 1 -d' ')+时间戳"|bc `seconds"
举例:
[ 672.091250] a.out[26520]: segfault at 0 ip 00000000004004fd sp 00007ffe51b27fe0 error 6 in a.out[400000+1000]
[root@vmware ~] date -d "1970-01-01 UTC `echo "$(date +%s)-$(cat /proc/uptime|cut -f 1 -d' ')+672.091250"|bc `seconds"
2019年 05月 08日 星期三 09:40:02 CST
3. ldd 用于获取进程所依赖的动态库,以及所在位置
4. addr2line,将dmesg获取到的地址转换为代码中发成错误的文件、行号及函数名
奔溃发生的位置不同,该命令的使用方式也有所不同
1)在主进程中奔溃
addr2line -e 进程名 IP指令地址 -f
举例:
#include <stdio.h>
int main()
{
int *p = NULL;
*p = 0;
return 0;
}
[root@vmware ~] gcc a.c -g
[root@vmware ~] ./a.out
段错误(吐核)
[root@vmware ~] dmesg |grep a.out
[ 1310.167335] a.out[122089]: segfault at 0 ip 00000000004004fd sp 00007ffcf08f3ab0 error 6 in a.out[400000+1000]
[root@vmware ~] addr2line -e a.out 00000000004004fd -f
func
/root/a.c:5
通过该例子我们可以看到,程序发生段错误的函数以及具体位置。需要注意的是如果编译程序时没有加上-g参数,就只能显示出函数名,显示不出具体所在文件的位置.
2)动态库中奔溃
addr2line -e 进程名 “IP指令地址-动态库后紧跟着的地址” -f
举例:
#include<stdio.h>
#include<string.h>
void func()
{
int *p = NULL;
memcpy(p, "test", 4);
} int main()
{
func();
return 0;
}
[root@vmware ~] dmesg |grep a.out
[ 6807.501481] a.out[72684]: segfault at 0 ip 00007f6559bc7463 sp 00007fff80625b18 error 6 in libc-2.17.so[7f6559a7c000+1b6000]
[root@vmware ~] ldd a.out
linux-vdso.so.1 => (0x00007ffc643f6000)
libc.so.6 => /lib64/libc.so.6 (0x00007f83ef206000)
/lib64/ld-linux-x86-64.so.2 (0x00007f83ef5e2000)
[root@vmware ~] addr2line -e /lib64/libc.so.6 14B463 -f
__memcpy_ssse3_back
:?
这个这个例子我们可以看到,段错误发生的位置是在a.out进程调用的libc库里,因此addr2line指向的地址使用14B463 = 00007f6559bc7463 - 7f6559a7c000
如何在没有core文件的情况下用dmesg+addr2line定位段错误的更多相关文章
- ng-file-upload(在单文件选择,并且通过点击“上传”按钮上传文件的情况下,如何在真正选择文件之前保留上一文件信息?)
文章前面研究ng-file-upload可能涉及指令: You can use ng-model or ngf-change instead of specifying function for ng ...
- 嵌入式 linux下利用backtrace追踪函数调用堆栈以及定位段错误
嵌入式 linux下利用backtrace追踪函数调用堆栈以及定位段错误 2015-05-27 14:19 184人阅读 评论(0) 收藏 举报 分类: 嵌入式(928) 一般察看函数运行时堆栈的 ...
- linux下利用backtrace追踪函数调用堆栈以及定位段错误
一般察看函数运行时堆栈的方法是使用GDB(bt命令)之类的外部调试器,但是,有些时候为了分析程序的BUG,(主要针对长时间运行程序的分析),在程序出错时打印出函数的调用堆栈是非常有用的. 在glibc ...
- Linux下利用backtrace追踪函数调用堆栈以及定位段错误[转]
来源:Linux社区 作者:astrotycoon 一般察看函数运行时堆栈的方法是使用GDB(bt命令)之类的外部调试器,但是,有些时候为了分析程序的BUG,(主要针对长时间运行程序的分析),在程序 ...
- Linux 下运行 C++ 程序出现 “段错误(核心已转储)”
Linux下写C++程序出现“段错误(核心已转储)”的问题: 段错误一般就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gdtr来保存的,他是一个48位的寄存器,其中的32位是保存由它 ...
- php 502 无错误行和报错文件的情况下使用gdb调试方法
lnmp环境 gdb /usr/local/php5.2/bin/php-cgi /tmp/coredump-php-cgi.20503 source /home/tmp/lnmp1.4-full ...
- Linux开启SELinux的情况下怎么解决nginx403跟502错误
https://www.cnblogs.com/caijt/p/10978324.html 以上篇博客中说了怎么在linux部署asp.net core 跟 nginx,里面成功的前提是把SElin ...
- Linux下利用backtrace追踪函数调用堆栈以及定位段错误【转】
转自:https://www.linuxidc.com/Linux/2012-11/73470p2.htm 通常情况系,程序发生段错误时系统会发送SIGSEGV信号给程序,缺省处理是退出函数.我们可以 ...
- 自定义ListView适配器Adapter引用布局文件的情况下实现点击列表项时背景颜色为灰色
listview控件设置适配器的时候,如果使用自定义的adapter,比如MyArrayAdapter extends ArrayAdapter<String> 如果listitem布局文 ...
随机推荐
- linux sort 命令实用手册
Linux 中的sort 命令是一个很实用的工具,用于对文本内容以行为单位进行ASCII 码排序,默认按照升序进行排序(当然也可以按照降序). sort 命令的格式如下: sort `参数` `文件名 ...
- Deep Snake : 基于轮廓调整的SOTA实例分割方法,速度32.3fps | CVPR 2020
论文提出基于轮廓的实例分割方法Deep snake,轮廓调整是个很不错的方向,引入循环卷积,不仅提升了性能还减少了计算量,保持了实时性,但是Deep snake的大体结构不够优雅,应该还有一些工作可以 ...
- Android自绘制控件
开发过程中,我们免不了需要用到一些自定义的 View,自定义 View 一般可分为三类: ① 继承类 View —— 一般继承系统以后的基本 View,新增/重置一些自定义属性 ,例如两端对齐的Tex ...
- 【集群实战】NFS网络文件共享服务
1. NFS介绍 1.1 什么是NFS? NFS是Network File System的缩写,中文意思是网络文件系统. 它的主要功能是通过网络(一般是局域网)让不同的主机系统之间可以共享文件或目录. ...
- 定了,这个vue.js开源项目,面试时,一定会考问
因为现在的网店,都是用的商城系统, 而实体店都是入座后,扫码打开网上商城进行选购(餐饮,超市等),所以,vue.js迅速开发网上购物商城系统成为了香饽饽, 本人开源2020年4月开发的购物商城系统, ...
- $_server[]关于浏览器和服务器的参数获取
$_SERVER['USER'] www $_SERVER['HOME'] /home/www $_SERVER['HTTP_UPGRADE_INSECURE_REQUESTS'] 1 $_SERVE ...
- Hadoop学习笔记(一)——安装与配置
操作系统:Ubuntu 15.04; Hadoop version: 2.6.4 参考文献: Ubuntu上搭建Hadoop环境(单机模式+伪分布模式)
- USACO Training Section 1.1 坏掉的项链Broken Necklace
题目描述 你有一条由N个红色的,白色的,或蓝色的珠子组成的项链(3<=N<=350),珠子是随意安排的. 这里是 n=29 的二个例子: 第一和第二个珠子在图片中已经被作记号. 图片 A ...
- 2019-2020 ICPC, Asia Jakarta Regional Contest A. Copying Homework (思维)
Danang and Darto are classmates. They are given homework to create a permutation of N integers from ...
- Jenkins+Ansible+Gitlab自动发布/回滚Spring项目
一.实现方法流程图 流程图如下:代码托管在本地GitLab上(为了复现整套流水线,我直接使用了GitHub,懒得再搭建GitLab),开发完成后提交代码到代码仓库,[自动]触发Jenkins进行持续集 ...