diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2021-02-28 22:21:26 -0500 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2021-02-28 22:21:26 -0500 |
commit | 181b1256871e392da63951f82c16b4908e5b651e (patch) | |
tree | 39777eca39f15e75fad283748fe2b5082c1bbf7a | |
parent | 9d9993607c9093bd59a02138f5e51f1c678e17e9 (diff) |
on crash, output info to log
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | main.c | 68 | ||||
-rw-r--r-- | ted.c | 3 | ||||
-rw-r--r-- | ted.h | 2 |
4 files changed, 68 insertions, 7 deletions
@@ -2,7 +2,7 @@ ALL_CFLAGS=$(CFLAGS) -Wall -Wextra -Wshadow -Wconversion -Wpedantic -pedantic -s -Wno-unused-function -Wno-fixed-enum-extension -Wimplicit-fallthrough -Wno-format-truncation -Wno-unknown-warning-option LIBS=-lSDL2 -lGL -ldl -lm libpcre2-32.a -Ipcre2-10.36/build DEBUG_CFLAGS=$(ALL_CFLAGS) -DDEBUG -O0 -g -RELEASE_CFLAGS=$(ALL_CFLAGS) -O3 -g +RELEASE_CFLAGS=$(ALL_CFLAGS) -O3 PROFILE_CFLAGS=$(ALL_CFLAGS) -O3 -g -DPROFILE=1 GLOBAL_DATA_DIR=/usr/share/ted LOCAL_DATA_DIR=/home/`logname`/.local/share/ted @@ -1,7 +1,8 @@ // @TODO: -// - on crash, output backtrace to log +// - "on crash, output backtrace to log" for Windows // - Windows installation // - restore previously opened files (setting: restore-session) +// - test on BSD // - completion @@ -18,6 +19,9 @@ no_warn_start no_warn_end #include <locale.h> #include <wctype.h> +#if __linux__ +#include <execinfo.h> +#endif #if _WIN32 #include <shellapi.h> #endif @@ -108,6 +112,44 @@ static void APIENTRY gl_message_callback(GLenum source, GLenum type, unsigned in } #endif +#if __unix__ +static Ted *error_signal_handler_ted; +static void error_signal_handler(int signum, siginfo_t *info, void *context) { + (void)context; + Ted *ted = error_signal_handler_ted; + if (ted) { + FILE *log = ted->log; + if (log) { + fprintf(log, "Signal %d: %s\n", signum, strsignal(signum)); + fprintf(log, "errno = %d\n", info->si_errno); + fprintf(log, "code = %d\n", info->si_code); + fprintf(log, "address = 0x%llx\n", (unsigned long long)info->si_addr); + #if __linux__ + fprintf(log, "utime = %lu\n", (unsigned long)info->si_utime); + fprintf(log, "stime = %lu\n", (unsigned long)info->si_stime); + fprintf(log, "address lsb = %d\n", info->si_addr_lsb); + fprintf(log, "lower bound = 0x%llx\n", (unsigned long long)info->si_lower); + fprintf(log, "lower bound = 0x%llx\n", (unsigned long long)info->si_upper); + fprintf(log, "syscall address = 0x%llx\n", (unsigned long long)info->si_call_addr); + fprintf(log, "syscall = 0x%d\n", info->si_syscall); + + fprintf(log, "Backtrace:\n"); + void *addresses[300] = {0}; + int n_addresses = backtrace(addresses, (int)arr_count(addresses)); + for (int i = 0; i < n_addresses; ++i) { + fprintf(log, " 0x%llx\n", (unsigned long long)addresses[i]); + } + #endif + fclose(log); + } + + die("ted has crashed ): Please send %s/log.txt to pommicket""@gmail.com if you want this fixed.", ted->local_data_dir); + } else { + die("ted crashed when starting up ):"); + } +} +#endif + static void ted_update_window_dimensions(Ted *ted) { int w = 0, h = 0; SDL_GetWindowSize(ted->window, &w, &h); @@ -182,6 +224,20 @@ INT WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, #else int main(int argc, char **argv) { #endif + +#if __unix__ + { + struct sigaction act = {0}; + act.sa_sigaction = error_signal_handler; + act.sa_flags = SA_SIGINFO; + sigaction(SIGSEGV, &act, NULL); + sigaction(SIGFPE, &act, NULL); + sigaction(SIGABRT, &act, NULL); + sigaction(SIGILL, &act, NULL); + sigaction(SIGPIPE, &act, NULL); + } +#endif + setlocale(LC_ALL, ""); // allow unicode // read command-line arguments @@ -211,6 +267,8 @@ int main(int argc, char **argv) { die("Not enough memory available to run ted."); } + error_signal_handler_ted = ted; + { // get local data directory #if _WIN32 wchar_t *appdata = NULL; @@ -242,6 +300,7 @@ int main(int argc, char **argv) { strbuf_printf(log_filename, "%s/log.txt", ted->local_data_dir); log = fopen(log_filename, "w"); } + ted->log = log; { // get current working directory fs_get_cwd(ted->cwd, sizeof ted->cwd); @@ -636,7 +695,7 @@ int main(int argc, char **argv) { Font *font = ted->font; - // default window title + // default window titlel strcpy(ted->window_title, "ted"); @@ -665,6 +724,10 @@ int main(int argc, char **argv) { text_render(font); } + // stop dragging tab if mouse was released + if (ted->nmouse_releases[SDL_BUTTON_LEFT]) + ted->dragging_tab_node = NULL; + if (ted->menu) { menu_render(ted); } @@ -729,7 +792,6 @@ int main(int argc, char **argv) { } } - #if DEBUG for (u16 i = 0; i < TED_MAX_BUFFERS; ++i) if (ted->buffers_used[i]) @@ -97,9 +97,6 @@ static void ted_load_fonts(Ted *ted) { // sets the active buffer to this buffer, and updates active_node, etc. accordingly // you can pass NULL to buffer to make it so no buffer is active. static void ted_switch_to_buffer(Ted *ted, TextBuffer *buffer) { - if (ted->active_buffer == buffer) return; - - ted->active_buffer = buffer; if (ted->find) find_update(ted, true); @@ -272,6 +272,8 @@ typedef struct Ted { Command warn_unsaved; // if non-zero, the user is trying to execute this command, but there are unsaved changes bool build_shown; // are we showing the build output? bool building; // is the build process running? + + FILE *log; BuildError *build_errors; // dynamic array of build errors u32 build_error; // build error we are currently "on" |