diff options
Diffstat (limited to 'debuggerd/handler/debuggerd_handler.cpp')
-rw-r--r-- | debuggerd/handler/debuggerd_handler.cpp | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp index c09c2f31f..cf24d5767 100644 --- a/debuggerd/handler/debuggerd_handler.cpp +++ b/debuggerd/handler/debuggerd_handler.cpp @@ -62,6 +62,19 @@ #define CRASH_DUMP_PATH "/system/bin/" CRASH_DUMP_NAME +class ErrnoRestorer { + public: + ErrnoRestorer() : saved_errno_(errno) { + } + + ~ErrnoRestorer() { + errno = saved_errno_; + } + + private: + int saved_errno_; +}; + extern "C" void debuggerd_fallback_handler(siginfo_t*, ucontext_t*, void*); static debuggerd_callbacks_t g_callbacks; @@ -328,6 +341,10 @@ static void resend_signal(siginfo_t* info, bool crash_dump_started) { // Handler that does crash dumping by forking and doing the processing in the child. // Do this by ptracing the relevant thread, and then execing debuggerd to do the actual dump. static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void* context) { + // Make sure we don't change the value of errno, in case a signal comes in between the process + // making a syscall and checking errno. + ErrnoRestorer restorer; + // It's possible somebody cleared the SA_SIGINFO flag, which would mean // our "info" arg holds an undefined value. if (!have_siginfo(signal_number)) { |