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 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 
     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