blob: aed6a2b1cfdbda625e9738dce786d2b4a59fd8a0 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Elliott Hughesffe67362011-07-17 12:09:27 -070016
Mathieu Chartier15d34022014-02-26 17:16:38 -080017#include <signal.h>
18#include <string.h>
19#include <sys/utsname.h>
20#include <inttypes.h>
21
22#include "base/logging.h"
23#include "base/mutex.h"
24#include "base/stringprintf.h"
25#include "thread-inl.h"
26#include "utils.h"
Elliott Hughesffe67362011-07-17 12:09:27 -070027
28namespace art {
29
Mathieu Chartierc2f4d022014-03-03 16:11:42 -080030static constexpr bool kDumpHeapObjectOnSigsevg = false;
Mathieu Chartier28c83592014-03-04 13:40:17 -080031static constexpr bool kUseSignalHandler = false;
Mathieu Chartierc2f4d022014-03-03 16:11:42 -080032
Mathieu Chartier15d34022014-02-26 17:16:38 -080033struct sigaction old_action;
34void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context) {
Ian Rogersc7dd2952014-10-21 23:31:19 -070035 static bool handling_unexpected_signal = false;
36 if (handling_unexpected_signal) {
Andreas Gampe3fec9ac2016-09-13 10:47:28 -070037 LogHelper::LogLineLowStack(__FILE__,
38 __LINE__,
39 ::android::base::FATAL_WITHOUT_ABORT,
40 "HandleUnexpectedSignal reentered\n");
Mathieu Chartier15d34022014-02-26 17:16:38 -080041 _exit(1);
42 }
Ian Rogersc7dd2952014-10-21 23:31:19 -070043 handling_unexpected_signal = true;
Nicolas Geoffraydb978712014-12-09 13:33:38 +000044 gAborting++; // set before taking any locks
Mathieu Chartier15d34022014-02-26 17:16:38 -080045 MutexLock mu(Thread::Current(), *Locks::unexpected_signal_lock_);
46
47 Runtime* runtime = Runtime::Current();
48 if (runtime != nullptr) {
49 // Print this out first in case DumpObject faults.
Andreas Gampe3fec9ac2016-09-13 10:47:28 -070050 LOG(FATAL_WITHOUT_ABORT) << "Fault message: " << runtime->GetFaultMessage();
Mathieu Chartier15d34022014-02-26 17:16:38 -080051 gc::Heap* heap = runtime->GetHeap();
Mathieu Chartierc2f4d022014-03-03 16:11:42 -080052 if (kDumpHeapObjectOnSigsevg && heap != nullptr && info != nullptr) {
Andreas Gampe3fec9ac2016-09-13 10:47:28 -070053 LOG(FATAL_WITHOUT_ABORT) << "Dump heap object at fault address: ";
54 heap->DumpObject(LOG_STREAM(FATAL_WITHOUT_ABORT), reinterpret_cast<mirror::Object*>(info->si_addr));
Mathieu Chartier15d34022014-02-26 17:16:38 -080055 }
56 }
57 // Run the old signal handler.
58 old_action.sa_sigaction(signal_number, info, raw_context);
59}
60
Elliott Hughes457005c2012-04-16 13:54:25 -070061void Runtime::InitPlatformSignalHandlers() {
Mathieu Chartier28c83592014-03-04 13:40:17 -080062 if (kUseSignalHandler) {
63 struct sigaction action;
64 memset(&action, 0, sizeof(action));
65 sigemptyset(&action.sa_mask);
66 action.sa_sigaction = HandleUnexpectedSignal;
67 // Use the three-argument sa_sigaction handler.
68 action.sa_flags |= SA_SIGINFO;
69 // Use the alternate signal stack so we can catch stack overflows.
70 action.sa_flags |= SA_ONSTACK;
71 int rc = 0;
72 rc += sigaction(SIGSEGV, &action, &old_action);
73 CHECK_EQ(rc, 0);
74 }
Elliott Hughes457005c2012-04-16 13:54:25 -070075}
76
Elliott Hughesffe67362011-07-17 12:09:27 -070077} // namespace art