diff options
Diffstat (limited to 'gdb-wrapper2/test_program.c')
-rw-r--r-- | gdb-wrapper2/test_program.c | 154 |
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(); +} |