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

View File

@ -1,7 +1,12 @@
/*
* Copyright 2005-2008, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#undef NDEBUG
#include <assert.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -18,6 +23,7 @@ static const char *kUsage =
"Options:\n"
" -d - call disable_debugger() first\n"
" -h, --help - print this info text\n"
" --signal - crash in a signal handler\n"
" --thread - crash in a separate thread\n"
"\n"
"Modes:\n"
@ -26,7 +32,7 @@ static const char *kUsage =
" segv2 - strcmp() using a 0x1 pointer\n"
" div - executes a division by zero\n"
" debugger - invokes debugger()\n"
" assert - failed assert(), which should invoke the "
" assert - failed assert(), which should invoke the\n"
" debugger\n"
"\n"
"[x86 specific]\n"
@ -113,6 +119,24 @@ crash_protection()
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*
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
crashing_thread(void* data)
{
crash_function_t* doCrash = (crash_function_t*)data;
snooze(100000);
doCrash();
do_crash();
return 0;
}
@ -151,8 +192,6 @@ crashing_thread(void* data)
int
main(int argc, const char* const* argv)
{
bool inThread = false;
bool disableDebugger = false;
const char* mode = "segv";
// parse args
@ -164,9 +203,11 @@ main(int argc, const char* const* argv)
if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
print_usage_and_exit(false);
} 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) {
inThread = true;
sOptions.inThread = true;
} else {
fprintf(stderr, "Invalid option \"%s\"\n", arg);
print_usage_and_exit(true);
@ -176,18 +217,18 @@ main(int argc, const char* const* argv)
}
}
crash_function_t* doCrash = get_crash_function(mode);
if (doCrash == NULL) {
sOptions.function = get_crash_function(mode);
if (sOptions.function == NULL) {
fprintf(stderr, "Invalid mode \"%s\"\n", mode);
print_usage_and_exit(true);
}
if (disableDebugger)
if (sOptions.disableDebugger)
disable_debugger(true);
if (inThread) {
if (sOptions.inThread) {
thread_id thread = spawn_thread(crashing_thread, "crashing thread",
B_NORMAL_PRIORITY, (void*)doCrash);
B_NORMAL_PRIORITY, NULL);
if (thread < 0) {
fprintf(stderr, "Error: Failed to spawn thread: %s\n",
strerror(thread));
@ -199,7 +240,7 @@ main(int argc, const char* const* argv)
while (wait_for_thread(thread, &result) == B_INTERRUPTED) {
}
} else {
doCrash();
do_crash();
}
return 0;