2015-03-06 2 views
0

я написал кусок кода, чтобы проверить НДК-стек Вот фрагмент кодаNDK-стек не может получить полный стек

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

В стеке не видели мой код, неполные стек

Как это исправить

ответ

0

он говорит signal 11 (SIGSEGV), fault addr deadbaad, где 0xDeadBaad (мертвые, плохой), вероятно, что по умолчанию хранится в неинициализированную память (это старый каламбур). Поэтому он пытается читать или выполнять неинициализированную память.

+0

Закрыть. Это преднамеренный доступ в вызове 'abort()', чтобы сделать прерывания libc выделяющимися в журналах сбоев. См. Https://android.googlesource.com/platform/bionic/+/android-4.2.2_r1/libc/unistd/abort.c. – fadden

1

0xdeadbaad был использован Bionic libc для указания преднамеренного прерывания. Вы можете позвонить по номеру abort() по фрагменту стека, который вы получили. Я предполагаю, что вы вызываете ошибку утверждения (которая будет отображаться в logcat).

В некоторых версиях Android в некоторых случаях вы не получите хороший след от abort(). Часть проблемы заключается в том, что функция была помечена атрибутом noreturn поэтому компилятор не выплюнул жалоб, когда вы сделали что-то вроде этого:

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

Если abort() вернулся, этот метод будет возвращать неопределенное значение. В ARM обратный адрес находится в регистре LR и при необходимости сохраняется в стеке ... но если функция не возвращается, то нет необходимости сохранять обратный адрес, поэтому компилятору разрешено его бросать далеко. Это отлично работает, пока вы не захотите получить этот адрес для трассировки стека. Если LR повторно используется, и старое значение не было пролито на стек, оно просто исчезло.

Я думаю, что, возможно, был релиз, где проблема с компилятором была исправлена, но некоторые метаданные ассемблера были неправильными, что привело к подобным проблемам.

Последние версии Android не должны демонстрировать это поведение. Недавние версии также заменили доступ к 0xdeadbaad с более традиционным SIGABRT, поэтому вы больше не видите эту конкретную сигнатуру сбоя.

(FWIW, вы можете увидеть попытку обхода для noreturnin 4.2.2 (see comments). Он работал в более ранних версиях системы.)

Смежные вопросы