diff --git a/runtime/bin/platform_android.cc b/runtime/bin/platform_android.cc index 87ee9aa715f..2ea90778ce2 100644 --- a/runtime/bin/platform_android.cc +++ b/runtime/bin/platform_android.cc @@ -22,6 +22,11 @@ char* Platform::resolved_executable_name_ = NULL; int Platform::script_index_ = 1; char** Platform::argv_ = NULL; +static void segv_handler(int signal, siginfo_t* siginfo, void* context) { + Dart_DumpNativeStackTrace(context); + abort(); +} + bool Platform::Initialize() { // Turn off the signal handler for SIGPIPE as it causes the process // to terminate on writing to a closed pipe. Without the signal @@ -33,6 +38,30 @@ bool Platform::Initialize() { perror("Setting signal handler failed"); return false; } + + act.sa_flags = SA_SIGINFO; + act.sa_sigaction = &segv_handler; + if (sigemptyset(&act.sa_mask) != 0) { + perror("sigemptyset() failed."); + return false; + } + if (sigaddset(&act.sa_mask, SIGPROF) != 0) { + perror("sigaddset() failed"); + return false; + } + if (sigaction(SIGSEGV, &act, NULL) != 0) { + perror("sigaction() failed."); + return false; + } + if (sigaction(SIGBUS, &act, NULL) != 0) { + perror("sigaction() failed."); + return false; + } + if (sigaction(SIGTRAP, &act, NULL) != 0) { + perror("sigaction() failed."); + return false; + } + return true; } diff --git a/runtime/bin/platform_linux.cc b/runtime/bin/platform_linux.cc index ce89c19688c..13297fa7e94 100644 --- a/runtime/bin/platform_linux.cc +++ b/runtime/bin/platform_linux.cc @@ -53,6 +53,10 @@ bool Platform::Initialize() { perror("sigaction() failed."); return false; } + if (sigaction(SIGBUS, &act, NULL) != 0) { + perror("sigaction() failed."); + return false; + } if (sigaction(SIGTRAP, &act, NULL) != 0) { perror("sigaction() failed."); return false; diff --git a/runtime/bin/platform_macos.cc b/runtime/bin/platform_macos.cc index 2745df6490e..dda9ab8b8c3 100644 --- a/runtime/bin/platform_macos.cc +++ b/runtime/bin/platform_macos.cc @@ -60,6 +60,10 @@ bool Platform::Initialize() { perror("sigaction() failed."); return false; } + if (sigaction(SIGBUS, &act, NULL) != 0) { + perror("sigaction() failed."); + return false; + } if (sigaction(SIGTRAP, &act, NULL) != 0) { perror("sigaction() failed."); return false; diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc index 3059a2040df..a99b48ee84b 100644 --- a/runtime/vm/profiler.cc +++ b/runtime/vm/profiler.cc @@ -1035,7 +1035,7 @@ static bool CheckIsolate(Isolate* isolate) { } void Profiler::DumpStackTrace(void* context) { -#if defined(HOST_OS_LINUX) || defined(HOST_OS_MACOS) +#if defined(HOST_OS_LINUX) || defined(HOST_OS_MACOS) || defined(HOST_OS_ANDROID) ucontext_t* ucontext = reinterpret_cast(context); mcontext_t mcontext = ucontext->uc_mcontext; uword pc = SignalHandler::GetProgramCounter(mcontext); @@ -1085,12 +1085,14 @@ void Profiler::DumpStackTrace(uword sp, uword fp, uword pc, bool for_crash) { Thread* thread = Thread::Current(); if (thread == NULL) { + OS::PrintErr("Stack dump aborted because no current Dart thread.\n"); return; } OSThread* os_thread = thread->os_thread(); ASSERT(os_thread != NULL); Isolate* isolate = thread->isolate(); if (!CheckIsolate(isolate)) { + OS::PrintErr("Stack dump aborted because CheckIsolate failed.\n"); return; } @@ -1101,7 +1103,7 @@ void Profiler::DumpStackTrace(uword sp, uword fp, uword pc, bool for_crash) { uword stack_upper = 0; if (!InitialRegisterCheck(pc, fp, sp)) { - OS::PrintErr("Stack dump aborted because InitialRegisterCheck.\n"); + OS::PrintErr("Stack dump aborted because InitialRegisterCheck failed.\n"); return; } @@ -1109,7 +1111,7 @@ void Profiler::DumpStackTrace(uword sp, uword fp, uword pc, bool for_crash) { &stack_upper, /*get_os_thread_bounds=*/true)) { OS::PrintErr( - "Stack dump aborted because GetAndValidateThreadStackBounds.\n"); + "Stack dump aborted because GetAndValidateThreadStackBounds failed.\n"); return; }