Home | History | Annotate | Download | only in runtime
      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;
     34 void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context) {
     35   static bool handling_unexpected_signal = false;
     36   if (handling_unexpected_signal) {
     37     LogMessage::LogLine(__FILE__, __LINE__, INTERNAL_FATAL, "HandleUnexpectedSignal reentered\n");
     38     _exit(1);
     39   }
     40   handling_unexpected_signal = true;
     41   gAborting++;  // set before taking any locks
     42   MutexLock mu(Thread::Current(), *Locks::unexpected_signal_lock_);
     43 
     44   Runtime* runtime = Runtime::Current();
     45   if (runtime != nullptr) {
     46     // Print this out first in case DumpObject faults.
     47     LOG(INTERNAL_FATAL) << "Fault message: " << runtime->GetFaultMessage();
     48     gc::Heap* heap = runtime->GetHeap();
     49     if (kDumpHeapObjectOnSigsevg && heap != nullptr && info != nullptr) {
     50       LOG(INTERNAL_FATAL) << "Dump heap object at fault address: ";
     51       heap->DumpObject(LOG(INTERNAL_FATAL), reinterpret_cast<mirror::Object*>(info->si_addr));
     52     }
     53   }
     54   // Run the old signal handler.
     55   old_action.sa_sigaction(signal_number, info, raw_context);
     56 }
     57 
     58 void Runtime::InitPlatformSignalHandlers() {
     59   if (kUseSignalHandler) {
     60     struct sigaction action;
     61     memset(&action, 0, sizeof(action));
     62     sigemptyset(&action.sa_mask);
     63     action.sa_sigaction = HandleUnexpectedSignal;
     64     // Use the three-argument sa_sigaction handler.
     65     action.sa_flags |= SA_SIGINFO;
     66     // Use the alternate signal stack so we can catch stack overflows.
     67     action.sa_flags |= SA_ONSTACK;
     68     int rc = 0;
     69     rc += sigaction(SIGSEGV, &action, &old_action);
     70     CHECK_EQ(rc, 0);
     71   }
     72 }
     73 
     74 }  // namespace art
     75