登录
  • 欢迎访问Sharezer Blog

使用_Unwind_Backtrace 函数抓取 C/C++ 堆栈的

本文由 简悦 SimpRead 转码, 原文地址 blog.csdn.net

代码示例

#include <stdio.h>
#include <unwind.h>
#include <stdint.h>

#include <signal.h>

struct sigaction act_old;

static _Unwind_Reason_Code unwind_backtrace_callback(struct _Unwind_Context* context, void* arg) {

    uintptr_t pc = _Unwind_GetIP(context);
    if (pc) {
        printf("unwind got pc ...0x%x\n", pc);
    }

    return _URC_NO_REASON;
}

ssize_t unwind_backtrace() {

    _Unwind_Reason_Code rc = _Unwind_Backtrace(unwind_backtrace_callback, 0);

    return rc == _URC_END_OF_STACK ? 0 : -1;
}

void func_1() {
    int ret = unwind_backtrace();
    printf("unwind_backtrace return ...%d\n", ret);
}

void func_2() {
   func_1();
}

static void crash_handler_more(int sig, struct siginfo* info, void* buf) {

    unwind_backtrace();

    sigaction(sig, &act_old, 0);
}

void initCrashHandler() {
    struct sigaction act;
    act.sa_sigaction = crash_handler_more;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    sigaction(SIGKILL, &act, 0);
    sigaction(SIGINT, &act, 0);
    sigaction(SIGQUIT, &act, 0);
    sigaction(SIGILL, &act, 0);
    sigaction(SIGABRT, &act, 0);
    sigaction(SIGBUS, &act, 0);
    sigaction(SIGSEGV, &act, &act_old);
}

void triggerCrash() {
    char *p = 0;
    p[100] = 'a';
}

int main() {

    initCrashHandler();

    func_2();

    triggerCrash();
    return 0;
}

示例代码在正常调用和程序 crash 两种情况下抓取函数调用的 backtrace, 程序崩溃的 backtrace 可以保存下来用于分析崩溃问题. 可以用 dladdr 函数通过 pc 值提取出 Dl_info, 从而拿到函数符号名, 也可以通过 addr2line 工具进行转换.
由于 android 系统的 libc 不是标准的 gnulibc, 常用的 backtrace 抓取函数 android 系统并不支持, 经过验证, _Unwind_Backtrace 可以在 android 系统正常使用, backtrace 的所有 pc 值都可以被准确获取.


Sharezer , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明使用_Unwind_Backtrace 函数抓取 C/C++ 堆栈的
喜欢 (0)
[liangshaoze@sina.cn]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址