Jak můžu chytit SIGSEGV (chybám segmentace) a získat trasování zásobníku pod JNI o ​​Androidu?

hlasů
82

Jdu projekt na nový Android Native Development Kit (tj JNI) a rád bych chytat SIGSEGV, mělo by dojít k (případně i SIGILL, SIGABRT, SIGFPE) za účelem prezentace krásný pád dialog hlášení, namísto (nebo dříve), co v současné době děje: okamžitá nenucený smrt procesu a případně některé pokus OS ji restartovat. ( Edit: JVM / Dalvik VM zachytí signál a přihlásí trasování zásobníku a další užitečné informace, jen chci nabídnout uživateli možnost email, který informace ke mně opravdu).

Situace je: velká skupina C kód, který jsem nepsal dělá většinu práce v této aplikaci (celá hra logika), a přestože je to dobře testován na mnoha dalších platformách, je docela možné, že jsem v mém Android přístav, budou krmit odpadky a způsobit zhroucení v nativním kódu, takže chci, aby havárie skládky (jak nativní a Java), které se v současné době zobrazují v protokolu Android (Myslím, že to bude stderr v situaci, non-Android). Jsem volná modifikovat i C a Java kód libovolně, i když zpětná volání (a to jak na vstupu a vycházející z JNI) číslo asi 40 a samozřejmě, bonusové body pro malé diferenciálů.

Slyšel jsem signálu řetězení knihovnu v J2SE, libjsig.so, a jestli bych mohl bezpečně instalovat handler signálu takhle na Android, které by vyřešilo lapací část mé otázky, ale nevidím žádnou takovou knihovnu pro Android / Dalvik ,

Položena 05/07/2009 v 00:18
zdroj uživatelem
V jiných jazycích...                            


4 odpovědí

hlasů
77

Edit: Od Jelly Bean roku nemůžete získat trasování zásobníku, protože READ_LOGSodešel . :-(

Vlastně jsem dostal handler signálu pracovat, aniž by dělali něco příliš exotické, a vydali kódu používat, které si můžete prohlédnout na github (edit: odkazují na historické propuštění; Odstranil jsem rutinu nárazu od té doby). Zde je návod:

  1. Použijte sigaction()zachytit signály a uložit staré rutiny. ( Android.c: 570 )
  2. Čas plyne, je segfault stane.
  3. V obsluze signálu, volat až JNI naposledy a pak volat starou rutinu. ( Android.c: 528 )
  4. V tomto JNI volání log jakékoli užitečné informace o ladění, a zavolat startActivity()na činnost, která je označena jako museli být ve vlastním procesu. ( SGTPuzzles.java:962 , AndroidManifest.xml: 28 )
  5. Když se vrátil z Javy a zavolat tu starou rutinu, bude Android rámec připojit debuggerdk přihlášení krásný nativní trasu pro vás, a pak se proces zemře. ( Debugger.c , debuggerd.c )
  6. Mezitím vaše crash-manipulace aktivita spouští. Opravdu byste měli projít PID, takže to může počkat na krok 5 až dokončení; Nechci to dělat. Zde se omluvit uživatele a zeptejte se, zda můžete odeslat log. Pokud tomu tak je, shromáždit výstup logcat -d -v threadtimea zahájit studii ACTION_SENDs příjemce, předmět a tělo vyplněna. Uživatel bude muset stisknout tlačítko Odeslat. ( CrashHandler.java , SGTPuzzles.java:462 , strings.xml: 41
  7. Dejte si pozor na logcatselhání nebo při více než pár vteřin. Setkal jsem se s jedním zařízením, T-Mobile Pulse / Huawei U8220, kde logcat okamžitě přejde do T(dohledat) stavu a zavěsí. ( CrashHandler.java:70 , strings.xml: 51 )

V situaci, non-Android, někteří to by bylo něco jiného. Byste museli shromáždit své vlastní nativní trasování, viz tu druhou otázku , v závislosti na tom, jaký druh libc máte. Byste museli zvládnout dumping, že stopy, zahajuje svou samostatnou crash-psovoda proces a odeslání e-mailu v některých vhodných způsobů platformu, ale jsem si představit obecný přístup by měl i nadále fungovat.

Odpovězeno 24/11/2009 v 13:49
zdroj uživatelem

hlasů
14

Jsem trochu pozdě, ale měl jsem přesně stejnou potřebu, a já jsem vyvinul malou knihovnu, aby ho informoval, že chytí společné havárie ( SEGV, SIBGUS, atd) uvnitř JNI kód a nahradit je pravidelným java.lang.Error výjimkami . Bonus, pokud je klient běží na systému Android> = 4.1.1, trasování zásobníku vloží vyřešen backtrace o nehodě (pseudo-trasování obsahuje plnou nativní trasování zásobníku). Nebudete získat od zlých dopravních nehod (tj. Pokud si poškozený alokátor, například), ale aspoň by měl vám umožní zotavit se z většiny z nich. (ohlaste úspěchy a neúspěchy, kód je zcela nový)

Více informací na https://github.com/xroche/coffeecatch (kód BSD 2-Clauses licence )

Odpovězeno 28/08/2013 v 18:08
zdroj uživatelem

hlasů
6

FWIW, Google Breakpad funguje na Android. Udělal jsem portování práci, a my jsme dodávat jako součást Firefox Mobile. To vyžaduje trochu nastavení, protože to nedává vám stack stopy na straně klienta, ale pošle vám syrové zásobníku paměti a dělá stoh chůzi na straně serveru (takže nemusíte mít na loď symboly ladění s aplikací ).

Odpovězeno 08/11/2011 v 21:17
zdroj uživatelem

hlasů
5

V mé omezené zkušenosti (non-Android), SIGSEGV v JNI kód ​​obecně pád JVM před ovládací prvek se vrátí do kódu Java. Matně si vzpomínám, co slyšel o nějakém non-Sun JVM, který vám umožní zachytit SIGSEGV, ale AFAICR nemůžete očekávat, že bude schopen tak učinit.

Můžete se pokusit chytit v jazyce C (viz sigaction (2)), i když je možné po SIGSEGV (nebo SIGFPE nebo SIGILL) jen velmi málo psovoda jako pokračující chování procesu je oficiálně definován.

Odpovězeno 05/07/2009 v 02:55
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more