diff options
author | Sebastien Helleu <flashcode@flashtux.org> | 2005-03-05 17:03:15 +0000 |
---|---|---|
committer | Sebastien Helleu <flashcode@flashtux.org> | 2005-03-05 17:03:15 +0000 |
commit | 74330158421dce2429005ee67418aa0b1cbe7977 (patch) | |
tree | 4afb0c367142f8d0aa3da42ff5f480720665fc81 /src/common | |
parent | 57daa68be5ed4d44b64d0c1fd28875093593fe79 (diff) | |
download | weechat-74330158421dce2429005ee67418aa0b1cbe7977.zip |
Added crash dump when WeeChat receives SIGSEGV (Segmentation fault)
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/command.c | 44 | ||||
-rw-r--r-- | src/common/command.h | 1 | ||||
-rw-r--r-- | src/common/completion.c | 10 | ||||
-rw-r--r-- | src/common/weechat.c | 181 | ||||
-rw-r--r-- | src/common/weechat.h | 3 |
5 files changed, 196 insertions, 43 deletions
diff --git a/src/common/command.c b/src/common/command.c index 4e6c65ab2..63c3f1146 100644 --- a/src/common/command.c +++ b/src/common/command.c @@ -65,6 +65,10 @@ t_weechat_command weechat_commands[] = N_("[servername]"), N_("servername: server name to disconnect"), 0, 1, weechat_cmd_disconnect, NULL }, + { "debug", N_("print debug messages"), + N_("dump"), + N_("dump: save memory dump in WeeChat log file (same dump is written when WeeChat crashes)"), + 1, 1, weechat_cmd_debug, NULL }, { "help", N_("display help about commands"), N_("[command]"), N_("command: name of a WeeChat or IRC command"), 0, 1, weechat_cmd_help, NULL }, @@ -1034,7 +1038,7 @@ weechat_cmd_clear (int argc, char **argv) { if (argc == 1) { - if (strcmp (argv[0], "-all") == 0) + if (strcasecmp (argv[0], "-all") == 0) gui_buffer_clear_all (); else { @@ -1103,6 +1107,38 @@ weechat_cmd_connect (int argc, char **argv) } /* + * weechat_cmd_debug: print debug messages + */ + +int +weechat_cmd_debug (int argc, char **argv) +{ + if (argc != 1) + { + irc_display_prefix (NULL, PREFIX_ERROR); + gui_printf (NULL, + _("%s wrong argument count for \"%s\" command\n"), + WEECHAT_ERROR, "debug"); + return -1; + } + + if (strcasecmp (argv[0], "dump") == 0) + { + wee_dump (0); + } + else + { + irc_display_prefix (NULL, PREFIX_ERROR); + gui_printf (NULL, + _("%s unknown option for \"%s\" command\n"), + WEECHAT_ERROR, "perl"); + return -1; + } + + return 0; +} + +/* * weechat_cmd_disconnect: disconnect from a server */ @@ -1316,9 +1352,9 @@ weechat_cmd_perl (int argc, char **argv) break; case 1: - if (strcmp (argv[0], "autoload") == 0) + if (strcasecmp (argv[0], "autoload") == 0) plugin_auto_load (PLUGIN_TYPE_PERL, "perl/autoload"); - if (strcmp (argv[0], "unload") == 0) + if (strcasecmp (argv[0], "unload") == 0) { /* unload all Perl scripts */ plugin_unload (PLUGIN_TYPE_PERL, NULL); @@ -1327,7 +1363,7 @@ weechat_cmd_perl (int argc, char **argv) } break; case 2: - if (strcmp (argv[0], "load") == 0) + if (strcasecmp (argv[0], "load") == 0) { /* load Perl script */ if (strstr(argv[1], DIR_SEPARATOR)) diff --git a/src/common/command.h b/src/common/command.h index 474f3c10c..635c26261 100644 --- a/src/common/command.h +++ b/src/common/command.h @@ -65,6 +65,7 @@ extern int weechat_cmd_alias (char *); extern int weechat_cmd_buffer (int, char **); extern int weechat_cmd_clear (int, char **); extern int weechat_cmd_connect (int, char **); +extern int weechat_cmd_debug (int, char **); extern int weechat_cmd_disconnect (int, char **); extern int weechat_cmd_help (int, char **); extern int weechat_cmd_perl (int, char **); diff --git a/src/common/completion.c b/src/common/completion.c index 40996e46a..75be644a6 100644 --- a/src/common/completion.c +++ b/src/common/completion.c @@ -165,6 +165,16 @@ completion_build_list (t_completion *completion, void *channel) return; } } + if (strcasecmp (completion->base_command, "debug") == 0) + { + if (completion->base_command_arg == 1) + weelist_add (&completion->completion_list, + &completion->last_completion, + "dump"); + else + completion_stop (completion); + return; + } if ((strcasecmp (completion->base_command, "help") == 0) && (completion->base_command_arg == 1)) { diff --git a/src/common/weechat.c b/src/common/weechat.c index 193c63d5d..0e6c4184e 100644 --- a/src/common/weechat.c +++ b/src/common/weechat.c @@ -62,9 +62,10 @@ #include "../plugins/plugins.h" -int quit_weechat; /* = 1 if quit request from user... why ? :'( */ -char *weechat_home = NULL; /* WeeChat home dir. (example: /home/toto/.weechat) */ -FILE *weechat_log_file = NULL; /* WeeChat log file (~/.weechat/weechat.log) */ +int quit_weechat; /* = 1 if quit request from user... why ? :'( */ +int sigsegv = 0; /* SIGSEGV received? */ +char *weechat_home = NULL; /* WeeChat home dir. (example: /home/toto/.weechat) */ +FILE *weechat_log_file = NULL; /* WeeChat log file (~/.weechat/weechat.log) */ char *local_charset = NULL; /* local charset, for example: ISO-8859-1 */ @@ -72,14 +73,34 @@ int server_cmd_line; /* at least one server on WeeChat command line */ /* - * my_sigint: SIGINT handler, do nothing (just ignore this signal) - * Prevents user for exiting with Ctrl-C + * wee_log_printf: displays a message in WeeChat log (~/.weechat/weechat.log) */ void -my_sigint () +wee_log_printf (char *message, ...) { - /* do nothing */ + static char buffer[4096]; + va_list argptr; + static time_t seconds; + struct tm *date_tmp; + + if (!weechat_log_file) + return; + + va_start (argptr, message); + vsnprintf (buffer, sizeof (buffer) - 1, message, argptr); + va_end (argptr); + + seconds = time (NULL); + date_tmp = localtime (&seconds); + if (date_tmp) + fprintf (weechat_log_file, "[%04d-%02d-%02d %02d:%02d:%02d] %s", + date_tmp->tm_year + 1900, date_tmp->tm_mon + 1, date_tmp->tm_mday, + date_tmp->tm_hour, date_tmp->tm_min, date_tmp->tm_sec, + buffer); + else + fprintf (weechat_log_file, "%s", buffer); + fflush (weechat_log_file); } /* @@ -154,37 +175,6 @@ long get_timeval_diff(struct timeval *tv1, struct timeval *tv2) } /* - * wee_log_printf: displays a message in WeeChat log (~/.weechat/weechat.log) - */ - -void -wee_log_printf (char *message, ...) -{ - static char buffer[4096]; - va_list argptr; - static time_t seconds; - struct tm *date_tmp; - - if (!weechat_log_file) - return; - - va_start (argptr, message); - vsnprintf (buffer, sizeof (buffer) - 1, message, argptr); - va_end (argptr); - - seconds = time (NULL); - date_tmp = localtime (&seconds); - if (date_tmp) - fprintf (weechat_log_file, "[%04d-%02d-%02d %02d:%02d:%02d] %s", - date_tmp->tm_year + 1900, date_tmp->tm_mon + 1, date_tmp->tm_mday, - date_tmp->tm_hour, date_tmp->tm_min, date_tmp->tm_sec, - buffer); - else - fprintf (weechat_log_file, "%s", buffer); - fflush (weechat_log_file); -} - -/* * wee_display_config_options: display config options */ @@ -549,6 +539,120 @@ wee_shutdown (int return_code) } /* + * wee_dump writes dump to WeeChat log file + */ + +void +wee_dump (int crash) +{ + t_irc_server *ptr_server; + t_irc_channel *ptr_channel; + t_irc_nick *ptr_nick; + t_gui_window *ptr_window; + t_gui_buffer *ptr_buffer; + + /* prevent reentrance */ + if (sigsegv) + exit (EXIT_FAILURE); + + if (crash) + { + sigsegv = 1; + wee_log_printf ("very bad, WeeChat is crashing (SIGSEGV received)...\n"); + } + + wee_log_printf ("\n"); + if (crash) + { + wee_log_printf ("****** WeeChat CRASH DUMP ******\n"); + wee_log_printf ("****** Please send this file to WeeChat developers ******\n"); + wee_log_printf ("****** and explain when this crash happened ******\n"); + } + else + { + wee_log_printf ("****** WeeChat dump request ******\n"); + } + + for (ptr_server = irc_servers; ptr_server; ptr_server = ptr_server->next_server) + { + wee_log_printf ("\n"); + server_print_log (ptr_server); + + for (ptr_channel = ptr_server->channels; ptr_channel; + ptr_channel = ptr_channel->next_channel) + { + wee_log_printf ("\n"); + channel_print_log (ptr_channel); + + for (ptr_nick = ptr_channel->nicks; ptr_nick; + ptr_nick = ptr_nick->next_nick) + { + wee_log_printf ("\n"); + nick_print_log (ptr_nick); + } + + } + } + + wee_log_printf ("\n"); + wee_log_printf ("[windows/buffers]\n"); + wee_log_printf (" => windows:\n"); + for (ptr_window = gui_windows; ptr_window; ptr_window = ptr_window->next_window) + { + wee_log_printf (" 0x%X\n", ptr_window); + } + wee_log_printf (" => buffers:\n"); + for (ptr_buffer = gui_buffers; ptr_buffer; ptr_buffer = ptr_buffer->next_buffer) + { + wee_log_printf (" 0x%X\n", ptr_buffer); + } + wee_log_printf (" => current window = 0x%X\n", gui_current_window); + + for (ptr_window = gui_windows; ptr_window; ptr_window = ptr_window->next_window) + { + wee_log_printf ("\n"); + gui_window_print_log (ptr_window); + } + + for (ptr_buffer = gui_buffers; ptr_buffer; ptr_buffer = ptr_buffer->next_buffer) + { + wee_log_printf ("\n"); + gui_buffer_print_log (ptr_buffer); + } + + wee_log_printf ("\n"); + wee_log_printf ("****** End of dump ******\n"); + wee_log_printf ("\n"); +} + +/* + * my_sigint: SIGINT handler, do nothing (just ignore this signal) + * Prevents user for exiting with Ctrl-C + */ + +void +my_sigint () +{ + /* do nothing */ +} + +/* + * my_sigsegv: SIGSEGV handler: save crash log to ~/.weechat/weechat.log and exit + */ + +void +my_sigsegv () +{ + wee_dump (1); + wee_gui_shutdown (); + fprintf (stderr, "\n"); + fprintf (stderr, "*** Very bad! WeeChat has crashed (SIGSEGV received)\n"); + fprintf (stderr, "*** Full crash dump was saved to ~/.weechat/weechat.log file\n"); + fprintf (stderr, "*** Please send this file to WeeChat developers.\n\n"); + wee_shutdown (EXIT_FAILURE); +} + +/* * main: WeeChat startup */ @@ -564,6 +668,7 @@ main (int argc, char *argv[]) local_charset = strdup (nl_langinfo (CODESET)); signal (SIGINT, my_sigint); /* ignore SIGINT signal */ + signal (SIGSEGV, my_sigsegv); /* crash dump when SIGSEGV is received */ gui_pre_init (&argc, &argv); /* pre-initiliaze interface */ wee_init_vars (); /* initialize some variables */ wee_parse_args (argc, argv); /* parse command line args */ diff --git a/src/common/weechat.h b/src/common/weechat.h index 34f72dc4b..6e60acedd 100644 --- a/src/common/weechat.h +++ b/src/common/weechat.h @@ -102,9 +102,10 @@ extern int quit_weechat; extern char *weechat_home; extern char *local_charset; +extern void wee_log_printf (char *, ...); +extern void wee_dump (int); extern char *weechat_convert_encoding (char *, char *, char *); extern long get_timeval_diff (struct timeval *, struct timeval *); -extern void wee_log_printf (char *, ...); extern void wee_shutdown (int); #endif /* weechat.h */ |