[standalone] Register a segfault handler on Android as already done on Linux.
R=asiva@google.com Review-Url: https://codereview.chromium.org/2985963002 .
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<ucontext_t*>(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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user