linux 程序crash 调试、原因分析及问题定位

您所在的位置:网站首页 linux运行软件卡死 linux 程序crash 调试、原因分析及问题定位

linux 程序crash 调试、原因分析及问题定位

2024-02-26 06:58| 来源: 网络整理| 查看: 265

目录标题 前言PIEcore dump开启core dump backtrace静态库动态库 最后补充几句

前言

linux 程序崩溃,如果能根据已有的插桩日志能排查出来自然好,但是往往日志未全覆盖,这时候大海捞针排查起来还是比较麻烦的。 一般来说有以下这几种方法获取崩溃现场数据。

PIE

PIE (position-independent executable) 是一种生成地址无关可执行程序的技术。如果编译器在生成可执行程序的过程中使用了PIE,那么当可执行程序被加载到内存中时其加载地址存在不可预知性。

需要注意PIE的存在,一些嵌入式板子gcc版本低的话默认不开PIE,但是新版本的gcc默认开PIE的话,那backtrace也好,coredump也好生成出来的地址都是随机的,无法直接通过addr2line去解析,必须使用map函数地址+偏移量的形式去获取正常代码行号。 或者禁用pie,添加-no-pie选项。

core dump

core dump是linux原生自带的一个异常分析工具,当程序运行的过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在一个文件中。注意程序编译 需要带 -g。

开启core dump

linux 默认是关闭的。 在这里插入图片描述

开启

ulimit -c unlimited 在这里插入图片描述

此时,运行程序发生sigsegv之类的异常时,自动生成core文件在执行文件目录下。 在这里插入图片描述

随便写一个简单错误代码,做测试

957: int *a = NULL; 958: *a = 6; //非法,段错误

生成core文件后,执行

gdb core

随后你就可以看到,如下提示,指名在那个文件那个函数的那一行触发异常,如上为958行

warning: Could not load shared library symbols for linux-vdso.so.1. Do you need "set solib-search-path" or "set sysroot"? [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/a7_softfp_neon-vfpv4/libthread_db.so.1". Core was generated by `./JanusFace'. Program terminated with signal SIGSEGV, Segmentation fault. #0 0xacdd0d0c in test::testFunc (this=0x877f8550, stInfo=...) at testServer.cpp:958 958 testServer.cpp: No such file or directory.

这里的测试代码比较简单,如果是具体业务中的可能就要利用上gdb的那些功能,bt full 、查看栈帧,查看局部变量值之类的,方便具体问题具体分析。

(gdb) bt full #0 0xacdd0d0c in test::testFunc (this=0x877f8550, stVideoViewReqInfo=...) at testServer.cpp:958 iRet = -1 a = 0x0 __PRETTY_FUNCTION__ = "void test::testFunc(VIDEO_VIEW_REQ_INFO&)"

如上所示,局部变量a = 0 为空指针 。

backtrace

有时候不方便gdb的时候,那就只能用backtrace之类的函数来辅助分析排查了 注册如sigsegv之类异常信号的异常处理函数,在处理函数中用backtrace查看调用堆栈。

void SigSegv_handler(int signo) { int j, nptrs; void *buffer[BT_BUF_SIZE]; char **strings; nptrs = backtrace(buffer, BT_BUF_SIZE); printf("backtrace() returned %d addresses\n", nptrs); /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO) would produce similar output to the following: */ strings = backtrace_symbols(buffer, nptrs); if (strings == NULL) { perror("backtrace_symbols"); exit(EXIT_FAILURE); } for (j = 0; j


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3