TestMozCrash.cpp (1992B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "mozilla/Assertions.h" 8 9 #include <unistd.h> 10 #include <signal.h> 11 #include <string.h> 12 #include <sys/wait.h> 13 14 void handler(int signum) { exit(gMozCrashReason == nullptr ? 1 : 0); } 15 16 int main(int argc, char** argv) { 17 // libxul starts with gMozCrashReason set to nullptr. 18 if (gMozCrashReason) { 19 fprintf(stderr, "gMozCrashReason unexpectedly starts set to %s.\n", 20 gMozCrashReason); 21 return 1; 22 } 23 24 // The strategy here is simple: fork, trigger an abort from the child and 25 // observe behavior. 26 27 pid_t child = fork(); 28 if (child == 0) { 29 struct sigaction sa; 30 memset(&sa, 0, sizeof(sa)); 31 sa.sa_handler = handler; 32 sigemptyset(&sa.sa_mask); 33 for (int i = 1; i < 10; ++i) 34 if (sigaction(SIGSEGV, &sa, nullptr) == -1) { 35 perror(argv[0]); 36 return 1; 37 } 38 // Trigger an actual verbose crash. This calls a function within libxul to 39 // make sure it produces verbose crash. 40 mozilla::detail::InvalidArrayIndex_CRASH(2, 2); 41 } else { 42 // Recover exit status from child, check it's an actual crash and that 43 // gMozCrashReason is set. 44 int waitres; 45 if (wait(&waitres) >= 0) { 46 if (WIFEXITED(waitres) && WEXITSTATUS(waitres) == 0) return 0; 47 fprintf(stderr, 48 "Crash didn't happen in the expected way.\n" 49 "normal exit: %d.\n" 50 "signaled exit: %d.\n" 51 "exit status: %d.\n" 52 "signal used: %d.\n", 53 WIFEXITED(waitres), WIFSIGNALED(waitres), 54 (WIFEXITED(waitres) ? WEXITSTATUS(waitres) : -1), 55 (WIFSIGNALED(waitres) ? WTERMSIG(waitres) : -1)); 56 return 1; 57 } 58 } 59 }