Android app restarts automatically after a crash

后端 未结 2 961
滥情空心
滥情空心 2020-12-28 15:21

My app is partly written in native app using C/C++. The problem is that whenever C/C++ part crashes for some reason the app dies and then restarts automatically. This causes

相关标签:
2条回答
  • 2020-12-28 15:59

    By default your application should not be automatically restarting. Generally one would have to register for this kind of thing, e.g. via the AlarmManager/keep alives.

    Do you have a service as part of your application?

    0 讨论(0)
  • 2020-12-28 16:12

    Try to handle crash signals (SIGSEGV etc.) and send kill to yourself in signal handler. This trick helps me.

    Example:

    #include <signal.h>
    #include <unistd.h>
    
    
    static void signal_handler(int signal, siginfo_t *info, void *reserved)
    {
      kill(getpid(),SIGKILL);
    }
    
    extern "C" jint JNI_OnLoad(JavaVM* vm, void* /*reserved*/)
    {
      struct sigaction handler;
      memset(&handler, 0, sizeof(handler));
      handler.sa_sigaction = signal_handler;
      handler.sa_flags = SA_SIGINFO;
      sigaction(SIGILL, &handler, NULL);
      sigaction(SIGABRT, &handler, NULL);
      sigaction(SIGBUS, &handler, NULL);
      sigaction(SIGFPE, &handler, NULL);
      sigaction(SIGSEGV, &handler, NULL);
      sigaction(SIGSTKFLT, &handler, NULL);
      return(JNI_VERSION_1_6);
    }
    

    UPDATE2

    if you want to see crashlog in android logcat you should use this signal handler

    static void signal_handler(int signal, siginfo_t *info, void *reserved)
    {
     struct sockaddr_un addr;
     size_t namelen;
     socklen_t alen;
     int s, err;
     char name[] = "android:debuggerd";
     namelen  = strlen(name);
    
     // Test with length +1 for the *initial* '\0'.
     if ((namelen + 1) > sizeof(addr.sun_path)) {
        errno = EINVAL;
        return;
     }
    
     /* This is used for abstract socket namespace, we need
      * an initial '\0' at the start of the Unix socket path.
      *
      * Note: The path in this case is *not* supposed to be
      * '\0'-terminated. ("man 7 unix" for the gory details.)
      */
     memset (&addr, 0, sizeof addr);
     addr.sun_family = AF_LOCAL;
     addr.sun_path[0] = 0;
     memcpy(addr.sun_path + 1, name, namelen);
    
     alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;
    
     s = socket(AF_LOCAL, SOCK_STREAM, 0);
     if(s < 0) return;
    
     RETRY_ON_EINTR(err,connect(s, (struct sockaddr *) &addr, alen));
     if (err < 0) {
        close(s);
        s = -1;
     }
    
     pid_t tid = gettid();
     if(s>=0)
     {
       /* debugger knows our pid from the credentials on the
        * local socket but we need to tell it our tid.  It
        * is paranoid and will verify that we are giving a tid
        * that's actually in our process
        */
        int  ret;
    
        RETRY_ON_EINTR(ret, write(s, &tid, sizeof(unsigned)));
        if (ret == sizeof(unsigned)) {
            /* if the write failed, there is no point to read on
             * the file descriptor. */
            RETRY_ON_EINTR(ret, read(s, &tid, 1));
            //notify_gdb_of_libraries();
        }
        close(s);
     }
    
     wait(NULL);
     kill(getpid(),SIGKILL);
    }
    

    I took it from android source (can't insert link because android.git.kernel.org is down), but I am not sure that it will work in future Android releases

    0 讨论(0)
提交回复
热议问题