#include #include #include #include #include #include #include "gui.h" #include "reporter.h" // Signal handler for SIGSEGV and SIGABRT void crash_handler(int sig) { fprintf(stderr, "Error: Signal %d received.\n", sig); // In a real scenario, we might want to fork/exec a separate process here // to ensure a clean state for the GUI. For this demo, we'll try to // invoke the reporter directly, but be aware this is not async-signal-safe. // Get stack trace immediately char *trace = get_stack_trace(); fprintf(stderr, "Stack trace:\n%s\n", trace); // Show the crash report window // Note: gtk_main() might be running, so we need to be careful. // We'll attempt to run a new loop or just show the dialog if possible. // Ideally, we launch a new process: // execl("./bug_reporter", "bug_reporter", "--report", trace, NULL); // For simplicity in this single-process demo: char cwd[1024]; if (getcwd(cwd, sizeof(cwd)) != NULL) { show_crash_report_window(trace, cwd); } else { perror("getcwd"); show_crash_report_window(trace, NULL); // Pass NULL if cwd cannot be determined } free(trace); exit(1); } void setup_signal_handlers() { struct sigaction sa; sa.sa_handler = crash_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESETHAND; // Reset to default after handling once to avoid loops sigaction(SIGSEGV, &sa, NULL); sigaction(SIGABRT, &sa, NULL); } void on_crash_me_clicked(GtkWidget *widget, gpointer data) { (void)widget; (void)data; printf("Crashing application...\n"); int *p = NULL; *p = 42; // Dereference NULL } int main(int argc, char *argv[]) { gtk_init(&argc, &argv); setup_signal_handlers(); GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "Bug Reporter Demo"); gtk_window_set_default_size(GTK_WINDOW(window), 300, 200); g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); GtkWidget *button = gtk_button_new_with_label("Crash Me!"); g_signal_connect(button, "clicked", G_CALLBACK(on_crash_me_clicked), NULL); GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10); gtk_container_set_border_width(GTK_CONTAINER(box), 20); gtk_box_pack_start(GTK_BOX(box), button, TRUE, TRUE, 0); gtk_container_add(GTK_CONTAINER(window), box); gtk_widget_show_all(window); gtk_main(); return 0; }