异常信息转储预研笔记-堆栈地址转换

addr2line命令

addr2line -e <exec> <addr> -f | xargs c++filt

<exec>: 进程名
<addr>:堆栈地址

eg:
addr2line -e backtrace 0x4009d2 -f | xargs c++filt

此方案测试了,不知道什么原因只显示?? ??:0 ,而预期显示应该如下:

/home/xxx/backtrace/backtrace.cpp:13

简单查了一下原因,addrline命令需要的是偏移地址,而不是打印出来的绝对地址。

偏移地址 = 绝对地址 - 初始地址

addr2line缺陷:

注意,使用glibcbacktrace追踪的堆栈调用信息,通过addr2line只能获取函数的行号,而无法获取so库的内部函数的行号。

暂不深究;

dladdr方案

头文件

#include <dlfcn.h>

链接库

Dynamic linking library (libdl, -ldl)

函数原型

int dladdr(const void *addr, Dl_info *info);

// Dl_info结构体描述如下:
          typedef struct {
               const char *dli_fname;  /* Pathname of shared object that
                                          contains address */
               void       *dli_fbase;  /* Base address at which shared
                                          object is loaded */
               const char *dli_sname;  /* Name of symbol whose definition
                                          overlaps addr */
               void       *dli_saddr;  /* Exact address of symbol named
                                          in dli_sname */
           } Dl_info;

 解释

dli_fname:共享对象的路径名,包含地址;

dli_fbase:加载共享对象的基址;

dli_sname:定义与地址重叠的符号名称;

dli_saddr:dli_sname中命名的符号的确切地址;

实际输出示例依次如下:

/lib/x86_64...../libc.so.6

0x7343e5521000

usleep()

0x7343e5534000

问题记录

描述:使用dladdr后编译,报错undefined reference to symbol 'dladdr@@GLIBC_2.2.5'

解决:在编译命令后加上-ldl

elfutils/libdwfl方案(todo)

backtrace - Even - A super concise theme for Hugo (bishuiliuyun.github.io)

elfutils项目

The elfutils project (sourceware.org)

题外(todo)

异常信息转储除了libunwind,还有google的coredumper方案,暂未研究,记录一下埋个坑。

Google Code Archive - Long-term storage for Google Code Project Hosting.

 

待解决

1、libunwind打印的函数名被其他字符覆盖了一些(被混淆),看着很不友好,需要优化,可能方案:abi::__cxa_demangle;

2、使用dladdr未能输出行号;

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
_roi_buf_id, 1); if (status != VA_STATUS_SUCCESS) { printf("vaRenderPicture failed\n"); return -1; } status = vaEndPicture(va_display, va_context_id); if (status != VA_STATUS_SUCCESS) { 在 Windows 操作系统中,获取程序的堆栈信息可以使用以下两种方式: 1. 使用 Visual Studio: - 打开 Visual printf("vaEndPicture failed\n"); return -1; } vaDestroySurfaces(va_display, &va_src_surface Studio,选择“调试”菜单下的“附加到进程”选项; - 在弹出的对话框_id, 1); av_frame_free(&pFrame); frame_count++; } } av_packet_unref(&packet); 中选择要获取堆栈信息的进程,点击“附加”按钮; - 等待程序运行到需要获取堆栈 } // Clean up vaDestroyBuffer(va_display, seq_param_buf_id); vaDestroyBuffer(va_display, pic_param信息的地方,然后在 Visual Studio 中选择“调试”菜单下的“Windows”选项,再选择“_buf_id); vaDestroyBuffer(va_display, va_roi_buf_id); vaDestroySurfaces(va_display, &va_surface_id, 1); vaDestroyContext(va_display, va_context_id); vaDestroyConfig(va_display, config_id); vaTerminate(va_display调试窗口”下的“调用堆栈”选项。 2. 使用 Windows 自带的工具: - 打开); avcodec_free_context(&pCodecCtx); avformat_close_input(&pFormatCtx); return 0; } ``` “任务管理器”,在“详细信息”选项卡中找到要获取堆栈信息的进程; - 右键注意,这只是一个简单的示例代码,可能需要根据实际情况进行修改。同时,还应该点击该进程,选择“转储文件” -> “完整转储”; - 打开转储文件(.dmp注意以下几点: - ROI 数据的格式和内容要符合 H.264 标准; - ROI 数据要在每一帧文件),使用 Windbg 工具打开该文件; - 在 Windbg 命令行中输入“!analyze -v”命令编码前设置,否则不会生效; - VA API 的具体使用方式可以参考官方文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值