Elliott Hughes | 2faa5f1 | 2012-01-30 14:42:07 -0800 | [diff] [blame] | 1 | /* |
| 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 Hughes | ffe6736 | 2011-07-17 12:09:27 -0700 | [diff] [blame] | 16 | |
Mathieu Chartier | 15d3402 | 2014-02-26 17:16:38 -0800 | [diff] [blame] | 17 | #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 Hughes | ffe6736 | 2011-07-17 12:09:27 -0700 | [diff] [blame] | 27 | |
| 28 | namespace art { |
| 29 | |
Mathieu Chartier | c2f4d02 | 2014-03-03 16:11:42 -0800 | [diff] [blame] | 30 | static constexpr bool kDumpHeapObjectOnSigsevg = false; |
Mathieu Chartier | 28c8359 | 2014-03-04 13:40:17 -0800 | [diff] [blame] | 31 | static constexpr bool kUseSignalHandler = false; |
Mathieu Chartier | c2f4d02 | 2014-03-03 16:11:42 -0800 | [diff] [blame] | 32 | |
Mathieu Chartier | 15d3402 | 2014-02-26 17:16:38 -0800 | [diff] [blame] | 33 | struct sigaction old_action; |
| 34 | void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context) { |
| 35 | static bool handlingUnexpectedSignal = false; |
| 36 | if (handlingUnexpectedSignal) { |
| 37 | LogMessageData data(__FILE__, __LINE__, INTERNAL_FATAL, -1); |
| 38 | LogMessage::LogLine(data, "HandleUnexpectedSignal reentered\n"); |
| 39 | _exit(1); |
| 40 | } |
| 41 | handlingUnexpectedSignal = true; |
| 42 | gAborting++; // set before taking any locks |
| 43 | MutexLock mu(Thread::Current(), *Locks::unexpected_signal_lock_); |
| 44 | |
| 45 | Runtime* runtime = Runtime::Current(); |
| 46 | if (runtime != nullptr) { |
| 47 | // Print this out first in case DumpObject faults. |
| 48 | LOG(INTERNAL_FATAL) << "Fault message: " << runtime->GetFaultMessage(); |
| 49 | gc::Heap* heap = runtime->GetHeap(); |
Mathieu Chartier | c2f4d02 | 2014-03-03 16:11:42 -0800 | [diff] [blame] | 50 | if (kDumpHeapObjectOnSigsevg && heap != nullptr && info != nullptr) { |
Mathieu Chartier | 15d3402 | 2014-02-26 17:16:38 -0800 | [diff] [blame] | 51 | LOG(INTERNAL_FATAL) << "Dump heap object at fault address: "; |
| 52 | heap->DumpObject(LOG(INTERNAL_FATAL), reinterpret_cast<mirror::Object*>(info->si_addr)); |
| 53 | } |
| 54 | } |
| 55 | // Run the old signal handler. |
| 56 | old_action.sa_sigaction(signal_number, info, raw_context); |
| 57 | } |
| 58 | |
Elliott Hughes | 457005c | 2012-04-16 13:54:25 -0700 | [diff] [blame] | 59 | void Runtime::InitPlatformSignalHandlers() { |
Mathieu Chartier | 28c8359 | 2014-03-04 13:40:17 -0800 | [diff] [blame] | 60 | if (kUseSignalHandler) { |
| 61 | struct sigaction action; |
| 62 | memset(&action, 0, sizeof(action)); |
| 63 | sigemptyset(&action.sa_mask); |
| 64 | action.sa_sigaction = HandleUnexpectedSignal; |
| 65 | // Use the three-argument sa_sigaction handler. |
| 66 | action.sa_flags |= SA_SIGINFO; |
| 67 | // Use the alternate signal stack so we can catch stack overflows. |
| 68 | action.sa_flags |= SA_ONSTACK; |
| 69 | int rc = 0; |
| 70 | rc += sigaction(SIGSEGV, &action, &old_action); |
| 71 | CHECK_EQ(rc, 0); |
| 72 | } |
Elliott Hughes | 457005c | 2012-04-16 13:54:25 -0700 | [diff] [blame] | 73 | } |
| 74 | |
Elliott Hughes | ffe6736 | 2011-07-17 12:09:27 -0700 | [diff] [blame] | 75 | } // namespace art |