C/C++获取程序堆栈信息

碧玉妆成一树高

万条垂下绿丝绦

前言

如果是想做profile,可以使用libunwind获得C++的堆栈信息。

libunwind

这玩意说实话,资料特别特别少,特别是相关接口使用的例子,我只找到了一个,然后其他人全部抄的这一个,而且他还是获取当前程序堆栈的,也就是必须在被profile的程序中调用libunwind接口才能获取到堆栈信息。。。然后还不是中文的,国内关于libunwind的资料真的少

说实话,我觉得这样和现在的需求不符,我们需要是获取其他进程堆栈信息。

然后就只能啃libunwind文档了,发现了两个接口:

unw_init_local(unw_cursor_t *c, unw_context_t *ctxt)
unw_init_remote(unw_cursor_t *c, unw_addr_space_t as, void *arg)

很显然,第一个是在当前程序堆栈为unw_cursor_t指针进行初始化,第二个是利用“远程”程序堆栈为unw_cursor_t指针进行初始化,区别就在于第三个参数了,所以第三个参数一定带有其他进程的信息。

来看看文档中关于arg参数的介绍:

The arg void-pointer tells the address space exactly what entity should be unwound. For example, if unw_local_addr_space is passed in as, then arg needs to be a pointer to a context structure containing the machine-state of the initial stack frame. However, other address-spaces may instead expect a process-id, a thread-id, or a pointer to an arbitrary structure which identifies the stack-frame chain to be unwound. In other words, the interpretation of arg is entirely dependent on the address-space in use; libunwind never interprets the argument in any way on its own.

翻译一下的话,意思就是arg是用来告知“是哪里的堆栈信息应该被解开”,举个例子,如果unw_local_addr_space 是通过as来告知是哪里的堆栈信息要解开,那么arg需要被一个指针来指向一个存有机器状态的空间。然而如果是其他的程序的堆栈空间,则更期望arg指向了一个存有进程id,线程id或者其他堆栈信息的空间。换句话说,需要用户自己来指定这些信息。

说的云里雾里的,可能是自己英语水平太渣了,大概就是arg中需要存有目标进程的信息,目标进程就是要被“解堆栈”的进程,后面那个解释不解释我也不懂了就。

后面在github上直接搜unw_init_remote这个关键词,找到了别人的调用方法。

调用格式是这样的:

void rctx = _UPT_create(pid);   // pid就是目标进程id
unw_init_remote(&cursor, addr_space, rctx)

那怎么绑定进程就解决了。

主要接口介绍

这里只讲这里需要用到的接口,其他的可以自行参考libunwind文档

  1. 获得一块被展开的空间:

    unw_addr_space_t unw_create_addr_space(unw_accessors_t *ap, int byteorder)
    
  2. 获得当前机器状态的上下文:

    int unw_getcontext(unw_context_t *ucp);
    
  3. 跟踪目标进程,可选参数很多,这里用的attach和detach:

    long int ptrace (enum __ptrace_request __request, ...)
    
  4. 根据进程ID得到一个进程信息的void *指针,对应之前说的那个arg

    void *_UPT_create (pid_t)
    
  5. 对进程堆栈展开,并将信息赋给一个cursor,也就是之前介绍的:

    int unw_init_remote(unw_cursor_t *
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
C/C++应用程序在遇到宕机或崩溃时,可以生成dump文件,用于分析和排查问题。dump文件是一个二进制文件,包含了应用程序当前状态的所有信息,例如寄存器的值、堆栈信息、内存快照等。 生成dump文件的过程通常需要在宕机发生时进行设置,在代码中添加相应的处理逻辑。可以使用操作系统提供的工具或使用一些第三方库来生成dump文件。 在Windows操作系统中,可以使用Windows Error Reporting(WER)来生成dump文件。WER会通过注册表设置或程序运行时设置来配置生成dump文件的方式和路径。可以通过指定参数和设置注册表来控制生成dump文件的级别(如只生成小型或完全的dump文件)。当应用程序发生崩溃时,WER会拦截并触发生成dump文件。使用WER生成的dump文件可以在调试器中打开进行分析。 在Linux操作系统中,可以使用glibc库的backtrace机制来生成dump文件。通过设置信号处理函数,将崩溃时的堆栈信息写入文件。可以通过注册信号处理函数,并在函数中使用backtrace和backtrace_symbols将堆栈信息写入文件。 除了使用操作系统提供的工具和机制,还可以使用一些第三方库来生成dump文件,如Google Crashpad和Breakpad等。这些库提供了更灵活和可定制的选项,可以在崩溃发生时执行回调函数,并根据需求生成dump文件。 总之,通过生成dump文件,我们可以在程序崩溃时获取并保存关键的调试信息,有助于分析和定位问题的根源,提高应用程序的稳定性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值