xref: /haiku/src/tests/servers/debug/crashing_app.cpp (revision 1e36cfc2721ef13a187c6f7354dc9cbc485e89d3)
1 
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 
6 #include <OS.h>
7 
8 extern const char *__progname;
9 
10 // usage
11 static const char *kUsage =
12 	"%s <options> [ <mode> ]\n"
13 	"Crashes in more or less inovative ways.\n"
14 	"\n"
15 	"Options:\n"
16 	"  -h, --help           - print this info text\n"
17 	"\n"
18 	"Modes:\n"
19 	"[general]\n"
20 	"  segv                 - dereferences a null pointer (default)\n"
21 	"  segv2                - strcmp() using a 0x1 pointer\n"
22 	"  div                  - executes a division by zero\n"
23 	"  debugger             - invokes debugger()\n"
24 	"\n"
25 	"[x86 specific]\n"
26 	"  int3                 - executes the int3 (breakpoint) instruction\n"
27 	"  protection           - executes an instruction that causes a general\n"
28 	"                         protection exception\n";
29 
30 // application name
31 const char *kAppName = __progname;
32 
33 static void
34 print_usage(bool error)
35 {
36 	fprintf(error ? stderr : stdout, kUsage, kAppName);
37 }
38 
39 
40 static void
41 print_usage_and_exit(bool error)
42 {
43 	print_usage(error);
44 	exit(error ? 0 : 1);
45 }
46 
47 
48 static void
49 crash_segv()
50 {
51 	int *a = 0;
52 	*a = 0;
53 }
54 
55 static void
56 crash_segv2()
57 {
58 	const char *str = (const char*)0x1;
59 	strcmp(str, "Test");
60 }
61 
62 static int
63 crash_div()
64 {
65 	int i = 0;
66 	i = 1 / i;
67 	return i;
68 }
69 
70 static void
71 crash_debugger()
72 {
73 	debugger("crashing_app() invoked debugger()");
74 }
75 
76 #if __INTEL__
77 
78 static void
79 crash_int3()
80 {
81 	asm("int3");
82 }
83 
84 static void
85 crash_protection()
86 {
87 	asm("movl %0, %%dr7" : : "r"(0));
88 }
89 
90 #endif	// __INTEL__
91 
92 
93 int
94 main(int argc, const char *const *argv)
95 {
96 	const char *mode = "segv";
97 
98 	// parse args
99 	int argi = 1;
100 	while (argi < argc) {
101 		const char *arg = argv[argi++];
102 
103 		if (arg[0] == '-') {
104 			if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
105 				print_usage_and_exit(false);
106 			} else {
107 				fprintf(stderr, "Invalid option \"%s\"\n", arg);
108 				print_usage_and_exit(true);
109 			}
110 		} else {
111 			mode = arg;
112 		}
113 	}
114 
115 	if (strcmp(mode, "segv") == 0) {
116 		crash_segv();
117 	} else if (strcmp(mode, "segv2") == 0) {
118 		crash_segv2();
119 	} else if (strcmp(mode, "div") == 0) {
120 		crash_div();
121 	} else if (strcmp(mode, "debugger") == 0) {
122 		crash_debugger();
123 #if __INTEL__
124 	} else if (strcmp(mode, "int3") == 0) {
125 		crash_int3();
126 	} else if (strcmp(mode, "protection") == 0) {
127 		crash_protection();
128 #endif	// __INTEL__
129 	} else {
130 		fprintf(stderr, "Invalid mode \"%s\"\n", mode);
131 		print_usage_and_exit(true);
132 	}
133 
134 	return 0;
135 }
136