bug-buddy r2735 - in trunk: . gnome-breakpad src



Author: cosimoc
Date: Wed Oct  1 12:23:43 2008
New Revision: 2735
URL: http://svn.gnome.org/viewvc/bug-buddy?rev=2735&view=rev

Log:
2008-10-01  Cosimo Cecchi  <cosimoc gnome org>

	* gnome-breakpad/gnome-breakpad.cc:
	* src/bug-buddy.c: (unknown_app_finished), (fill_custom_info),
	(main):
	Implement a logger for critical and fatal warnings, which will be
	included in the bug report sent to bugzilla (#350221).
	* src/gnome-crash.c: (main):
	Update the test to contain a critical warning.


Modified:
   trunk/ChangeLog
   trunk/gnome-breakpad/gnome-breakpad.cc
   trunk/src/bug-buddy.c
   trunk/src/gnome-crash.c

Modified: trunk/gnome-breakpad/gnome-breakpad.cc
==============================================================================
--- trunk/gnome-breakpad/gnome-breakpad.cc	(original)
+++ trunk/gnome-breakpad/gnome-breakpad.cc	Wed Oct  1 12:23:43 2008
@@ -36,6 +36,17 @@
 static void    check_if_gdb    ();
 
 static gchar *bugbuddy;
+static GLogFunc old_handler = NULL;
+
+typedef struct {
+	int start;
+	int next_free;
+	int size;
+	char **strings;
+} CircBuff;
+
+static CircBuff * log_buff = NULL;
+#define LOG_BUFFER_SIZE 15
 
 #ifdef ENABLE_GOOGLE_BREAKPAD
 static ExceptionHandler * handler;
@@ -60,6 +71,136 @@
 }
 #endif
 
+/*
+static char *
+get_logged_warnings_file (void)
+{
+	int tmp_fd;
+	char *actual_name = NULL;
+	GError *error = NULL;
+
+	if (log_string == NULL)
+		return NULL;
+
+	tmp_fd = g_file_open_tmp ("bug-buddy-XXXXXX", &actual_name, &error);
+	if (error) {
+		g_warning ("Unable to create a temp file: %s", error->message);
+		g_error_free (error);
+		return NULL;
+	}
+
+	write (tmp_fd, log_string->str, log_string->len);
+	write (tmp_fd, "\n", 1);
+	close (tmp_fd);
+
+	g_string_free (log_string, TRUE);
+	log_string = NULL;
+
+	return actual_name;
+}
+*/
+
+static void
+circ_buff_free (CircBuff *buff)
+{
+	g_strfreev (buff->strings);
+	g_free (buff);
+
+	buff = NULL;
+}
+
+static CircBuff *
+circ_buff_new (int size)
+{
+	CircBuff *retval;
+
+	retval = g_new0 (CircBuff, 1);
+	retval->strings = g_new0 (char *, size + 1);
+	retval->strings[size + 1] = NULL;
+	retval->size = size;
+
+	return retval;
+}
+
+static void
+circ_add (CircBuff *buff, char * str)
+{
+	if (buff->strings[buff->next_free]) {
+		g_free (buff->strings[buff->next_free]);
+		buff->start = (buff->start + 1) % buff->size;
+	}
+	
+	buff->strings[buff->next_free] = str;
+	buff->next_free = (buff->next_free + 1) % buff->size;
+}
+
+static char *
+circ_buff_to_file (CircBuff *buff)
+{
+	int tmp_fd, i;
+	char *actual_name = NULL;
+	GError *error = NULL;
+	const char *header;
+
+	tmp_fd = g_file_open_tmp ("bug-buddy-XXXXXX", &actual_name, &error);
+
+	if (error) {
+		g_warning ("Unable to create the warnings temp file: %s", error->message);
+		g_error_free (error);
+		return NULL;
+	}
+
+	header = "\n\n---- Critical and fatal warnings logged during execution ----\n\n";
+	write (tmp_fd, header, strlen (header));
+
+	i = buff->start;
+
+	while (buff->strings[i] != NULL) {
+		/* write to file */
+		write (tmp_fd, buff->strings[i], strlen (buff->strings[i]));
+
+		/* increase and check for overflow */
+		i = (i + 1) % buff->size;
+
+		if (i == buff->start)
+			break;
+	}
+
+	close (tmp_fd);
+
+	return actual_name;
+}
+
+static void
+bug_buddy_log_handler (const gchar *log_domain,
+		       GLogLevelFlags log_level,
+		       const gchar *message,
+		       gpointer user_data)
+{
+	/* forward the message to the real handler and use the default GLib
+	 * handler if that's NULL (should never happen, but who knows).
+	 */
+	if (old_handler) {
+		old_handler (log_domain, log_level, message, user_data);
+	} else {
+		g_log_default_handler (log_domain, log_level, message, user_data);
+	}
+
+	if (log_level & 
+	    (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL)) 
+	{
+		/* log the message into memory */
+		if (!log_buff) {
+			log_buff = circ_buff_new (LOG_BUFFER_SIZE);
+		}
+
+		/* if the log domain is NULL, assume it's a message coming from the app,
+		 * see the docs for G_LOG_DOMAIN.
+		 */
+		circ_add (log_buff, g_strdup_printf ("** %s **: %s \n", log_domain ? log_domain : g_get_prgname (), message));
+	}
+}
+
 static void
 bugbuddy_segv_handle(int signum)
 {
@@ -199,29 +340,36 @@
 static bool
 run_bug_buddy (const gchar *appname, pid_t pid, const gchar *minidump_path)
 {
-	gchar *exec_str;
 	gboolean res;
+	char *warning_file, *exec_str;
+	GString *args_str;
 	GError *error = NULL;
 
-	if (pid != 0) 
-		exec_str = g_strdup_printf("bug-buddy "
-				   	"--appname=\"%s\" "
-				  	 "--pid=%d",
-				   	appname,(int) pid);
-	else if (minidump_path != NULL)
-		exec_str = g_strdup_printf("bug-buddy "
-				   	"--appname=\"%s\" "
-				  	 "--minidump=%s",
-				   	appname, minidump_path);
-	else
+	if (pid == 0 && minidump_path == NULL)
 		return false;
 
+	warning_file = circ_buff_to_file (log_buff);
+	circ_buff_free (log_buff);
 
+	args_str = g_string_new ("bug-buddy ");
+	g_string_append_printf (args_str, "--appname=\"%s\" ", appname);
+
+	if (warning_file) {
+		g_string_append_printf (args_str, "--include=\"%s\" --unlink-tempfile ", warning_file);
+		g_free (warning_file);
+	}
+
+	if (pid != 0)
+		g_string_append_printf (args_str,  "--pid=%d",(int) pid);
+	else if (minidump_path != NULL)
+		g_string_append_printf (args_str, "--minidump=%s", minidump_path);
+
+	exec_str = g_string_free (args_str, FALSE);
 	res = g_spawn_command_line_sync (exec_str, NULL, NULL,
 					 NULL, &error);
-	g_free(exec_str);
+	g_free (exec_str);
 	if (!res) {
-		g_warning("Couldn't run bug-buddy\n");
+		g_warning ("Couldn't run bug-buddy\n");
 		return false;
 	}
 
@@ -335,6 +483,8 @@
                 sigaction(SIGBUS, NULL, &old_action);
 		if (old_action.sa_handler == SIG_DFL)
                 	sigaction(SIGBUS, setptr, NULL);
+
+		old_handler = g_log_set_default_handler (bug_buddy_log_handler, NULL);
 	}
 	return 0;
 }

Modified: trunk/src/bug-buddy.c
==============================================================================
--- trunk/src/bug-buddy.c	(original)
+++ trunk/src/bug-buddy.c	Wed Oct  1 12:23:43 2008
@@ -86,6 +86,7 @@
 static void fill_custom_info (BugzillaApplication *app, GtkBuilder *ui);
 static void close_callback   (GtkWidget *widget, gpointer user_data);
 static void bug_buddy_quit   (GtkBuilder *ui);
+static void fill_include_file (char *filename, gboolean own_file, GtkBuilder *ui);
 
 
 static void
@@ -1363,6 +1364,11 @@
 {
 	GtkWidget *button;
 	char *label_text;
+	
+	/* add the include file information now that gdb has run */
+	if (gopt_data.include_file != NULL) {
+		fill_include_file (gopt_data.include_file, gopt_data.own_file, ui);
+	}
 
 	fill_stderr_info (ui);
 
@@ -1538,6 +1544,11 @@
 	g_return_if_fail (app != NULL);
 	g_return_if_fail (ui != NULL);
 
+	/* fill the include info now that gdb has run */
+	if (gopt_data.include_file != NULL) {
+		fill_include_file (gopt_data.include_file, gopt_data.own_file, ui);
+	}
+
 	if (app->extra_info_script == NULL) {
 		return;
 	}
@@ -1997,15 +2008,10 @@
 		}
 		g_object_set_data (G_OBJECT (ui), "type", GINT_TO_POINTER (BUG_TYPE_REQUEST));
 	}
-	
-	if (gopt_data.include_file != NULL) {
-		fill_include_file (gopt_data.include_file, gopt_data.own_file, ui);
-	}
 
-	
 	g_signal_connect (gtk_builder_get_object (ui, "close-button"), "clicked", 
 	                  G_CALLBACK (close_callback), ui);
-	
+
 	gtk_main ();
 
 	return 0;

Modified: trunk/src/gnome-crash.c
==============================================================================
--- trunk/src/gnome-crash.c	(original)
+++ trunk/src/gnome-crash.c	Wed Oct  1 12:23:43 2008
@@ -25,7 +25,11 @@
 main (int argc, char *argv[])
 {
 	int *n = NULL;
+
 	gtk_init (&argc, &argv);
+	/* test the log handler */
+	g_critical ("ka-boom!");
+
 	n[27] = 10-7-78;
 	return 0;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]