Added "--signal" option that performs the crash in a signal handler.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27934 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2008-10-09 00:47:36 +00:00
parent 2bd9dd82a6
commit c28bcbdf58
+54 -13
View File
@@ -1,7 +1,12 @@
/*
* Copyright 2005-2008, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#undef NDEBUG #undef NDEBUG
#include <assert.h> #include <assert.h>
#include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -18,6 +23,7 @@ static const char *kUsage =
"Options:\n" "Options:\n"
" -d - call disable_debugger() first\n" " -d - call disable_debugger() first\n"
" -h, --help - print this info text\n" " -h, --help - print this info text\n"
" --signal - crash in a signal handler\n"
" --thread - crash in a separate thread\n" " --thread - crash in a separate thread\n"
"\n" "\n"
"Modes:\n" "Modes:\n"
@@ -26,7 +32,7 @@ static const char *kUsage =
" segv2 - strcmp() using a 0x1 pointer\n" " segv2 - strcmp() using a 0x1 pointer\n"
" div - executes a division by zero\n" " div - executes a division by zero\n"
" debugger - invokes debugger()\n" " debugger - invokes debugger()\n"
" assert - failed assert(), which should invoke the " " assert - failed assert(), which should invoke the\n"
" debugger\n" " debugger\n"
"\n" "\n"
"[x86 specific]\n" "[x86 specific]\n"
@@ -113,6 +119,24 @@ crash_protection()
typedef int crash_function_t(); typedef int crash_function_t();
struct Options {
Options()
:
inThread(false),
inSignalHandler(false),
disableDebugger(false)
{
}
crash_function_t* function;
bool inThread;
bool inSignalHandler;
bool disableDebugger;
};
static Options sOptions;
static crash_function_t* static crash_function_t*
get_crash_function(const char* mode) get_crash_function(const char* mode)
{ {
@@ -138,12 +162,29 @@ get_crash_function(const char* mode)
} }
static void
signal_handler(int signal)
{
sOptions.function();
}
static void
do_crash()
{
if (sOptions.inSignalHandler) {
signal(SIGUSR1, &signal_handler);
send_signal(find_thread(NULL), SIGUSR1);
} else
sOptions.function();
}
static status_t static status_t
crashing_thread(void* data) crashing_thread(void* data)
{ {
crash_function_t* doCrash = (crash_function_t*)data;
snooze(100000); snooze(100000);
doCrash(); do_crash();
return 0; return 0;
} }
@@ -151,8 +192,6 @@ crashing_thread(void* data)
int int
main(int argc, const char* const* argv) main(int argc, const char* const* argv)
{ {
bool inThread = false;
bool disableDebugger = false;
const char* mode = "segv"; const char* mode = "segv";
// parse args // parse args
@@ -164,9 +203,11 @@ main(int argc, const char* const* argv)
if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) { if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
print_usage_and_exit(false); print_usage_and_exit(false);
} else if (strcmp(arg, "-d") == 0) { } else if (strcmp(arg, "-d") == 0) {
disableDebugger = true; sOptions.disableDebugger = true;
} else if (strcmp(arg, "--signal") == 0) {
sOptions.inSignalHandler = true;
} else if (strcmp(arg, "--thread") == 0) { } else if (strcmp(arg, "--thread") == 0) {
inThread = true; sOptions.inThread = true;
} else { } else {
fprintf(stderr, "Invalid option \"%s\"\n", arg); fprintf(stderr, "Invalid option \"%s\"\n", arg);
print_usage_and_exit(true); print_usage_and_exit(true);
@@ -176,18 +217,18 @@ main(int argc, const char* const* argv)
} }
} }
crash_function_t* doCrash = get_crash_function(mode); sOptions.function = get_crash_function(mode);
if (doCrash == NULL) { if (sOptions.function == NULL) {
fprintf(stderr, "Invalid mode \"%s\"\n", mode); fprintf(stderr, "Invalid mode \"%s\"\n", mode);
print_usage_and_exit(true); print_usage_and_exit(true);
} }
if (disableDebugger) if (sOptions.disableDebugger)
disable_debugger(true); disable_debugger(true);
if (inThread) { if (sOptions.inThread) {
thread_id thread = spawn_thread(crashing_thread, "crashing thread", thread_id thread = spawn_thread(crashing_thread, "crashing thread",
B_NORMAL_PRIORITY, (void*)doCrash); B_NORMAL_PRIORITY, NULL);
if (thread < 0) { if (thread < 0) {
fprintf(stderr, "Error: Failed to spawn thread: %s\n", fprintf(stderr, "Error: Failed to spawn thread: %s\n",
strerror(thread)); strerror(thread));
@@ -199,7 +240,7 @@ main(int argc, const char* const* argv)
while (wait_for_thread(thread, &result) == B_INTERRUPTED) { while (wait_for_thread(thread, &result) == B_INTERRUPTED) {
} }
} else { } else {
doCrash(); do_crash();
} }
return 0; return 0;