3

来自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

4

4 回答 4

6

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

从网上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

update2 一篇好文章

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

于 2012-07-18T09:30:02.503 回答
2

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

堆栈转储.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__);
于 2014-01-19T03:25:42.987 回答
0

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

语法当然是正确合理的!

我尝试了很多方法,但没有奏效。

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

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

于 2014-02-28T09:32:52.353 回答
0

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

LOCAL_STATIC_LIBRARIES += libutils 

LOCAL_MODULE := xxxvm/Android.m三个目标的行之前并添加

LOCAL_SHARED_LIBRARIES += libcorkscrew

vm/Android.mk

libdex/Android.mk, 和dexlist/Android.mk,dexdump/Android.mk

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

于 2017-07-30T15:55:19.893 回答