Fatal signal 11 (SIGSEGV)

5

I have a weird error and I can't find where it comes from. The only thing that appears in the logcat is :

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

I don't get this error right away when I run my app, I get it after a random amount of time (something between 1 min to 5 min). I'm unable to reproduce this error, it seems random and since there are no other informations it's hard to debug. I tried to add some log informations to my library but I still can't say where the crash occurs.

I ran the same app x times and I got different SIGSEGV address (sometimes it was the same address as before :

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)

My app is using a c++ library that has a NetworkThread that receives updates from a server. On the Java side there's a WorkerThread that check is there's new updates from the NetworkThread and if there's new updates it notifies all the listeners. I also have a LocationSpotter (on the Java side) that makes some JNI calls when the location is updated.

Is there a way to debug this or to use the addresses I got from the SIGSEGV to debug the app ? Also I'm using a shared JavaVM object for some methods to retrieve the current JNIEnv (and call AttachCurrentThread). Is that thread safe ?

I noticed that I still receive updates from the NetworkThread after I got the SIGSEGV error (before the app actually crashes). That means the NetworkThread is probably working.

I also noticed a line that could be the source of my problem (in the notifyAll method) because the last message printed before SIGSEGV is "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");

The logcat :

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)

I tried then to print a log in the first line of each listener's update method but none of them is printed (which is really weird I think).

Any help will be greatly appreciated

android
android-ndk
java-native-interface
asked on Stack Overflow Jan 10, 2013 by Fr4nz

3 Answers

5

Most of time Fatal signal error occur when you are trying to access any object which is not created at that time. So check them properly.

answered on Stack Overflow Jul 25, 2013 by Singhak
1

I believe that you should rewrite the notifyAll loop like this:

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);
    }
  • in your original code, the check was only printing to log, but update() would still fail (@Robin noticed this)
  • in your original code, a listener could get invalidated NULL between check and update()
  • even after the change above, update() could crash if the listener object pointed to by listeners.at(i) becomes invalid.

But it's possible that the crash happens because of exception handling. You did not reveal the catch(...) code, so I cannot speak about this.

answered on Stack Overflow Dec 29, 2013 by Alex Cohn • edited May 23, 2017 by Community
0

It seems to be obvious

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");

should be

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");
}
answered on Stack Overflow Nov 27, 2013 by Robin

User contributions licensed under CC BY-SA 3.0