2 * Copyright 2005-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
19 extern const char *__progname
;
22 static const char *kUsage
=
23 "%s <options> [ <mode> ]\n"
24 "Crashes in more or less inovative ways.\n"
27 " -d - call disable_debugger() first\n"
28 " -f, --fork - fork() and continue in the child\n"
29 " -h, --help - print this info text\n"
30 " --multi - crash in multiple threads\n"
31 " --signal - crash in a signal handler\n"
32 " --thread - crash in a separate thread\n"
36 " segv - dereferences a null pointer (default)\n"
37 " segv2 - strcmp() using a 0x1 pointer\n"
38 " div - executes a division by zero\n"
39 " debugger - invokes debugger()\n"
40 " assert - failed assert(), which should invoke the\n"
44 " int3 - executes the int3 (breakpoint) instruction\n"
45 " protection - executes an instruction that causes a general\n"
46 " protection exception\n";
49 const char *kAppName
= __progname
;
52 print_usage(bool error
)
54 fprintf(error
? stderr
: stdout
, kUsage
, kAppName
);
59 print_usage_and_exit(bool error
)
77 const char *str
= (const char*)0x1;
78 return strcmp(str
, "Test");
92 debugger("crashing_app() invoked debugger()");
117 asm("movl %0, %%dr7" : : "r"(0));
124 typedef int crash_function_t();
131 multipleThreads(false),
132 inSignalHandler(false),
133 disableDebugger(false),
138 crash_function_t
* function
;
140 bool multipleThreads
;
141 bool inSignalHandler
;
142 bool disableDebugger
;
146 static Options sOptions
;
149 static crash_function_t
*
150 get_crash_function(const char* mode
)
152 if (strcmp(mode
, "segv") == 0) {
154 } else if (strcmp(mode
, "segv2") == 0) {
156 } else if (strcmp(mode
, "div") == 0) {
157 return (crash_function_t
*)crash_div
;
158 } else if (strcmp(mode
, "debugger") == 0) {
159 return crash_debugger
;
160 } else if (strcmp(mode
, "assert") == 0) {
163 } else if (strcmp(mode
, "int3") == 0) {
165 } else if (strcmp(mode
, "protection") == 0) {
166 return crash_protection
;
175 signal_handler(int signal
)
184 if (sOptions
.inSignalHandler
) {
185 signal(SIGUSR1
, &signal_handler
);
186 send_signal(find_thread(NULL
), SIGUSR1
);
193 crashing_thread(void* data
)
202 main(int argc
, const char* const* argv
)
204 const char* mode
= "segv";
208 while (argi
< argc
) {
209 const char *arg
= argv
[argi
++];
212 if (strcmp(arg
, "-h") == 0 || strcmp(arg
, "--help") == 0) {
213 print_usage_and_exit(false);
214 } else if (strcmp(arg
, "-d") == 0) {
215 sOptions
.disableDebugger
= true;
216 } else if (strcmp(arg
, "-f") == 0 || strcmp(arg
, "--fork") == 0) {
217 sOptions
.fork
= true;
218 } else if (strcmp(arg
, "--multi") == 0) {
219 sOptions
.inThread
= true;
220 sOptions
.multipleThreads
= true;
221 } else if (strcmp(arg
, "--signal") == 0) {
222 sOptions
.inSignalHandler
= true;
223 } else if (strcmp(arg
, "--thread") == 0) {
224 sOptions
.inThread
= true;
226 fprintf(stderr
, "Invalid option \"%s\"\n", arg
);
227 print_usage_and_exit(true);
234 sOptions
.function
= get_crash_function(mode
);
235 if (sOptions
.function
== NULL
) {
236 fprintf(stderr
, "Invalid mode \"%s\"\n", mode
);
237 print_usage_and_exit(true);
240 if (sOptions
.disableDebugger
)
241 disable_debugger(true);
244 pid_t child
= fork();
246 fprintf(stderr
, "fork() failed: %s\n", strerror(errno
));
255 // the child continues...
258 if (sOptions
.inThread
) {
259 thread_id thread
= spawn_thread(crashing_thread
, "crashing thread",
260 B_NORMAL_PRIORITY
, NULL
);
262 fprintf(stderr
, "Error: Failed to spawn thread: %s\n",
267 resume_thread(thread
);
269 if (sOptions
.multipleThreads
) {
274 while (wait_for_thread(thread
, &result
) == B_INTERRUPTED
) {