Android - ANR causing process to be killed instead of a Dialog

    Recently, i came across few devices which wouldn't display a ANR dialog ( to give user a chance to wait) instead would just terminate the application process with a dialog saying "Unfortunately, application has stopped". This is the same dialog display for fatal exceptions (both java and native). So why doesn't Android display the usual dialog for an ANR?

   How about a bad behavior application to trigger an ANR and test it out on an emulator based on stock AOSP, but in this case no dialog was displayed instead the application window would be closed and the logs would indicate that the process was killed after user request. Turns out, this is a feature where in dialogs aren't shown in certain configurations,

    /**
     * Decide based on the configuration whether we should shouw the ANR,
     * crash, etc dialogs.  The idea is that if there is no affordnace to
     * press the on-screen buttons, we shouldn't show the dialog.
     *
     * A thought: SystemUI might also want to get told about this, the Power
     * dialog / global actions also might want different behaviors.
     */
    private static final boolean shouldShowDialogs(Configuration config) {
        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
    }

   Now the same application behaves differently in Oneplus one and Nexus 4 (running CM 11). As suspected, they just display a dialog indicating that the application has stopped unexpectedly. A look at the log indicates a forked framework change causing this,

11-28 10:37:53.277   803   855 I Process : Sending signal. PID: 19749 SIG: 3
11-28 10:37:53.277 19749 19754 I dalvikvm: threadid=3: reacting to signal 3
11-28 10:37:53.297 19749 19754 I dalvikvm: Wrote stack traces to '/data/anr/traces.txt'
11-28 10:37:56.457   803   855 I Process : Sending signal. PID: 19749 SIG: 6

11-28 10:37:56.577   222   222 I DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** ***
11-28 10:37:56.577   222   222 I DEBUG   : Build fingerprint: 'oneplus/bacon/A0001:4.4.4/KTU84Q/XNPH44S:user/release-keys'
11-28 10:37:56.577   222   222 I DEBUG   : Revision: '0'
11-28 10:37:56.577   222   222 I DEBUG   : pid: 19749, tid: 19749, name: anrapp1  >>>
11-28 10:37:56.577   222   222 I DEBUG   : signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------


   These custom ROMs similar to stock AOSP sends a SIGNAL_QUIT to the application process to generate its stack trace and update traces file. But then another signal SIBABRT is sent by the framework and this is what causes a signal with SI_TKILL code to be sent to the process and for it to be killed. This is probably being done to generate the process's native stack traces via tombstone.

11-28 10:37:56.457   803 19857 E ActivityManager: Error reading /data/anr/traces.txt
11-28 10:37:56.457   803 19857 E ActivityManager: java.io.FileNotFoundException: /data/anr/traces.txt: open failed: ENOENT (No such file or directory)
11-28 10:37:56.457   803 19857 E ActivityManager:       at libcore.io.IoBridge.open(IoBridge.java:409)
11-28 10:37:56.457   803 19857 E ActivityManager:       at java.io.FileInputStream.<init>(FileInputStream.java:78)
11-28 10:37:56.457   803 19857 E ActivityManager:       at android.os.FileUtils.readTextFile(FileUtils.java:236)
11-28 10:37:56.457   803 19857 E ActivityManager:       at com.android.server.am.ActivityManagerService$19.run(ActivityManagerService.java:10152)
11-28 10:37:56.457   803 19857 E ActivityManager: Caused by: libcore.io.ErrnoException: open failed: ENOENT (No such file or directory)
11-28 10:37:56.457   803 19857 E ActivityManager:       at libcore.io.Posix.open(Native Method)
11-28 10:37:56.457   803 19857 E ActivityManager:       at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
11-28 10:37:56.457   803 19857 E ActivityManager:       at libcore.io.IoBridge.open(IoBridge.java:393)
11-28 10:37:56.457   803 19857 E ActivityManager:       ... 3 more


  Besides, the dropbox thread has a 100% failure when it tries to read the traces file. The generic traces file is probably being renamed to reflect the application name but the dropbox thread tries to read the generic file (traces.txt) and fails with FileNotFound error.

 Update: Turns out this isn't a change specific to CM instead is a change distributed by Qualcomm via Code Aurora. It looks like Google isn't using this patch and this is one of the few reasons why Nexus program should stay alive for the rest of the folks in Android ecosystem to use a benchmark at all times.

commit 47aa5dedc57dd6e5690811622ffcbfccecb8ecb6
Author: xxxxxxxx xxxxxxx <xxxxx@codeaurora.org>
Date:   Fri Jan 13 18:22:40 2012 -0800

    frameworks/base: creating sperate files for ANRs traces
    
    If an ANR comes just after the framework reboot, the traces for the
    framework reboot will get over-written with the ANR traces. So, We
    are missing the traces for the framework reboot which makes debugging
    the framework reboot difficult.
    
    Even for multiple ANRs in different apps, we will get the traces for
    the last ANR.
    
    Most of the time traces show that the call is stuck in some native call
    and we do not have any info about the native call stack becuase we do
    not collect the tombstones for teh ANR.
    
    This patch will create one trace file for each application in case of ANR
    and the filename would be traces_<app_name>.txt and the traces for
    framework reboot will be stored in traces.txt
    

    Change-Id: I5b78ce62b26f25d3dc14097e2988ba12c2d77826 


No comments: