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

本文介绍了如何使用libunwind库获取C/C++程序的堆栈信息,特别是在profile场景下的应用。文章详细讲解了libunwind的主要接口,并提供了获取其他进程堆栈信息的简单示例。
摘要由CSDN通过智能技术生成

碧玉妆成一树高

万条垂下绿丝绦

前言

如果是想做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
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值