Фатальный сигнал 11 (SIGSEGV)

У меня странная ошибка, и я не могу найти, откуда она взялась. Единственное, что появляется в logcat:

01-10 17:07:10.665: A/libc(20449): Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1)

Я не получаю эту ошибку сразу после запуска своего приложения, я получаю его через случайное время (что-то между 1 мин. До 5 мин). Я не могу воспроизвести эту ошибку, она кажется случайной и, поскольку нет никакой другой информации, ее трудно отлаживать. Я попытался добавить некоторые данные журнала в свою библиотеку, но я все еще не могу сказать, где произошел сбой.

Я запускал одно и то же приложение x раз, и у меня был другой адрес SIGSEGV (иногда это был тот же адрес, что и раньше:

01-10 17:29:04.650: A/libc(21588): Fatal signal 11 (SIGSEGV) at 0x6c707063 (code=1)

01-10 17:25:55.165: A/libc(21473): Fatal signal 11 (SIGSEGV) at 0x0069004c (code=1)

01-10 17:11:58.780: A/libc(20742): Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1)

01-10 17:00:02.010: A/libc(20160): Fatal signal 11 (SIGSEGV) at 0x00000018 (code=1)

Мое приложение использует библиотеку c ++, в которой есть NetworkThread, который получает обновления с сервера. На стороне Java есть WorkerThread, который проверяет, есть новые обновления из NetworkThread, и если есть новые обновления, он уведомляет всех слушателей. У меня также есть LocationSpotter (на стороне Java), который вызывает некоторые вызовы JNI при обновлении местоположения.

Есть ли способ отладить это или использовать адреса, которые я получил от SIGSEGV, чтобы отлаживать приложение? Также я использую общий объект JavaVM для некоторых методов для получения текущего JNIEnv (и вызывается AttachCurrentThread). Безопасна ли эта нить?

Я заметил, что по-прежнему получаю обновления от NetworkThread после того, как получил ошибку SIGSEGV (до того, как приложение действительно выйдет из строя). Это означает, что NetworkThread, вероятно, работает.

Я также заметил строку, которая может быть источником моей проблемы (в методе notifyAll), потому что последнее сообщение, напечатанное до SIGSEGV, является «notifyAll1»:

 for (unsigned i = 0; i < listeners.size(); i++) { try { __android_log_print(ANDROID_LOG_INFO, "FROM C++", "notifyAll1"); if (listeners.at(i) == NULL) __android_log_print(ANDROID_LOG_INFO, "FROM C++", "LISTENER NULL"); listeners.at(i)->update(u); // <- This line is a potential suspect __android_log_print(ANDROID_LOG_INFO, "FROM C++", "notifyAll2"); 

Логарифм:

 01-10 17:07:10.665: I/FROM C++(20449): notifyAll1 01-10 17:07:10.665: A/libc(20449): Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1) 

Затем я попытался напечатать журнал в первой строке каждого метода update слушателя, но ни один из них не был напечатан (что действительно странно, я думаю).

Любая помощь будет оценена

Большая часть времени Ошибка фатального сигнала возникает, когда вы пытаетесь получить доступ к любому объекту, который не был создан в это время. Поэтому проверьте их правильно.

Я считаю, что вы должны переписать цикл notifyAll следующим образом:

 for (unsigned i = 0; i < listeners.size(); i++) { try { __android_log_print(ANDROID_LOG_INFO, "FROM C++", "notifyAll1 i=%u", i); auto listener = *listeners.at(i); if (&listener == NULL) { __android_log_print(ANDROID_LOG_INFO, "FROM C++", "LISTENER NULL"); } else { __android_log_print(ANDROID_LOG_INFO, "FROM C++", "notifyAll2 : listener[%u] at %p", i, &listener); listener.update(u); } 
  • В вашем исходном коде проверка была только для печати в журнале, но update () все равно не удалось ( @Robin заметил это)
  • В вашем исходном коде слушатель может получить недействительный NULL между проверкой и обновлением ()
  • Даже после изменения выше, update () может произойти сбой, если объект прослушивателя, на который указывает listeners.at (i), становится недействительным.

Но возможно, что авария происходит из-за обработки исключений. Вы не обнаружили код catch (…) , поэтому я не могу говорить об этом.

Кажется очевидным

 if (listeners.at(i) == NULL) __android_log_print(ANDROID_LOG_INFO, "FROM C++", "LISTENER NULL"); listeners.at(i)->update(u); // <- This line is a potential suspect __android_log_print(ANDROID_LOG_INFO, "FROM C++", "notifyAll2"); 

должно быть

 if (listeners.at(i) == NULL) { __android_log_print(ANDROID_LOG_INFO, "FROM C++", "LISTENER NULL"); } else { listeners.at(i)->update(u); // <- This line is a potential suspect __android_log_print(ANDROID_LOG_INFO, "FROM C++", "notifyAll2"); }