#include "emu.h" #include "dosemu_config.h" #include "debug.h" #include #include #include #include #include static FILE *gdb_f = NULL; static void gdb_command(char *cmd) { printf(cmd); fflush(stdout); fprintf(gdb_f, cmd); fflush(gdb_f); } static int start_gdb(pid_t dosemu_pid) { char *buf; printf("Debug info:\n"); fflush(stdout); asprintf(&buf, "gdb %s", dosemu_proc_self_exe); printf(buf); putchar('\n'); fflush(stdout); if (!(gdb_f = popen(buf, "w"))) return 0; sprintf(buf, "attach %i\n", dosemu_pid); gdb_command(buf); free(buf); return 1; } static void do_debug(void) { char *cmd1 = "info registers\n"; char *cmd2 = "backtrace full\n"; gdb_command(cmd1); gdb_command(cmd2); } static void stop_gdb(void) { char *cmd1 = "detach\n"; char *cmd2 = "quit\n"; int status; gdb_command(cmd1); gdb_command(cmd2); wait(&status); pclose(gdb_f); putchar('\n'); fflush(stdout); } static void collect_info(pid_t pid) { char *cmd0 = "ldd %s"; char *cmd1 = "getconf GNU_LIBC_VERSION"; char *cmd2 = "getconf GNU_LIBPTHREAD_VERSION"; char *cmd3 = "gcc -v"; char *cmd4 = "uname -a"; char *cmd5 = "cat /proc/%i/maps"; char *tmp; printf("System info:\n"); fflush(stdout); asprintf(&tmp, cmd0, dosemu_proc_self_exe); system(tmp); free(tmp); system(cmd1); system(cmd2); system(cmd3); system(cmd4); asprintf(&tmp, cmd5, pid); system(tmp); free(tmp); fflush(stdout); } void gdb_debug(void) { pid_t dosemu_pid = getpid(); pid_t dbg_pid; int status; if (getuid() != geteuid()) return; switch ((dbg_pid = fork())) { case 0: dup2(fileno(dbg_fd), STDOUT_FILENO); dup2(fileno(dbg_fd), STDERR_FILENO); collect_info(dosemu_pid); if (start_gdb(dosemu_pid)) { do_debug(); stop_gdb(); } _exit(0); break; case -1: return; default: waitpid(dbg_pid, &status, 0); } }