Commit ae3cd00f authored by Jehan's avatar Jehan

app, tools: add support for ExcHndl/DrMinGW for Win32 debugging.

The feature already exists in our code and produces backtraces upon a
crash into a file. The only difference is that we are now getting the
file contents and showing it in our new debug dialog, so that it works
similarly on all platform (and therefore making the debug info visible
to people, otherwise they would never report, even though the data is
generated).
The difference with gdb/lldb is that it doesn't allow backtraces at
random points (for debugging non-fatal yet bad errors). Also the API has
just 2 functions and in particular an ExcHndlInit() but no way to unload
the feature. So we don't need the debugging page in Preferences because
the switch option would not work. On Windows, the feature will be
decided at build time only.

Last point: the code is untested on Windows so far. I assume it would
work, but there is at least one point I am unsure of: will ExcHndl have
already generated the backtrace file when gimpdebug runs? If not, I will
have to let gimp die first to be able to get the backtrace.
parent 015f2fc8
......@@ -173,7 +173,8 @@ app_run (const gchar *full_prog_name,
gboolean use_debug_handler,
gboolean show_playground,
GimpStackTraceMode stack_trace_mode,
GimpPDBCompatMode pdb_compat_mode)
GimpPDBCompatMode pdb_compat_mode,
const gchar *backtrace_file)
{
GimpInitStatusFunc update_status_func = NULL;
Gimp *gimp;
......@@ -247,7 +248,8 @@ app_run (const gchar *full_prog_name,
gimp_cpu_accel_set_use (use_cpu_accel);
errors_init (gimp, full_prog_name, use_debug_handler, stack_trace_mode);
errors_init (gimp, full_prog_name, use_debug_handler,
stack_trace_mode, backtrace_file);
/* Check if the user's gimp_directory exists
*/
......
......@@ -49,7 +49,8 @@ void app_run (const gchar *full_prog_name,
gboolean use_debug_handler,
gboolean show_playground,
GimpStackTraceMode stack_trace_mode,
GimpPDBCompatMode pdb_compat_mode);
GimpPDBCompatMode pdb_compat_mode,
const gchar *backtrace_file);
#endif /* __APP_H__ */
......@@ -1229,6 +1229,11 @@ prefs_dialog_new (Gimp *gimp,
/***************/
/* Debugging */
/***************/
/* No debugging preferences are needed on win32. Either GIMP has been
* built with DrMinGW support (HAVE_EXCHNDL) or not. If it has, then
* the backtracing is enabled and can't be disabled. It assume it will
* work only upon a crash.
*/
#ifndef G_OS_WIN32
vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box),
/* TODO: icon needed. */
......
......@@ -52,6 +52,7 @@ static Gimp *the_errors_gimp = NULL;
static gboolean use_debug_handler = FALSE;
static GimpStackTraceMode stack_trace_mode = GIMP_STACK_TRACE_QUERY;
static gchar *full_prog_name = NULL;
static gchar *backtrace_file = NULL;
/* local function prototypes */
......@@ -82,7 +83,8 @@ void
errors_init (Gimp *gimp,
const gchar *_full_prog_name,
gboolean _use_debug_handler,
GimpStackTraceMode _stack_trace_mode)
GimpStackTraceMode _stack_trace_mode,
const gchar *_backtrace_file)
{
const gchar * const log_domains[] =
{
......@@ -131,6 +133,7 @@ errors_init (Gimp *gimp,
use_debug_handler = _use_debug_handler ? TRUE : FALSE;
stack_trace_mode = _stack_trace_mode;
full_prog_name = g_strdup (_full_prog_name);
backtrace_file = g_strdup (_backtrace_file);
for (i = 0; i < G_N_ELEMENTS (log_domains); i++)
g_log_set_handler (log_domains[i],
......@@ -149,6 +152,9 @@ void
errors_exit (void)
{
the_errors_gimp = NULL;
if (backtrace_file)
g_free (backtrace_file);
}
void
......@@ -283,8 +289,9 @@ gimp_eek (const gchar *reason,
/* If enabled (it is disabled by default), the GUI preference
* takes precedence over the command line argument.
*/
gchar *args[6] = { "gimpdebug-2.0", full_prog_name, NULL,
(gchar *) reason, (gchar *) message, NULL };
gchar *args[7] = { "gimpdebug-2.0", full_prog_name, NULL,
(gchar *) reason, (gchar *) message,
backtrace_file, NULL };
gchar pid[16];
gint exit_status;
......
......@@ -26,7 +26,8 @@
void errors_init (Gimp *gimp,
const gchar *full_prog_name,
gboolean use_debug_handler,
GimpStackTraceMode stack_trace_mode);
GimpStackTraceMode stack_trace_mode,
const gchar *backtrace_file);
void errors_exit (void);
void gimp_fatal_error (const gchar *message) G_GNUC_NORETURN;
......
......@@ -305,6 +305,7 @@ main (int argc,
gchar *basename;
GFile *system_gimprc_file = NULL;
GFile *user_gimprc_file = NULL;
gchar *backtrace_file = NULL;
gint i;
#if defined (__GNUC__) && defined (_WIN64)
......@@ -369,7 +370,6 @@ main (int argc,
time_t t;
gchar *filename;
gchar *dir;
gchar *path;
/* This has to be the non-roaming directory (i.e., the local
directory) as backtraces correspond to the binaries on this
......@@ -383,14 +383,12 @@ main (int argc,
time (&t);
filename = g_strdup_printf ("%s-crash-%" G_GUINT64_FORMAT ".txt",
g_get_prgname(), t);
path = g_build_filename (dir, filename, NULL);
backtrace_file = g_build_filename (dir, filename, NULL);
g_free (filename);
g_free (dir);
ExcHndlInit ();
ExcHndlSetLogFileNameA (path);
g_free (path);
ExcHndlSetLogFileNameA (backtrace_file);
}
#endif
......@@ -567,7 +565,11 @@ main (int argc,
use_debug_handler,
show_playground,
stack_trace_mode,
pdb_compat_mode);
pdb_compat_mode,
backtrace_file);
if (backtrace_file)
g_free (backtrace_file);
if (system_gimprc_file)
g_object_unref (system_gimprc_file);
......
......@@ -10,6 +10,12 @@ bin_PROGRAMS = \
gimptool-2.0 \
gimp-debug-resume
if !ENABLE_GIMP_CONSOLE
if HAVE_EXCHNDL
bin_PROGRAMS += gimpdebug-2.0
endif
endif
gimp_debug_resume_SOURCES = gimp-debug-resume.c
else
......
......@@ -56,13 +56,15 @@ main (int argc,
const gchar *pid;
const gchar *reason;
const gchar *message;
gchar *trace;
const gchar *bt_file = NULL;
gchar *trace = NULL;
gchar *error;
GtkWidget *dialog;
if (argc != 5)
if (argc != 5 && argc != 6)
{
g_print ("Usage: gimpdebug-2.0 [PROGRAM] [PID] [REASON] [MESSAGE]\n");
g_print ("Usage: gimpdebug-2.0 [PROGRAM] [PID] [REASON] [MESSAGE] [BT_FILE]\n\n"
"Note: the backtrace file is optional and only used in Windows.\n");
exit (EXIT_FAILURE);
}
......@@ -70,9 +72,18 @@ main (int argc,
pid = argv[2];
reason = argv[3];
message = argv[4];
error = g_strdup_printf ("%s: %s", reason, message);
trace = gimp_debug_get_stack_trace (program, pid);
if (argc == 6)
{
bt_file = argv[5];
g_file_get_contents (bt_file, &trace, NULL, NULL);
}
else
{
trace = gimp_debug_get_stack_trace (program, pid);
}
if (trace == NULL || strlen (trace) == 0)
exit (EXIT_FAILURE);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment