summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorSebastien Helleu <flashcode@flashtux.org>2005-03-05 17:03:15 +0000
committerSebastien Helleu <flashcode@flashtux.org>2005-03-05 17:03:15 +0000
commit74330158421dce2429005ee67418aa0b1cbe7977 (patch)
tree4afb0c367142f8d0aa3da42ff5f480720665fc81 /src/common
parent57daa68be5ed4d44b64d0c1fd28875093593fe79 (diff)
downloadweechat-74330158421dce2429005ee67418aa0b1cbe7977.zip
Added crash dump when WeeChat receives SIGSEGV (Segmentation fault)
Diffstat (limited to 'src/common')
-rw-r--r--src/common/command.c44
-rw-r--r--src/common/command.h1
-rw-r--r--src/common/completion.c10
-rw-r--r--src/common/weechat.c181
-rw-r--r--src/common/weechat.h3
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 */