ndk-stack无法获得完整的堆栈

时间:2015-03-06 09:44:55

标签: android c++ c android-ndk

我写了一段代码,以便测试ndk-stack 这是代码片段

libtest.so

    std::vector<int> testVec;

    testVec.at(500);

enter image description here

但我得到的是不完整的堆栈

********** Crash dump: **********
Build fingerprint: 'MI/casablanca_icntv/casablanca:4.2.2/CADEV/1253:user/release-keys'
pid: 24989, tid: 24989  >>> com.ktcp.video <<<
signal 11 (SIGSEGV), fault addr deadbaad
Stack frame #00  pc 0001a852  /system/lib/libc.so: Routine ????:0
Stack frame #01  pc 00018190  /system/lib/libc.so (abort): Routine ????:0
Stack frame #00  pc 0001a852  /system/lib/libc.so: Routine ????:0
Stack frame #01  pc 00018190  /system/lib/libc.so (abort): Routine ????:0
Stack frame #00  pc 0001a852  /system/lib/libc.so: Routine ????:0
Stack frame #01  pc 00018190  /system/lib/libc.so (abort): Routine ????:0
Stack frame #00  pc 0001a852  /system/lib/libc.so: Routine ????:0
Stack frame #01  pc 00018190  /system/lib/libc.so (abort): Routine ????:0
^C^C

enter image description here

在堆栈中没有看到我的代码,不完整的堆栈

如何修复

2 个答案:

答案 0 :(得分:1)

Bionic libc使用

0xdeadbaad表示故意中止。你可以在你得到的堆栈片段上看到对abort()的调用。我猜你是在触发一个断言失败(会出现在logcat中)。

在某些版本的Android上,在某些情况下,您无法从abort()获得良好的跟踪。问题的一部分是该函数被noreturn属性标记,因此当您执行以下操作时,编译器不会吐出投诉:

int foo(int x) {
    if (x == 0) {
        return 12345;
    } else {
        abort();
    }
}

如果返回abort(),则此方法将返回未定义的值。在ARM上,返回地址存在于LR寄存器中,并在必要时保留在堆栈中......但如果函数没有返回,则不需要保存返回地址,因此允许编译器抛出它远。这很好,直到你想拥有堆栈跟踪的地址。如果重新使用LR,并且旧值没有溢出到堆栈,它就会消失。

我认为可能存在修复编译器问题的版本,但某些汇编器元数据错误,导致类似的问题。

Android的最新版本不应出现此行为。最新版本还使用更传统的SIGABRT替换了0xdeadbaad的访问权限,因此您不再看到此特定崩溃签名。

(FWIW,您可以看到noreturn in 4.2.2 (see comments)的尝试解决方法。它在早期版本的系统中有效。)

答案 1 :(得分:0)

它说signal 11 (SIGSEGV), fault addr deadbaad,其中0xDeadBaad(死,坏)很可能默认存储到未初始化的内存中(这是一个旧的双关语)。所以它试图读取或执行未初始化的内存。