1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "android_webview/common/aw_crash_handler.h"
7 #include <android/log.h>
10 #include "base/logging.h"
14 const int kExceptionSignals
[] = {
15 SIGSEGV
, SIGABRT
, SIGFPE
, SIGILL
, SIGBUS
18 struct sigaction old_handlers
[arraysize(kExceptionSignals
)];
20 bool crash_handler_registered
;
22 std::string g_crash_msg
;
24 const char* g_crash_msg_ptr
; // Avoid invoking STL magic in a signal handler.
26 void AwExceptionHandler(int sig
, siginfo_t
* info
, void* uc
) {
27 if (g_crash_msg_ptr
!= NULL
)
28 __android_log_write(ANDROID_LOG_ERROR
, "chromium", g_crash_msg_ptr
);
30 // We served our purpose. Now restore the old crash handlers. If the embedder
31 // did register a custom crash handler, it will be invoked by the kernel after
32 // this function returns. Otherwise, this will end up invoking the default
33 // signal disposition.
34 for (uint32_t i
= 0; i
< arraysize(kExceptionSignals
); ++i
) {
35 if (sigaction(kExceptionSignals
[i
], &old_handlers
[i
], NULL
) == -1) {
36 signal(kExceptionSignals
[i
], SIG_DFL
);
43 namespace android_webview
{
44 namespace crash_handler
{
46 void RegisterCrashHandler(const std::string
& version
) {
47 if (crash_handler_registered
) {
52 g_crash_msg
= "### WebView crash. " + version
;
53 g_crash_msg_ptr
= g_crash_msg
.c_str();
55 // Fail if unable to store all the old handlers.
56 for (uint32_t i
= 0; i
< arraysize(kExceptionSignals
); ++i
) {
57 if (sigaction(kExceptionSignals
[i
], NULL
, &old_handlers
[i
]) == -1) {
58 LOG(ERROR
) << "Error while trying to retrieve old handler for signal "
59 << kExceptionSignals
[i
] << ")";
65 memset(&sa
, 0, sizeof(sa
));
66 sigemptyset(&sa
.sa_mask
);
68 for (uint32_t i
= 0; i
< arraysize(kExceptionSignals
); ++i
)
69 sigaddset(&sa
.sa_mask
, kExceptionSignals
[i
]);
71 sa
.sa_sigaction
= AwExceptionHandler
;
72 sa
.sa_flags
= SA_ONSTACK
| SA_SIGINFO
;
74 for (uint32_t i
= 0; i
< arraysize(kExceptionSignals
); ++i
) {
75 if (sigaction(kExceptionSignals
[i
], &sa
, NULL
) == -1) {
76 // At this point it is impractical to back out changes, and so failure to
77 // install a signal is intentionally ignored.
78 LOG(ERROR
) << "Error while overriding handler for signal "
79 << kExceptionSignals
[i
];
83 crash_handler_registered
= true;
86 } // namespace crash_handler
87 } // namespace android_webview