Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:dliang
nautilus
nautilus-debug-log.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File nautilus-debug-log.diff of Package nautilus
2006-12-19 Federico Mena Quintero <federico@novell.com> * libnautilus-private/nautilus-debug-log.c (make_key_file_from_configuration): Oops, handle the case of an empty domains_hash. 2006-12-12 Federico Mena Quintero <federico@novell.com> Log the milestones separately so that we don't lose them in the ring buffer. * libnautilus-private/nautilus-debug-log.c (DEFAULT_RING_BUFFER_NUM_LINES): Oops, make this 1000 by default; 30000 was way too big for normal usage. (add_to_milestones): New function; adds a milestone string to a linked list of milestones. (nautilus_debug_logv): Call add_to_milestones() if appropriate. (write_string): New helper function. (dump_milestones): New helper function. (dump_configuration): Use write_string(). (dump_ring_buffer): New helper function; moved the code from nautilus_debug_log_dump(). (nautilus_debug_log_dump): Use dump_milestones() and dump_ring_buffer(). (dump_configuration): Print the instructions to re-create the configuration here, instead of in nautilus_debug_log_dump(). 2006-11-23 Federico Mena Quintero <federico@novell.com> Use the write-to-a-pipe trick from the signal handler instead of queueing an idle handler from there. * src/nautilus-main.c (setup_debug_log_signals): Set up a pair of pipes for the SIGUSR1 handler; set up a GIOChannel on them. (sigusr1_handler): Write a byte to our pipe instead of queueing an idle handler. (debug_log_io_cb): Replaces dump_debug_log_idle_cb(). Read from the pipe, and dump the debug log. 2006-11-15 Federico Mena Quintero <federico@novell.com> * libnautilus-private/nautilus-debug-log.c (nautilus_debug_log_load_configuration): New function; loads the configuration from a key file like this: [debug log] enable domains = foo; bar; baz max lines = 1000 * libnautilus-private/nautilus-debug-log.c (dump_configuration): New utility function. (nautilus_debug_log_dump): At the end of the log, dump the configuration used for the debug log so that the user can re-create it later. * libnautilus-private/nautilus-debug-log.h: New prototype for nautilus_debug_log_load_configuration(). * src/nautilus-main.c (setup_debug_log): Load the debug log's configuration from ~/nautilus-debug-log.conf (setup_debug_log_domains): Removed. 2006-11-13 Federico Mena Quintero <federico@novell.com> * src/nautilus-main.c (log_override_cb): If the log level of the message is G_LOG_LEVEL_DEBUG, don't log it as a milestone. We'll use this log level for miscellaneous debugging messages from gnome-vfs. Also, don't send G_LOG_LEVEL_DEBUG messages to the default log handler, to avoid a huge ~/.xsession-errors. (setup_debug_log_domains): Enable logging for NAUTILUS_DEBUG_LOG_DOMAIN_GLOG. 2006-10-23 Federico Mena Quintero <federico@novell.com> * libnautilus-private/nautilus-debug-log.h (NAUTILUS_DEBUG_LOG_DOMAIN_GLOG): New domain for GLog messages. We'll spit the messages that come from GLog as milestone events. * src/nautilus-main.c (setup_debug_log): New function; set up everything here. (setup_debug_log_glog): New function. Override the default handler for GLog so that its messages will also appear as milestone events in our own debug log. 2006-10-16 Federico Mena Quintero <federico@novell.com> * src/file-manager/fm-directory-view.c (files_added_callback): Log when files are added to the view. (files_changed_callback): Log when files get changed in the view. (fm_directory_view_notify_selection_changed): Log when the selection changes. * src/nautilus-main.c (setup_debug_log_domains): Add NAUTILUS_DEBUG_LOG_DOMAIN_ASYNC to the list of enabled log domains. * libnautilus-private/nautilus-debug-log.h: New prototype for nautilus_debug_log_with_file_list(). * libnautilus-private/nautilus-debug-log.c (nautilus_debug_log_with_file_list): New function; takes a GList of NautilusFile. 2006-10-03 Federico Mena Quintero <federico@novell.com> * libnautilus-private/nautilus-debug-log.c (nautilus_debug_logv): Deal with URI lists optionally. (nautilus_debug_log_with_uri_list): New function. * libnautilus-private/nautilus-icon-dnd.c (receive_dropped_color): Log when a color is dropped. (receive_dropped_tile_image): Log when a tile image is dropped. * libnautilus-private/nautilus-icon-container.c (motion_notify_event): Log when a drag begins. (button_release_event): Log when a drag ends. * libnautilus-private/nautilus-file-operations.c (nautilus_file_operations_copy_move): Log move/copy/link actions. (nautilus_file_operations_new_folder): Log when a folder is created. (nautilus_file_operations_new_file_from_template): Log when a file is created from a template. (nautilus_file_operations_new_file): Log when a file is created. (nautilus_file_operations_delete): Log when files are deleted. (do_empty_trash): Log when the trash is emptied. 2006-09-22 Federico Mena Quintero <federico@novell.com> * libnautilus-private/nautilus-debug-log.[ch]: New files with a simple logging infrastructure based on a ring buffer. * libnautilus-private/Makefile.am (libnautilus_private_la_SOURCES): Added nautilus-debug-log.[ch]. * src/nautilus-main.c (main): Make SIGUSR1 dump the debug log to ~/nautilus-debug-log.txt. * src/file-manager/fm-directory-view.c (fm_directory_view_activate_files): Log the action of activating a file. (open_location): Likewise. (fm_directory_view_launch_application): Likewise, for launching an application. (action_new_launcher_callback): Likewise, for creating a launcher. (activate_callback): Log the various actions that can happen here. * src/file-manager/fm-tree-view.c (got_activation_uri_callback): Log the various activations/launches that can happen. * src/nautilus-places-sidebar.c (row_activated_callback): Log the action of the user activating something in the Places sidebar. * src/nautilus-window-manage-views.c (nautilus_window_open_location_full): Log the action of changing the location in a window. (nautilus_window_set_content_view): Log the action of thanging the view of a window. (end_location_change): Log when the window finishes loading. * src/file-manager/fm-list-view.c (row_expanded_callback): Log the action of expanding a row to load a subdirectory. (row_collapsed_callback): Likewise, for collapsing a row. * src/file-manager/fm-error-reporting.c (fm_rename_file): Log the action of renaming a file. * src/nautilus-application.c (nautilus_application_present_spatial_window_with_selection): Log when new or existing spatial windows get presented. (nautilus_application_create_navigation_window): Log when a navigation window gets created. --- /dev/null 2006-06-16 08:07:58.000000000 -0500 +++ nautilus-2.12.2/libnautilus-private/nautilus-debug-log.h 2006-11-15 11:45:32.000000000 -0600 @@ -0,0 +1,58 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-debug-log.h: Ring buffer for logging debug messages + + Copyright (C) 2006 Novell, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Federico Mena-Quintero <federico@novell.com> +*/ + +#ifndef NAUTILUS_DEBUG_LOG_H +#define NAUTILUS_DEBUG_LOG_H + +#include <glib.h> + +#define NAUTILUS_DEBUG_LOG_DOMAIN_USER "USER" /* always enabled */ +#define NAUTILUS_DEBUG_LOG_DOMAIN_ASYNC "async" /* when asynchronous notifications come in */ +#define NAUTILUS_DEBUG_LOG_DOMAIN_GLOG "GLog" /* used for GLog messages; don't use it yourself */ + +void nautilus_debug_log (gboolean is_milestone, const char *domain, const char *format, ...); + +void nautilus_debug_log_with_uri_list (gboolean is_milestone, const char *domain, const GList *uris, + const char *format, ...); +void nautilus_debug_log_with_file_list (gboolean is_milestone, const char *domain, GList *files, + const char *format, ...); + +void nautilus_debug_logv (gboolean is_milestone, const char *domain, const GList *uris, const char *format, va_list args); + +gboolean nautilus_debug_log_load_configuration (const char *filename, GError **error); + +void nautilus_debug_log_enable_domains (const char **domains, int n_domains); +void nautilus_debug_log_disable_domains (const char **domains, int n_domains); + +gboolean nautilus_debug_log_is_domain_enabled (const char *domain); + +gboolean nautilus_debug_log_dump (const char *filename, GError **error); + +void nautilus_debug_log_set_max_lines (int num_lines); +int nautilus_debug_log_get_max_lines (void); + +/* For testing only */ +void nautilus_debug_log_clear (void); + +#endif /* NAUTILUS_DEBUG_LOG_H */ --- /dev/null 2006-06-16 08:07:58.000000000 -0500 +++ nautilus-2.12.2/libnautilus-private/nautilus-debug-log.c 2006-12-12 11:06:48.000000000 -0600 @@ -0,0 +1,692 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + nautilus-debug-log.c: Ring buffer for logging debug messages + + Copyright (C) 2006 Novell, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Federico Mena-Quintero <federico@novell.com> +*/ +#include <config.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <sys/time.h> +#include <eel/eel-glib-extensions.h> +#include "nautilus-debug-log.h" +#include "nautilus-file.h" + +#define DEFAULT_RING_BUFFER_NUM_LINES 1000 + +#define KEY_FILE_GROUP "debug log" +#define KEY_FILE_DOMAINS_KEY "enable domains" +#define KEY_FILE_MAX_LINES_KEY "max lines" + +static GStaticMutex log_mutex = G_STATIC_MUTEX_INIT; + +static GHashTable *domains_hash; +static char **ring_buffer; +static int ring_buffer_next_index; +static int ring_buffer_num_lines; +static int ring_buffer_max_lines = DEFAULT_RING_BUFFER_NUM_LINES; + +static GSList *milestones_head; +static GSList *milestones_tail; + +static void +lock (void) +{ + g_static_mutex_lock (&log_mutex); +} + +static void +unlock (void) +{ + g_static_mutex_unlock (&log_mutex); +} + +void +nautilus_debug_log (gboolean is_milestone, const char *domain, const char *format, ...) +{ + va_list args; + + va_start (args, format); + nautilus_debug_logv (is_milestone, domain, NULL, format, args); + va_end (args); +} + +static gboolean +is_domain_enabled (const char *domain) +{ + /* User actions are always logged */ + if (strcmp (domain, NAUTILUS_DEBUG_LOG_DOMAIN_USER) == 0) + return TRUE; + + if (!domains_hash) + return FALSE; + + return (g_hash_table_lookup (domains_hash, domain) != NULL); +} + +static void +ensure_ring (void) +{ + if (ring_buffer) + return; + + ring_buffer = g_new0 (char *, ring_buffer_max_lines); + ring_buffer_next_index = 0; + ring_buffer_num_lines = 0; +} + +static void +add_to_ring (char *str) +{ + ensure_ring (); + + g_assert (str != NULL); + + if (ring_buffer_num_lines == ring_buffer_max_lines) { + /* We have an overlap, and the ring_buffer_next_index points to + * the "first" item. Free it to make room for the new item. + */ + + g_assert (ring_buffer[ring_buffer_next_index] != NULL); + g_free (ring_buffer[ring_buffer_next_index]); + } else + ring_buffer_num_lines++; + + g_assert (ring_buffer_num_lines <= ring_buffer_max_lines); + + ring_buffer[ring_buffer_next_index] = str; + + ring_buffer_next_index++; + if (ring_buffer_next_index == ring_buffer_max_lines) { + ring_buffer_next_index = 0; + g_assert (ring_buffer_num_lines == ring_buffer_max_lines); + } +} + +static void +add_to_milestones (const char *str) +{ + char *str_copy; + + str_copy = g_strdup (str); + + if (milestones_tail) { + milestones_tail = g_slist_append (milestones_tail, str_copy); + milestones_tail = milestones_tail->next; + } else { + milestones_head = milestones_tail = g_slist_append (NULL, str_copy); + } + + g_assert (milestones_head != NULL && milestones_tail != NULL); +} + +void +nautilus_debug_logv (gboolean is_milestone, const char *domain, const GList *uris, const char *format, va_list args) +{ + char *str; + char *debug_str; + struct timeval tv; + struct tm tm; + + lock (); + + if (!(is_milestone || is_domain_enabled (domain))) + goto out; + + str = g_strdup_vprintf (format, args); + gettimeofday (&tv, NULL); + + tm = *localtime (&tv.tv_sec); + + debug_str = g_strdup_printf ("%p %04d/%02d/%02d %02d:%02d:%02d.%04d (%s): %s", + g_thread_self (), + tm.tm_year + 1900, + tm.tm_mon + 1, + tm.tm_mday, + tm.tm_hour, + tm.tm_min, + tm.tm_sec, + (int) (tv.tv_usec / 100), + domain, + str); + g_free (str); + + if (uris) { + int debug_str_len; + int uris_len; + const GList *l; + char *new_str; + char *p; + + uris_len = 0; + + for (l = uris; l; l = l->next) { + const char *uri; + + uri = l->data; + uris_len += strlen (uri) + 2; /* plus 2 for a tab and the newline */ + } + + debug_str_len = strlen (debug_str); + new_str = g_new (char, debug_str_len + 1 + uris_len); /* plus 1 for newline */ + + p = g_stpcpy (new_str, debug_str); + *p++ = '\n'; + + for (l = uris; l; l = l->next) { + const char *uri; + + uri = l->data; + + *p++ = '\t'; + + p = g_stpcpy (p, uri); + + if (l->next) + *p++ = '\n'; + } + + g_free (debug_str); + debug_str = new_str; + } + + add_to_ring (debug_str); + if (is_milestone) + add_to_milestones (debug_str); + + out: + unlock (); +} + +void +nautilus_debug_log_with_uri_list (gboolean is_milestone, const char *domain, const GList *uris, + const char *format, ...) +{ + va_list args; + + va_start (args, format); + nautilus_debug_logv (is_milestone, domain, uris, format, args); + va_end (args); +} + +void +nautilus_debug_log_with_file_list (gboolean is_milestone, const char *domain, GList *files, + const char *format, ...) +{ + va_list args; + GList *uris; + GList *l; + + uris = NULL; + + for (l = files; l; l = l->next) { + NautilusFile *file; + char *uri; + + file = NAUTILUS_FILE (l->data); + uri = nautilus_file_get_uri (file); + + if (nautilus_file_is_gone (file)) { + char *new_uri; + + /* Hack: this will create an invalid URI, but it's for + * display purposes only. + */ + new_uri = g_strconcat (uri ? uri : "", " (gone)", NULL); + g_free (uri); + uri = new_uri; + } + uris = g_list_prepend (uris, uri); + } + + uris = g_list_reverse (uris); + + va_start (args, format); + nautilus_debug_logv (is_milestone, domain, uris, format, args); + va_end (args); + + eel_g_list_free_deep (uris); +} + +gboolean +nautilus_debug_log_load_configuration (const char *filename, GError **error) +{ + GKeyFile *key_file; + char **strings; + gsize num_strings; + int num; + GError *my_error; + + g_assert (filename != NULL); + g_assert (error == NULL || *error == NULL); + + key_file = g_key_file_new (); + + if (!g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, error)) { + g_key_file_free (key_file); + return FALSE; + } + + /* Domains */ + + my_error = NULL; + strings = g_key_file_get_string_list (key_file, KEY_FILE_GROUP, KEY_FILE_DOMAINS_KEY, &num_strings, &my_error); + if (my_error) + g_error_free (my_error); + else { + int i; + + for (i = 0; i < num_strings; i++) + strings[i] = g_strstrip (strings[i]); + + nautilus_debug_log_enable_domains ((const char **) strings, num_strings); + g_strfreev (strings); + } + + /* Number of lines */ + + my_error = NULL; + num = g_key_file_get_integer (key_file, KEY_FILE_GROUP, KEY_FILE_MAX_LINES_KEY, &my_error); + if (my_error) + g_error_free (my_error); + else + nautilus_debug_log_set_max_lines (num); + + g_key_file_free (key_file); + return TRUE; +} + +void +nautilus_debug_log_enable_domains (const char **domains, int n_domains) +{ + int i; + + g_assert (domains != NULL); + g_assert (n_domains >= 0); + + lock (); + + if (!domains_hash) + domains_hash = g_hash_table_new (g_str_hash, g_str_equal); + + for (i = 0; i < n_domains; i++) { + g_assert (domains[i] != NULL); + + if (strcmp (domains[i], NAUTILUS_DEBUG_LOG_DOMAIN_USER) == 0) + continue; /* user actions are always enabled */ + + if (g_hash_table_lookup (domains_hash, domains[i]) == NULL) { + char *domain; + + domain = g_strdup (domains[i]); + g_hash_table_insert (domains_hash, domain, domain); + } + } + + unlock (); +} + +void +nautilus_debug_log_disable_domains (const char **domains, int n_domains) +{ + int i; + + g_assert (domains != NULL); + g_assert (n_domains >= 0); + + lock (); + + if (domains_hash) { + for (i = 0; i < n_domains; i++) { + char *domain; + + g_assert (domains[i] != NULL); + + if (strcmp (domains[i], NAUTILUS_DEBUG_LOG_DOMAIN_USER) == 0) + continue; /* user actions are always enabled */ + + domain = g_hash_table_lookup (domains_hash, domains[i]); + if (domain) { + g_hash_table_remove (domains_hash, domain); + g_free (domain); + } + } + } /* else, there is nothing to disable */ + + unlock (); +} + +gboolean +nautilus_debug_log_is_domain_enabled (const char *domain) +{ + gboolean retval; + + g_assert (domain != NULL); + + lock (); + retval = is_domain_enabled (domain); + unlock (); + + return retval; +} + +struct domains_dump_closure { + char **domains; + int num_domains; +}; + +static void +domains_foreach_dump_cb (gpointer key, gpointer value, gpointer data) +{ + struct domains_dump_closure *closure; + char *domain; + + closure = data; + domain = key; + + closure->domains[closure->num_domains] = domain; + closure->num_domains++; +} + +static GKeyFile * +make_key_file_from_configuration (void) +{ + GKeyFile *key_file; + struct domains_dump_closure closure; + int num_domains; + + key_file = g_key_file_new (); + + /* domains */ + + if (domains_hash) { + num_domains = g_hash_table_size (domains_hash); + if (num_domains != 0) { + closure.domains = g_new (char *, num_domains); + closure.num_domains = 0; + + g_hash_table_foreach (domains_hash, domains_foreach_dump_cb, &closure); + g_assert (num_domains == closure.num_domains); + + g_key_file_set_string_list (key_file, KEY_FILE_GROUP, KEY_FILE_DOMAINS_KEY, + (const gchar * const *) closure.domains, closure.num_domains); + g_free (closure.domains); + } + } + + /* max lines */ + + g_key_file_set_integer (key_file, KEY_FILE_GROUP, KEY_FILE_MAX_LINES_KEY, ring_buffer_max_lines); + + return key_file; +} + +static gboolean +write_string (const char *filename, FILE *file, const char *str, GError **error) +{ + if (fputs (str, file) == EOF) { + int saved_errno; + + saved_errno = errno; + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (saved_errno), + "error when writing to log file %s", filename); + + return FALSE; + } + + return TRUE; +} + +static gboolean +dump_configuration (const char *filename, FILE *file, GError **error) +{ + GKeyFile *key_file; + char *data; + gsize length; + gboolean success; + + if (!write_string (filename, file, + "\n\n" + "This configuration for the debug log can be re-created\n" + "by putting the following in ~/nautilus-debug-log.conf\n" + "(use ';' to separate domain names):\n\n", + error)) { + return FALSE; + } + + success = FALSE; + + key_file = make_key_file_from_configuration (); + + data = g_key_file_to_data (key_file, &length, error); + if (!data) + goto out; + + if (!write_string (filename, file, data, error)) { + goto out; + } + + success = TRUE; + out: + g_key_file_free (key_file); + return success; +} + +static gboolean +dump_milestones (const char *filename, FILE *file, GError **error) +{ + GSList *l; + + if (!write_string (filename, file, "===== BEGIN MILESTONES =====\n", error)) + return FALSE; + + for (l = milestones_head; l; l = l->next) { + const char *str; + + str = l->data; + if (!(write_string (filename, file, str, error) + && write_string (filename, file, "\n", error))) + return FALSE; + } + + if (!write_string (filename, file, "===== END MILESTONES =====\n", error)) + return FALSE; + + return TRUE; +} + +static gboolean +dump_ring_buffer (const char *filename, FILE *file, GError **error) +{ + int start_index; + int i; + + if (!write_string (filename, file, "===== BEGIN RING BUFFER =====\n", error)) + return FALSE; + + if (ring_buffer_num_lines == ring_buffer_max_lines) + start_index = ring_buffer_next_index; + else + start_index = 0; + + for (i = 0; i < ring_buffer_num_lines; i++) { + int idx; + + idx = (start_index + i) % ring_buffer_max_lines; + + if (!(write_string (filename, file, ring_buffer[idx], error) + && write_string (filename, file, "\n", error))) { + return FALSE; + } + } + + if (!write_string (filename, file, "===== END RING BUFFER =====\n", error)) + return FALSE; + + return TRUE; +} + +gboolean +nautilus_debug_log_dump (const char *filename, GError **error) +{ + FILE *file; + gboolean success; + + g_assert (error == NULL || *error == NULL); + + lock (); + + success = FALSE; + + file = fopen (filename, "w"); + if (!file) { + int saved_errno; + + saved_errno = errno; + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (saved_errno), + "could not open log file %s", filename); + goto out; + } + + if (!(dump_milestones (filename, file, error) + && dump_ring_buffer (filename, file, error) + && dump_configuration (filename, file, error))) { + goto do_close; + } + + success = TRUE; + + do_close: + + if (fclose (file) != 0) { + int saved_errno; + + saved_errno = errno; + + if (error && *error) { + g_error_free (*error); + *error = NULL; + } + + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (saved_errno), + "error when closing log file %s", filename); + success = FALSE; + } + + out: + + unlock (); + return success; +} + +void +nautilus_debug_log_set_max_lines (int num_lines) +{ + char **new_buffer; + int lines_to_copy; + + g_assert (num_lines > 0); + + lock (); + + if (num_lines == ring_buffer_max_lines) + goto out; + + new_buffer = g_new0 (char *, num_lines); + + lines_to_copy = MIN (num_lines, ring_buffer_num_lines); + + if (ring_buffer) { + int start_index; + int i; + + if (ring_buffer_num_lines == ring_buffer_max_lines) + start_index = (ring_buffer_next_index + ring_buffer_max_lines - lines_to_copy) % ring_buffer_max_lines; + else + start_index = ring_buffer_num_lines - lines_to_copy; + + g_assert (start_index >= 0 && start_index < ring_buffer_max_lines); + + for (i = 0; i < lines_to_copy; i++) { + int idx; + + idx = (start_index + i) % ring_buffer_max_lines; + + new_buffer[i] = ring_buffer[idx]; + ring_buffer[idx] = NULL; + } + + for (i = 0; i < ring_buffer_max_lines; i++) + g_free (ring_buffer[i]); + + g_free (ring_buffer); + } + + ring_buffer = new_buffer; + ring_buffer_next_index = lines_to_copy; + ring_buffer_num_lines = lines_to_copy; + ring_buffer_max_lines = num_lines; + + out: + + unlock (); +} + +int +nautilus_debug_log_get_max_lines (void) +{ + int retval; + + lock (); + retval = ring_buffer_max_lines; + unlock (); + + return retval; +} + +void +nautilus_debug_log_clear (void) +{ + int i; + + lock (); + + if (!ring_buffer) + goto out; + + for (i = 0; i < ring_buffer_max_lines; i++) { + g_free (ring_buffer[i]); + ring_buffer[i] = NULL; + } + + ring_buffer_next_index = 0; + ring_buffer_num_lines = 0; + + out: + unlock (); +} --- nautilus-orig/libnautilus-private/Makefile.am 2006-09-22 20:14:18.000000000 -0500 +++ nautilus-debug/libnautilus-private/Makefile.am 2006-10-03 10:52:16.000000000 -0500 @@ -63,6 +63,8 @@ libnautilus_private_la_SOURCES = \ nautilus-column-utilities.h \ nautilus-customization-data.c \ nautilus-customization-data.h \ + nautilus-debug-log.c \ + nautilus-debug-log.h \ nautilus-default-file-icon.c \ nautilus-default-file-icon.h \ nautilus-desktop-directory-file.c \ --- nautilus-orig/libnautilus-private/nautilus-icon-dnd.c 2005-09-19 04:59:50.000000000 -0500 +++ nautilus-debug/libnautilus-private/nautilus-icon-dnd.c 2006-10-03 15:35:08.000000000 -0500 @@ -31,6 +31,7 @@ #include <math.h> #include "nautilus-icon-dnd.h" +#include "nautilus-debug-log.h" #include "nautilus-file-dnd.h" #include "nautilus-icon-private.h" #include "nautilus-link.h" @@ -557,8 +558,15 @@ receive_dropped_color (NautilusIconConta GtkSelectionData *data) { action = get_background_drag_action (container, action); - + if (action > 0) { + char *uri; + + uri = get_container_uri (container); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "dropped color on icon container displaying %s", uri); + g_free (uri); + eel_background_receive_dropped_color (eel_get_widget_background (GTK_WIDGET (container)), GTK_WIDGET (container), @@ -575,6 +583,13 @@ receive_dropped_tile_image (NautilusIcon action = get_background_drag_action (container, action); if (action > 0) { + char *uri; + + uri = get_container_uri (container); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "dropped tile image on icon container displaying %s", uri); + g_free (uri); + eel_background_receive_dropped_background_image (eel_get_widget_background (GTK_WIDGET (container)), action, @@ -609,6 +624,11 @@ receive_dropped_keyword (NautilusIconCon * so we don't have to worry about async. issues here. */ uri = nautilus_icon_container_get_icon_uri (container, drop_target_icon); + + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "dropped emblem '%s' on icon container URI: %s", + keyword, uri); + file = nautilus_file_get (uri); g_free (uri); @@ -639,7 +659,7 @@ receive_dropped_uri_list (NautilusIconCo if (uri_list == NULL) { return; } - + g_signal_emit_by_name (container, "handle_uri_list", uri_list, action, --- nautilus-orig/libnautilus-private/nautilus-icon-container.c 2006-09-22 20:14:20.000000000 -0500 +++ nautilus-debug/libnautilus-private/nautilus-icon-container.c 2006-10-03 15:17:01.000000000 -0500 @@ -29,6 +29,7 @@ #include <math.h> #include "nautilus-icon-container.h" +#include "nautilus-debug-log.h" #include "nautilus-global-preferences.h" #include "nautilus-icon-private.h" #include "nautilus-lib-self-check-functions.h" @@ -3547,6 +3548,8 @@ button_release_event (GtkWidget *widget, nautilus_icon_container_did_not_drag (container, event); } else { nautilus_icon_dnd_end_drag (container); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "end drag from icon container"); } break; case DRAG_STATE_STRETCH: @@ -3618,6 +3621,9 @@ motion_notify_event (GtkWidget *widget, event, canvas_x, canvas_y); + + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "begin drag from icon container"); } break; case DRAG_STATE_STRETCH: --- nautilus-orig/libnautilus-private/nautilus-file-operations.c 2006-09-22 20:14:20.000000000 -0500 +++ nautilus-debug/libnautilus-private/nautilus-file-operations.c 2006-10-03 16:15:54.000000000 -0500 @@ -30,6 +30,7 @@ #include <locale.h> #include "nautilus-file-operations.h" +#include "nautilus-debug-log.h" #include "nautilus-file-operations-progress.h" #include "nautilus-lib-self-check-functions.h" @@ -1938,6 +1939,33 @@ nautilus_file_operations_copy_move (cons g_assert (item_uris != NULL); + { + const char *action_str; + + switch (copy_action) { + case GDK_ACTION_COPY: + action_str = "copy"; + break; + + case GDK_ACTION_MOVE: + action_str = "move"; + break; + + case GDK_ACTION_LINK: + action_str = "link"; + break; + + default: + action_str = "[unknown action]"; + break; + } + + nautilus_debug_log_with_uri_list (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, item_uris, + "%s the following URIs to \"%s\":", + action_str, + target_dir ? target_dir : "[empty location]"); + } + target_dir_uri = NULL; trash_dir_uri = NULL; result = GNOME_VFS_OK; @@ -2367,6 +2395,9 @@ nautilus_file_operations_new_folder (Gtk char *dirname; NewFolderTransferState *state; + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "create an untitled folder in \"%s\"", parent_dir); + state = g_new (NewFolderTransferState, 1); state->done_callback = done_callback; state->data = data; @@ -2542,6 +2573,10 @@ nautilus_file_operations_new_file_from_t g_assert (parent_dir != NULL); g_assert (template_uri != NULL); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "create new file \"%s\" from template \"%s\" in \"%s\"", + target_filename, template_uri, parent_dir); + state = g_new (NewFileTransferState, 1); state->done_callback = done_callback; state->data = data; @@ -2628,6 +2663,10 @@ nautilus_file_operations_new_file (GtkWi char *target_filename; int fd; + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "create new file in \"%s\"", + parent_dir); + fd = mkstemp (source_file_str); if (fd == -1) { (*done_callback) (NULL, data); @@ -2673,6 +2712,9 @@ nautilus_file_operations_delete (const G NautilusFile *file; TransferInfo *transfer_info; + nautilus_debug_log_with_uri_list (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, item_uris, + "delete files:"); + uri_list = NULL; for (p = item_uris; p != NULL; p = p->next) { item_uri = (const char *) p->data; @@ -2737,6 +2779,9 @@ do_empty_trash (GtkWidget *parent_view) TransferInfo *transfer_info; GList *trash_dir_list; + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "empty trash"); + trash_dir_list = nautilus_trash_monitor_get_trash_directories (); if (trash_dir_list != NULL) { /* set up the move parameters */ --- nautilus-orig/src/file-manager/fm-directory-view.c 2006-09-22 20:14:20.000000000 -0500 +++ nautilus-debug/src/file-manager/fm-directory-view.c 2006-10-16 16:06:23.000000000 -0500 @@ -75,6 +75,7 @@ #include <libnautilus-private/nautilus-recent.h> #include <libnautilus-extension/nautilus-menu-provider.h> #include <libnautilus-private/nautilus-clipboard-monitor.h> +#include <libnautilus-private/nautilus-debug-log.h> #include <libnautilus-private/nautilus-desktop-icon-file.h> #include <libnautilus-private/nautilus-desktop-directory.h> #include <libnautilus-private/nautilus-directory-background.h> @@ -659,16 +660,21 @@ fm_directory_view_launch_application (Gn { char *uri; GnomeVFSURI *vfs_uri; + GtkWindow *window; g_assert (application != NULL); g_assert (NAUTILUS_IS_FILE (file)); g_assert (FM_IS_DIRECTORY_VIEW (directory_view)); + uri = nautilus_file_get_uri (file); + + window = fm_directory_view_get_containing_window (directory_view); + nautilus_launch_application - (application, file, - fm_directory_view_get_containing_window (directory_view)); + (application, file, window); - uri = nautilus_file_get_uri (file); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "directory_view_launch_application window=%p: %s", window, uri); /* Only add real gnome-vfs uris to recent. Not things like trash:// and x-nautilus-desktop:// */ @@ -711,6 +717,7 @@ open_location (FMDirectoryView *director NautilusWindowOpenFlags flags) { NautilusFile *file; + GtkWindow *window; g_assert (FM_IS_DIRECTORY_VIEW (directory_view)); g_assert (new_uri != NULL); @@ -725,7 +732,10 @@ open_location (FMDirectoryView *director monitor_file_for_open_with (directory_view, NULL); } nautilus_file_unref (file); - + + window = fm_directory_view_get_containing_window (directory_view); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "directory view open_location window=%p: %s", window, new_uri); nautilus_window_info_open_location (directory_view->details->window, new_uri, mode, flags, NULL); } @@ -1150,6 +1160,7 @@ action_new_launcher_callback (GtkAction { char *parent_uri; FMDirectoryView *view; + GtkWindow *window; g_assert (FM_IS_DIRECTORY_VIEW (callback_data)); @@ -1157,6 +1168,9 @@ action_new_launcher_callback (GtkAction parent_uri = fm_directory_view_get_backing_uri (view); + window = fm_directory_view_get_containing_window (view); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "directory view create new launcher in window=%p: %s", window, parent_uri); nautilus_launch_application_from_command (gtk_widget_get_screen (GTK_WIDGET (view)), "gnome-desktop-item-edit", "gnome-desktop-item-edit --create-new", @@ -2705,8 +2719,19 @@ files_added_callback (NautilusDirectory gpointer callback_data) { FMDirectoryView *view; + GtkWindow *window; + char *uri; view = FM_DIRECTORY_VIEW (callback_data); + + window = fm_directory_view_get_containing_window (view); + uri = fm_directory_view_get_uri (view); + nautilus_debug_log_with_file_list (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_ASYNC, files, + "files added in window %p: %s", + window, + uri ? uri : "(no directory)"); + g_free (uri); + queue_pending_files (view, files, &view->details->new_added_files); /* The number of items could have changed */ @@ -2719,8 +2744,19 @@ files_changed_callback (NautilusDirector gpointer callback_data) { FMDirectoryView *view; + GtkWindow *window; + char *uri; view = FM_DIRECTORY_VIEW (callback_data); + + window = fm_directory_view_get_containing_window (view); + uri = fm_directory_view_get_uri (view); + nautilus_debug_log_with_file_list (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_ASYNC, files, + "files changed in window %p: %s", + window, + uri ? uri : "(no directory)"); + g_free (uri); + queue_pending_files (view, files, &view->details->new_changed_files); /* The free space or the number of items could have changed */ @@ -4808,6 +4844,7 @@ run_script_callback (GtkAction *action, char *quoted_path; char *old_working_dir; char *parameters, *command, *name; + GtkWindow *window; launch_parameters = (ScriptLaunchParameters *) callback_data; @@ -4844,6 +4881,10 @@ run_script_callback (GtkAction *action, name = nautilus_file_get_name (launch_parameters->file); /* FIXME: handle errors with dialog? Or leave up to each script? */ + window = fm_directory_view_get_containing_window (launch_parameters->directory_view); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "directory view run_script_callback, window=%p, name=\"%s\", command=\"%s\"", + window, name, command); nautilus_launch_application_from_command (screen, name, command, NULL, FALSE); g_free (name); g_free (command); @@ -7109,9 +7150,17 @@ fm_directory_view_notify_selection_chang { NautilusFile *file; GList *selection; + GtkWindow *window; g_return_if_fail (FM_IS_DIRECTORY_VIEW (view)); + selection = fm_directory_view_get_selection (view); + + window = fm_directory_view_get_containing_window (view); + nautilus_debug_log_with_file_list (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, selection, + "selection changed in window %p", + window); + view->details->selection_was_removed = FALSE; if (!view->details->selection_change_is_due_to_shell) { @@ -7140,7 +7189,6 @@ fm_directory_view_notify_selection_chang /* If there's exactly one item selected we sniff the slower attributes needed * to activate a file ahead of time to improve interactive response. */ - selection = fm_directory_view_get_selection (view); if (eel_g_list_exactly_one_item (selection)) { file = NAUTILUS_FILE (selection->data); @@ -7159,9 +7207,9 @@ fm_directory_view_notify_selection_chang NULL, NULL); } - - nautilus_file_list_free (selection); } + + nautilus_file_list_free (selection); } static gboolean @@ -7293,6 +7341,7 @@ activate_callback (NautilusFile *file, g char *old_working_dir; ActivationAction action; GdkScreen *screen; + GtkWindow *window; parameters = callback_data; @@ -7304,7 +7353,6 @@ activate_callback (NautilusFile *file, g || nautilus_file_get_file_info_result (file) == GNOME_VFS_ERROR_CANCELLED) { nautilus_file_unref (file); g_free (parameters); - return; } @@ -7320,10 +7368,15 @@ activate_callback (NautilusFile *file, g */ action = get_executable_text_file_action (view, file); } + + window = fm_directory_view_get_containing_window (parameters->view); switch (action) { case ACTIVATION_ACTION_LAUNCH_DESKTOP_FILE : file_uri = nautilus_file_get_uri (file); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "directory view activate_callback launch_desktop_file window=%p: %s", + window, file_uri); nautilus_launch_desktop_file ( screen, file_uri, NULL, fm_directory_view_get_containing_window (view)); @@ -7331,6 +7384,9 @@ activate_callback (NautilusFile *file, g break; case ACTIVATION_ACTION_LAUNCH_APPLICATION_FROM_COMMAND : uri += strlen (NAUTILUS_COMMAND_SPECIFIER); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "directory view activate_callback launch_application_from_command window=%p: %s", + window, uri); nautilus_launch_application_from_command (screen, NULL, uri, NULL, FALSE); break; case ACTIVATION_ACTION_LAUNCH : @@ -7340,6 +7396,10 @@ activate_callback (NautilusFile *file, g executable_path = gnome_vfs_get_local_path_from_uri (uri); quoted_path = g_shell_quote (executable_path); name = nautilus_file_get_name (file); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "directory view activate_callback launch_application_from_command " + "window=%p, name=\"%s\", quoted_path=\"%s\"", + window, name, quoted_path); nautilus_launch_application_from_command (screen, name, quoted_path, NULL, (action == ACTIVATION_ACTION_LAUNCH_IN_TERMINAL) /* use terminal */ ); @@ -7352,9 +7412,15 @@ activate_callback (NautilusFile *file, g break; case ACTIVATION_ACTION_OPEN_IN_VIEW : + /* no need to log here; we already do it in open_location() */ open_location (view, uri, parameters->mode, parameters->flags); break; case ACTIVATION_ACTION_OPEN_IN_APPLICATION : + file_uri = nautilus_file_get_uri (file); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "directory view launch_show_file window=%p: %s", + window, file_uri); + nautilus_launch_show_file (file, fm_directory_view_get_containing_window (view)); @@ -7367,10 +7433,10 @@ activate_callback (NautilusFile *file, g /* We should not add trash and directory uris.*/ if ((!nautilus_file_is_in_trash (file)) && (!nautilus_file_is_directory (file))) { - file_uri = nautilus_file_get_uri (file); egg_recent_model_add (nautilus_recent_get_model (), file_uri); - g_free (file_uri); } + + g_free (file_uri); break; case ACTIVATION_ACTION_DO_NOTHING : break; @@ -7619,6 +7685,25 @@ fm_directory_view_activate_files (FMDire g_return_if_fail (FM_IS_DIRECTORY_VIEW (view)); + { + GList *l; + GtkWindow *window; + + window = fm_directory_view_get_containing_window (view); + + for (l = files; l; l = l->next) { + NautilusFile *file; + char *uri; + + file = NAUTILUS_FILE (l->data); + uri = nautilus_file_get_uri (file); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "fm_directory_view_activate_files window=%p: %s", + window, uri); + g_free (uri); + } + } + /* If there's a single file to activate, check user's preference whether * to open it in this window or a new window. If there is more than one * file to activate, open each one in a new window. Don't try to choose --- nautilus-orig/src/file-manager/fm-tree-view.c 2006-09-22 20:14:20.000000000 -0500 +++ nautilus-debug/src/file-manager/fm-tree-view.c 2006-10-03 10:52:16.000000000 -0500 @@ -60,6 +60,7 @@ #include <libgnomevfs/gnome-vfs-utils.h> #include <libgnomevfs/gnome-vfs-volume-monitor.h> #include <libnautilus-private/nautilus-clipboard-monitor.h> +#include <libnautilus-private/nautilus-debug-log.h> #include <libnautilus-private/nautilus-file-attributes.h> #include <libnautilus-private/nautilus-file-operations.h> #include <libnautilus-private/nautilus-global-preferences.h> @@ -345,12 +346,18 @@ got_activation_uri_callback (NautilusFil && eel_str_has_prefix (uri, NAUTILUS_COMMAND_SPECIFIER)) { uri += strlen (NAUTILUS_COMMAND_SPECIFIER); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "tree view launch_application_from_command window=%p: %s", + view->details->window, uri); nautilus_launch_application_from_command (screen, NULL, uri, NULL, FALSE); } else if (uri != NULL && eel_str_has_prefix (uri, NAUTILUS_DESKTOP_COMMAND_SPECIFIER)) { file_uri = nautilus_file_get_uri (file); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "tree view launch_desktop_file window=%p: %s", + view->details->window, file_uri); nautilus_launch_desktop_file (screen, file_uri, NULL, NULL); g_free (file_uri); @@ -363,6 +370,9 @@ got_activation_uri_callback (NautilusFil /* Non-local executables don't get launched. They act like non-executables. */ if (file_uri == NULL) { + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "tree view window_info_open_location window=%p: %s", + view->details->window, uri); nautilus_window_info_open_location (view->details->window, uri, @@ -370,6 +380,9 @@ got_activation_uri_callback (NautilusFil 0, NULL); } else { + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "tree view launch_application_from_command window=%p: %s", + view->details->window, file_uri); nautilus_launch_application_from_command (screen, NULL, file_uri, NULL, FALSE); g_free (file_uri); } @@ -381,6 +394,9 @@ got_activation_uri_callback (NautilusFil g_free (view->details->selection_location); } view->details->selection_location = g_strdup (uri); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "tree view window_info_open_location window=%p: %s", + view->details->window, uri); nautilus_window_info_open_location (view->details->window, uri, --- nautilus-orig/src/nautilus-places-sidebar.c 2006-09-22 20:14:20.000000000 -0500 +++ nautilus-debug/src/nautilus-places-sidebar.c 2006-10-03 10:52:16.000000000 -0500 @@ -43,6 +43,7 @@ #include <libgnome/gnome-macros.h> #include <libgnome/gnome-i18n.h> #include <libnautilus-private/nautilus-bookmark.h> +#include <libnautilus-private/nautilus-debug-log.h> #include <libnautilus-private/nautilus-global-preferences.h> #include <libnautilus-private/nautilus-sidebar-provider.h> #include <libnautilus-private/nautilus-module.h> @@ -406,6 +407,9 @@ row_activated_callback (GtkTreeView *tre (model, &iter, PLACES_SIDEBAR_COLUMN_URI, &uri, -1); if (uri != NULL) { + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "activate from places sidebar window=%p: %s", + sidebar->window, uri); /* Navigate to the clicked location. */ nautilus_window_info_open_location (sidebar->window, @@ -416,6 +420,14 @@ row_activated_callback (GtkTreeView *tre gtk_tree_model_get (model, &iter, PLACES_SIDEBAR_COLUMN_DRIVE, &drive, -1); if (drive != NULL) { + char *path; + + path = gnome_vfs_drive_get_device_path (drive); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "activate drive from places sidebar window=%p: %s", + sidebar->window, path); + g_free (path); + gnome_vfs_drive_mount (drive, mount_volume_callback, sidebar); gnome_vfs_drive_unref (drive); } --- nautilus-orig/src/nautilus-window-manage-views.c 2006-09-22 20:14:19.000000000 -0500 +++ nautilus-debug/src/nautilus-window-manage-views.c 2006-10-03 10:52:16.000000000 -0500 @@ -53,6 +53,7 @@ #include <libgnomevfs/gnome-vfs-async-ops.h> #include <libgnomevfs/gnome-vfs-uri.h> #include <libgnomevfs/gnome-vfs-utils.h> +#include <libnautilus-private/nautilus-debug-log.h> #include <libnautilus-private/nautilus-file-attributes.h> #include <libnautilus-private/nautilus-file-utilities.h> #include <libnautilus-private/nautilus-file.h> @@ -444,9 +445,18 @@ nautilus_window_open_location_full (Naut { NautilusWindow *target_window; gboolean do_load_location = TRUE; + char *old_location; target_window = NULL; + old_location = nautilus_window_get_location (window); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "window %p open location: old=\"%s\", new=\"%s\"", + window, + old_location ? old_location : "(none)", + location); + g_free (old_location); + switch (mode) { case NAUTILUS_WINDOW_OPEN_ACCORDING_TO_MODE : if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER)) { @@ -1232,6 +1242,15 @@ nautilus_window_report_load_complete (Na static void end_location_change (NautilusWindow *window) { + char *location; + + location = nautilus_window_get_location (window); + if (location) { + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "finished loading window %p: %s", window, location); + g_free (location); + } + nautilus_window_allow_stop (window, FALSE); /* Now we can free pending_scroll_to, since the load_complete @@ -1497,11 +1516,18 @@ nautilus_window_set_content_view (Nautil const char *id) { NautilusFile *file; + char *location; g_return_if_fail (NAUTILUS_IS_WINDOW (window)); g_return_if_fail (window->details->location != NULL); g_return_if_fail (id != NULL); + location = nautilus_window_get_location (window); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "change view of window %p: \"%s\" to \"%s\"", + window, location, id); + g_free (location); + if (nautilus_window_content_view_matches_iid (window, id)) { return; } @@ -1681,6 +1707,7 @@ nautilus_navigation_window_back_or_forwa bookmark = g_list_nth_data (list, distance); uri = nautilus_bookmark_get_uri (bookmark); scroll_pos = nautilus_bookmark_get_scroll_pos (bookmark); + begin_location_change (NAUTILUS_WINDOW (window), uri, NULL, --- nautilus-orig/src/file-manager/fm-list-view.c 2005-11-14 08:46:57.000000000 -0600 +++ nautilus-debug/src/file-manager/fm-list-view.c 2006-10-03 10:52:16.000000000 -0500 @@ -55,6 +55,7 @@ #include <libnautilus-extension/nautilus-column-provider.h> #include <libnautilus-private/nautilus-column-chooser.h> #include <libnautilus-private/nautilus-column-utilities.h> +#include <libnautilus-private/nautilus-debug-log.h> #include <libnautilus-private/nautilus-directory-background.h> #include <libnautilus-private/nautilus-dnd.h> #include <libnautilus-private/nautilus-file-dnd.h> @@ -895,6 +896,15 @@ row_expanded_callback (GtkTreeView *tree view = FM_LIST_VIEW (callback_data); if (fm_list_model_load_subdirectory (view->details->model, path, &directory)) { + char *uri; + + uri = nautilus_directory_get_uri (directory); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "list view row expanded window=%p: %s", + fm_directory_view_get_containing_window (FM_DIRECTORY_VIEW (view)), + uri); + g_free (uri); + fm_directory_view_add_subdirectory (FM_DIRECTORY_VIEW (view), directory); if (nautilus_directory_are_all_files_seen (directory)) { @@ -951,6 +961,7 @@ row_collapsed_callback (GtkTreeView *tre FMListView *view; NautilusFile *file; struct UnloadDelayData *unload_data; + char *uri; view = FM_LIST_VIEW (callback_data); @@ -958,6 +969,13 @@ row_collapsed_callback (GtkTreeView *tre iter, FM_LIST_MODEL_FILE_COLUMN, &file, -1); + + uri = nautilus_file_get_uri (file); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "list view row collapsed window=%p: %s", + fm_directory_view_get_containing_window (FM_DIRECTORY_VIEW (view)), + uri); + g_free (uri); unload_data = g_new (struct UnloadDelayData, 1); unload_data->view = view; --- nautilus-orig/src/file-manager/fm-error-reporting.c 2006-09-22 20:14:20.000000000 -0500 +++ nautilus-debug/src/file-manager/fm-error-reporting.c 2006-10-03 10:52:16.000000000 -0500 @@ -29,6 +29,7 @@ #include <string.h> #include <libgnome/gnome-i18n.h> #include <libgnomevfs/gnome-vfs-result.h> +#include <libnautilus-private/nautilus-debug-log.h> #include <libnautilus-private/nautilus-file.h> #include <eel/eel-string.h> #include <eel/eel-stock-dialogs.h> @@ -304,6 +305,7 @@ fm_rename_file (NautilusFile *file, const char *new_name) { char *old_name, *wait_message; + char *uri; g_return_if_fail (NAUTILUS_IS_FILE (file)); g_return_if_fail (new_name != NULL); @@ -328,6 +330,12 @@ fm_rename_file (NautilusFile *file, NULL); /* FIXME bugzilla.gnome.org 42395: Parent this? */ g_free (wait_message); + uri = nautilus_file_get_uri (file); + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "rename file old=\"%s\", new=\"%s\"", + uri, new_name); + g_free (uri); + /* Start the rename. */ nautilus_file_rename (file, new_name, rename_callback, NULL); --- nautilus-orig/src/nautilus-application.c 2006-09-22 20:14:20.000000000 -0500 +++ nautilus-debug/src/nautilus-application.c 2006-10-03 10:52:16.000000000 -0500 @@ -75,6 +75,7 @@ #include <libgnomevfs/gnome-vfs-ops.h> #include <libgnomevfs/gnome-vfs-utils.h> #include <libgnomevfs/gnome-vfs-volume-monitor.h> +#include <libnautilus-private/nautilus-debug-log.h> #include <libnautilus-private/nautilus-file-utilities.h> #include <libnautilus-private/nautilus-global-preferences.h> #include <libnautilus-private/nautilus-icon-factory.h> @@ -1139,6 +1140,10 @@ nautilus_application_present_spatial_win if (new_selection) { nautilus_view_set_selection (existing_window->content_view, new_selection); } + + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "present EXISTING spatial window=%p: %s", + existing_window, location); return existing_window; } } @@ -1176,6 +1181,10 @@ nautilus_application_present_spatial_win spatial_window_destroyed_callback, NULL); nautilus_window_go_to_with_selection (window, location, new_selection); + + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "present NEW spatial window=%p: %s", + window, location); return window; } @@ -1195,6 +1204,10 @@ nautilus_application_create_navigation_w startup_id); #endif + nautilus_debug_log (FALSE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "create new navigation window=%p", + window); + return window; } --- nautilus-no-debug-log/src/nautilus-main.c 2006-11-10 16:39:41.000000000 -0600 +++ nautilus-2.12.2/src/nautilus-main.c 2006-12-12 10:02:27.000000000 -0600 @@ -37,6 +37,7 @@ #include <bonobo-activation/bonobo-activation.h> #include <bonobo/bonobo-main.h> #include <dlfcn.h> +#include <signal.h> #include <eel/eel-debug.h> #include <eel/eel-glib-extensions.h> #include <eel/eel-self-checks.h> @@ -49,6 +50,7 @@ #include <libgnome/gnome-init.h> #include <libgnomeui/gnome-ui-init.h> #include <libgnomevfs/gnome-vfs-init.h> +#include <libnautilus-private/nautilus-debug-log.h> #include <libnautilus-private/nautilus-directory-metafile.h> #include <libnautilus-private/nautilus-global-preferences.h> #include <libnautilus-private/nautilus-lib-self-check-functions.h> @@ -214,6 +216,157 @@ slowly_and_stupidly_obtain_timestamp (Di return event.xproperty.time; } +static void +dump_debug_log (void) +{ + char *filename; + + filename = g_build_filename (g_get_home_dir (), "nautilus-debug-log.txt", NULL); + nautilus_debug_log_dump (filename, NULL); /* NULL GError */ + g_free (filename); +} + +static int debug_log_pipes[2]; + +static gboolean +debug_log_io_cb (GIOChannel *io, GIOCondition condition, gpointer data) +{ + char a; + + while (read (debug_log_pipes[0], &a, 1) != 1) + ; + + nautilus_debug_log (TRUE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "user requested dump of debug log"); + + dump_debug_log (); + return FALSE; +} + +/* sigaction structures for the old handlers of these signals */ +static struct sigaction old_segv_sa; +static struct sigaction old_abrt_sa; +static struct sigaction old_trap_sa; +static struct sigaction old_fpe_sa; +static struct sigaction old_bus_sa; + +static void +sigusr1_handler (int sig) +{ + while (write (debug_log_pipes[1], "a", 1) != 1) + ; +} + +static void +sigfatal_handler (int sig) +{ + void (* func) (int); + + /* FIXME: is this totally busted? We do malloc() inside these functions, + * and yet we are inside a signal handler... + */ + nautilus_debug_log (TRUE, NAUTILUS_DEBUG_LOG_DOMAIN_USER, + "debug log dumped due to signal %d", sig); + dump_debug_log (); + + switch (sig) { + case SIGSEGV: + func = old_segv_sa.sa_handler; + break; + + case SIGABRT: + func = old_abrt_sa.sa_handler; + break; + + case SIGTRAP: + func = old_trap_sa.sa_handler; + break; + + case SIGFPE: + func = old_fpe_sa.sa_handler; + break; + + case SIGBUS: + func = old_bus_sa.sa_handler; + break; + + default: + func = NULL; + break; + } + + /* this scares me */ + if (func != NULL && func != SIG_IGN && func != SIG_DFL) + (* func) (sig); +} + +static void +setup_debug_log_signals (void) +{ + struct sigaction sa; + GIOChannel *io; + + if (pipe (debug_log_pipes) == -1) + g_error ("Could not create pipe() for debug log"); + + io = g_io_channel_unix_new (debug_log_pipes[0]); + g_io_add_watch (io, G_IO_IN, debug_log_io_cb, NULL); + + sa.sa_handler = sigusr1_handler; + sigemptyset (&sa.sa_mask); + sa.sa_flags = 0; + sigaction (SIGUSR1, &sa, NULL); + + sa.sa_handler = sigfatal_handler; + sigemptyset (&sa.sa_mask); + sa.sa_flags = 0; + + sigaction(SIGSEGV, &sa, &old_segv_sa); + sigaction(SIGABRT, &sa, &old_abrt_sa); + sigaction(SIGTRAP, &sa, &old_trap_sa); + sigaction(SIGFPE, &sa, &old_fpe_sa); + sigaction(SIGBUS, &sa, &old_bus_sa); +} + +static GLogFunc default_log_handler; + +static void +log_override_cb (const gchar *log_domain, + GLogLevelFlags log_level, + const gchar *message, + gpointer user_data) +{ + gboolean is_debug; + gboolean is_milestone; + + is_debug = ((log_level & G_LOG_LEVEL_DEBUG) != 0); + is_milestone = !is_debug; + + nautilus_debug_log (is_milestone, NAUTILUS_DEBUG_LOG_DOMAIN_GLOG, "%s", message); + + if (!is_debug) + (* default_log_handler) (log_domain, log_level, message, user_data); +} + +static void +setup_debug_log_glog (void) +{ + default_log_handler = g_log_set_default_handler (log_override_cb, NULL); +} + +static void +setup_debug_log (void) +{ + char *config_filename; + + config_filename = g_build_filename (g_get_home_dir (), "nautilus-debug-log.conf", NULL); + nautilus_debug_log_load_configuration (config_filename, NULL); /* NULL GError */ + g_free (config_filename); + + setup_debug_log_signals (); + setup_debug_log_glog (); +} + int main (int argc, char *argv[]) { @@ -305,6 +458,12 @@ main (int argc, char *argv[]) GNOME_PARAM_HUMAN_READABLE_NAME, _("Nautilus"), NULL); + /* We do this after gnome_program_init(), since that function sets up + * its own handler for SIGSEGV and others --- we want to chain to those + * handlers. + */ + setup_debug_log (); + /* Do this here so that gdk_display is initialized */ if (startup_id_copy == NULL) { /* Create a fake one containing a timestamp that we can use */
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor