Mobile Development 15 min read

How Android Handles ANR SIGQUIT: Signal Interception Explained

This article explains how Android captures ANR events by intercepting the SIGQUIT signal, covering the relevant signal‑handling functions (kill, signal, sigaction, sigwait, pthread_sigmask), their differences, the SignalCatcher thread implementation, and how developers can create custom SIGQUIT monitors for ANR analysis.

Alibaba Terminal Technology
Alibaba Terminal Technology
Alibaba Terminal Technology
How Android Handles ANR SIGQUIT: Signal Interception Explained

Background

ANR (Application Not Responding) frequency is an important metric for Android user experience. Since Android 6.0+, the /data/anr/traces.txt file is no longer accessible due to permission restrictions, so we need alternative ways to capture ANR, namely intercepting the SIGQUIT(3) signal.

Signal Handling Functions

To intercept SIGQUIT, we need to understand related system calls: kill, signal, sigaction, sigwait, pthread_sigmask.

kill

Header : #include <signal.h>

Function definition : int kill(pid_t pid, int signo)

Description : Sends a signal to a process; Android AMS uses Process.sendSignal(pid, signal), which ultimately calls kill.

signal

Header : #include <signal.h>

Function definition : sig_t signal(int signum, sig_t handler)

Description : Sets the handler for a given signal. If handler is SIG_DFL, the default action is used; SIG_IGN ignores the signal; otherwise the specified handler is called. Valid signals include SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM, etc.

sigaction

Header : #include <signal.h>

Function definition : int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)

Description : Configures the handling of a signal. The struct sigaction is defined as:

struct sigaction {
    void (*sa_handler)(int);
    void (*sa_sigaction)(int, siginfo_t *, void *);
    sigset_t sa_mask;
    int sa_flags;
    void (*sa_restorer)(void);
};

sa_handler is equivalent to the handler argument of signal(). sa_sigaction is used when SA_SIGINFO flag is set, allowing additional information. sa_mask specifies signals to block during handling. sa_flags can include SA_RESETHAND, SA_RESTART, SA_NODEFER, etc.

sigwait

Header : #include <signal.h>

Function definition : int sigwait(const sigset_t *set, int *sig)

Description : Waits synchronously for a signal from the specified set, returning the signal number. It is useful for dedicated signal‑handling threads. Recommendations: do not block SIGSTOP or SIGKILL; do not block SIGFPE, SIGILL, SIGSEGV, SIGBUS; ensure the signal set is blocked in all threads before calling sigwait; use kill() to send signals to the whole process, not pthread_kill().

pthread_sigmask

Header : #include <signal.h>

Function definition : int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)

Description : Sets the calling thread’s signal mask, allowing selective blocking or unblocking of signals.

Differences Between signal, sigaction, and sigwait

signal is a legacy wrapper whose functionality is subsumed by sigaction; both ultimately invoke the rt_sigaction system call. sigaction provides more control and is the preferred API. sigwait differs by delivering signals synchronously to a waiting thread; if a signal is also caught by sigaction, the kernel decides whether to wake the waiting thread or invoke the handler, but not both.

Android ANR SIGQUIT Handling

When an ANR occurs, Android’s ActivityManagerService forks a process via Zygote, which creates a dedicated “SignalCatcher” thread. AMS sends SIGQUIT(3) to the target process; the SignalCatcher thread waits for SIGQUIT (and SIGUSR1) using sigwait and dumps thread stacks to /data/anr/traces.txt.

SignalCatcher Thread Creation

The SignalCatcher thread is created during Runtime initialization. Runtime::BlockSignals adds SIGPIPE, SIGQUIT, and SIGUSR1 to a SignalSet and blocks them using pthread_sigmask, ensuring they are handled only by the SignalCatcher.

SignalCatcher Run Loop

void* SignalCatcher::Run(void* arg) {
    SignalSet signals;
    signals.Add(SIGQUIT);
    signals.Add(SIGUSR1);
    while (true) {
        int signal_number = signal_catcher->WaitForSignal(self, signals);
        if (signal_catcher->ShouldHalt()) {
            runtime->DetachCurrentThread();
            return nullptr;
        }
        switch (signal_number) {
            case SIGQUIT:
                signal_catcher->HandleSigQuit();
                break;
            case SIGUSR1:
                signal_catcher->HandleSigUsr1();
                break;
            default:
                LOG(ERROR) << "Unexpected signal " << signal_number;
                break;
        }
    }
}

This design guarantees that SIGQUIT and SIGUSR1 are processed only by the SignalCatcher, preventing other threads from interfering and preserving stack integrity.

Custom SIGQUIT Interception

Developers can implement their own SIGQUIT monitor by unblocking SIGQUIT in the main thread with pthread_sigmask(SIG_UNBLOCK, …) and installing a sigaction handler with SA_ONSTACK | SA_SIGINFO. Example code:

void RunSigQuitMonitor() {
    sigset_t set, old_set;
    sigemptyset(&set);
    sigaddset(&set, SIGQUIT);
    int r = pthread_sigmask(SIG_UNBLOCK, &set, &old_set);
    if (r != 0) return;
    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sigemptyset(&sa.sa_mask);
    sigaddset(&sa.sa_mask, SIGQUIT);
    sa.sa_sigaction = SignalHandler;
    sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
    if (sigaction(SIGQUIT, &sa, &old_handler) != 0) {
        pthread_sigmask(SIG_SETMASK, &old_set, NULL);
    }
}

By doing so, the custom handler can capture ANR information without interfering with the system’s SignalCatcher.

Conclusion

Understanding Android’s SIGQUIT handling enables developers to quickly implement custom ANR monitoring solutions.

References

https://baike.baidu.com/item/kill/2680256

https://baike.baidu.com/item/signal.h/7316160?fr=aladdin

https://baike.baidu.com/item/sigaction

https://baike.baidu.com/item/sigwait

https://baike.baidu.com/item/pthread_sigmask

Source analysis of signal vs sigaction: https://blog.csdn.net/wangzuxi/article/details/44814825

Libev source analysis 06: https://www.cnblogs.com/gqtcgq/p/7247097.html

Android application process creation: https://www.jianshu.com/p/b4cb8608d7f

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

AndroidCANRsignal handlingSIGQUIT
Alibaba Terminal Technology
Written by

Alibaba Terminal Technology

Official public account of Alibaba Terminal

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.