summaryrefslogtreecommitdiff
path: root/gdb-wrapper2/test_program.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb-wrapper2/test_program.c')
-rw-r--r--gdb-wrapper2/test_program.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/gdb-wrapper2/test_program.c b/gdb-wrapper2/test_program.c
new file mode 100644
index 0000000..e332d5f
--- /dev/null
+++ b/gdb-wrapper2/test_program.c
@@ -0,0 +1,154 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <signal.h>
+
+#define MAX_SIGNALS 32
+
+#define print(fmt, ...) fprintf(stderr, "test_program: "fmt, ##__VA_ARGS__)
+
+_Bool do_raise = 0;
+int raise_signal;
+_Bool do_Com_Error = 0;
+_Bool recursive = 0;
+
+enum { DEFAULT = 0, CATCH, IGNORE };
+int handle[MAX_SIGNALS] = {0};
+_Bool handle_any = 0;
+
+_Bool verbose = 0;
+
+static int read_args(int argc, char **argv)
+{
+ for (int i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "--raise")) {
+ if (i + 1 >= argc)
+ goto needs_argument;
+
+ do_raise = 1;
+ raise_signal = atoi(argv[i + 1]);
+ i++;
+ } else if (!strcmp(argv[i], "--Com_Error")) {
+ do_Com_Error = 1;
+ } else if (!strcmp(argv[i], "--recursive")) {
+ recursive = 1;
+ } else if (!strcmp(argv[i], "--catch") ||
+ !strcmp(argv[i], "--ignore")) {
+ int sig;
+
+ if (i + 1 >= argc)
+ goto needs_argument;
+
+ sig = atoi(argv[i + 1]);
+ if (sig < 0 || sig >= MAX_SIGNALS) {
+ print("invalid argument for --catch/--ignore: %i\n",
+ sig);
+ return 1;
+ }
+
+ if (!strcmp(argv[i], "--catch"))
+ handle[sig] = CATCH;
+ else
+ handle[sig] = IGNORE;
+
+ handle_any = 1;
+ i++;
+ } else if (!strcmp(argv[i], "--ignore")) {
+
+ } else if (!strcmp(argv[i], "--verbose")) {
+ verbose = 1;
+ } else {
+ print("invalid option '%s'\n", argv[i]);
+ return 1;
+ }
+
+ continue;
+ needs_argument:
+ print("option '%s' needs an argument\n", argv[i]);
+ return 1;
+ }
+
+ if (do_Com_Error && do_raise) {
+ print("--raise and --Com_Error are mutually exclusive.\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+_Noreturn void graceful_exit(void)
+{
+ print("Graceful exit.\n");
+ exit(0);
+}
+
+void signal_catcher(int sig)
+{
+ print("Caught signal %i.\n", sig);
+
+ if (recursive) {
+ if (verbose)
+ print("Raising signal %i from within the handler.\n",
+ raise_signal);
+ raise(raise_signal);
+ }
+
+ graceful_exit();
+}
+
+_Noreturn void Com_Error(int type, const char *str)
+{
+ print("Com_Error: %s\n", str);
+
+ if (recursive)
+ Com_Error(666, "Error while erroring");
+
+ graceful_exit();
+}
+
+int main(int argc, char **argv)
+{
+ int rv;
+
+ rv = read_args(argc, argv);
+ if (rv)
+ return rv;
+
+ for (int i = 0; i < MAX_SIGNALS; i++) {
+ void (*fun)(int);
+
+ switch (handle[i]) {
+ case DEFAULT:
+ continue;
+
+ case CATCH:
+ fun = signal_catcher;
+ if (verbose)
+ print("Signal %i will be caught.\n", i);
+ break;
+
+ case IGNORE:
+ fun = SIG_IGN;
+ if (verbose)
+ print("Signal %i will be ignored.\n", i);
+ break;
+ }
+
+ if (signal(i, fun) == SIG_ERR) {
+ print("For signal %i: ", i);
+ perror("signal");
+ return 1;
+ }
+ }
+
+ if (do_raise) {
+ print("Raising signal %i.\n", raise_signal);
+ raise(raise_signal);
+ }
+
+ if (do_Com_Error)
+ Com_Error(123, "Some error string");
+
+ print("Reached the end of main().\n");
+ graceful_exit();
+}