• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
16 
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"
27 
28 namespace art {
29 
30 static constexpr bool kDumpHeapObjectOnSigsevg = false;
31 static constexpr bool kUseSignalHandler = false;
32 
33 struct sigaction old_action;
HandleUnexpectedSignal(int signal_number,siginfo_t * info,void * raw_context)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();
50     if (kDumpHeapObjectOnSigsevg && heap != nullptr && info != nullptr) {
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 
InitPlatformSignalHandlers()59 void Runtime::InitPlatformSignalHandlers() {
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   }
73 }
74 
75 }  // namespace art
76