【问题标题】:How to use CallStack (in CallStack.tpp) in a executable on android platform?如何在 android 平台上的可执行文件中使用调用堆栈(在 Call Stack.top 中)?
【发布时间】:2012-07-13 06:52:57
【问题描述】:

来自https://stackoverflow.com/a/11467040/1442443的问题

我的最终目标是转储用户空间堆栈。

我尝试将如下的 cpp 文件构建为 android 平台上的 可执行文件。因此,通过调用 tryToGetStack(),我可以在运行时获取可执行文件的调用堆栈。

#include <utils/CallStack.h>
namespace android
{
    extern "C" void tryToGetStack()
    {
        CallStack stack;
        stack.update();
        stack.dump("");
    }
}

并将 lib 设置添加到 Android.mak,因为 CallStack.tpp 在 libutils 中

LOCAL_SHARED_LIBRARIES += libutils

但我总是收到错误消息:

错误:未定义对 'android::CallStack::CallStack()' 的引用

错误:未定义对 'android::CallStack::update(int, int)' 的引用

...

似乎可执行文件在链接时解析符号,而不是在运行时加载 .so 文件? 我是否遗漏了什么或者 Android 构建系统有一些限制?

我知道这是一个简单的问题,但我真的需要帮助......

更新1

我尝试将代码添加到另一个可执行文件。结果是一样的……有人知道android构建系统的规则吗?

更新2

我的控制台里有一些关键词“target StaticExecutable: ...”,我觉得就是答案。

http://en.wikipedia.org/wiki/Static_executable

【问题讨论】:

  • 仅供参考,看起来 CallStack 现在在 android-p 上的 libutilscallstack 中提供。

标签: android linux build stack-trace callstack


【解决方案1】:

我的最终目标是转储用户空间堆栈

从网上google了这么多资料,我发现有4种方法:

  1. ptracehttp://en.wikipedia.org/wiki/Ptrace

    用ptrace真的很难用,需要先停止线程再用ptrace附加

  2. _unwind_backtrace:CallStack使用的方式(CallStack.cpp中的CallStack类)

    示例:http://git.stlinux.com/?p=stm/uclibc.git;a=blob;f=libubacktrace/sysdeps/sh/backtrace.c;h=18b91b1bb3fa26344a521927c631553a410fcf56;hb=d6a3d9ece5922a337800a8e2ed4db7e226f9ccb3

    它有一个缺点:如果你在线程处理信号时使用它,它会转储信号堆栈而不是转储线程堆栈

    同样的问题:How to get fullstacktrace using _Unwind_Backtrace on SIGSEGV

  3. 回溯http://www.gnu.org/software/libc/manual/html_node/Backtraces.html

    一个 GNU 扩展函数,在 Android 使用的 Bionic libc 中没有实现

    参考:https://stackoverflow.com/a/8295238/1442443

    参考:http://lists.puredata.info/pipermail/pd-list/2012-02/094258.html

  4. 转储用户空间线程堆栈的补丁http://www.gossamer-threads.com/lists/linux/kernel/1525096

    但只能在 X86 架构中实现... orz

    我尝试将它移植到android,不,它只显示堆栈的第一帧,因为arm不使用帧指针。

所以... 2 就是答案。

但是,我想知道是否有人可以解决这个问题:How to get fullstacktrace using _Unwind_Backtrace on SIGSEGV

更新:

如果你可以使用交叉编译器来使用glic编译你的代码,也许你可以使用 3. backtrace ! http://communities.mentor.com/community/cs/archives/arm-gnu/msg02514.html

更新2 好文章

http://codingrelic.geekhold.com/2009/05/pre-mortem-backtracing.html

【讨论】:

    【解决方案2】:

    因为这是一个如此重要的问题,所以我的回答对我有用。我的代码是 C 语言,所以它必须调用一个可以访问 android::CallStack 的 C++ 函数。

    stackdump.cpp:

    #include < utils/CallStack.h >
    extern "C" void dumpCallStack( char *label)
    {
       android::CallStack cs;
       cs.update();
       cs.dump(label);
    }
    

    我的主要代码(foo.c):

    void dumpCallStack(char *label);
    
    ...
    
    dumpCallStack(\__FUNCTION__);
    

    【讨论】:

      【解决方案3】:

      我曾经遇到过同样的问题。而且很难解释。

      语法当然正确合理!

      我尝试了很多方法,但都不起作用。

      最后,我有一个想法,应该将 lib 引用“LOCAL_SHARED_LIBRARIES += libutils”放入生成动态库的 makefile 中,而不是放入生成静态库的 makefile 中。这是最后一个原因。

      参考: http://yongbingchen.github.io/blog/2013/05/09/dump-stack-in-android-native-c-code/

      【讨论】:

        【解决方案4】:

        我也收到此错误,但我补充说:

        LOCAL_STATIC_LIBRARIES += libutils 
        

        在三个目标的vm/Android.mLOCAL_MODULE := xxx 行之前并添加了

        LOCAL_SHARED_LIBRARIES += libcorkscrew
        

        vm/Android.mk

        libdex/Android.mk,同样适用于dexlist/Android.mkdexdump/Android.mk

        完成所有这些之后,它对我有用。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-01-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-12-23
          相关资源
          最近更新 更多