mirror of https://github.com/GNOME/gimp.git
libgimp: add an exception handler for Windows.
Drmingw already added its own exception handler which generates crash traces in a text file, for plug-ins as well. This additional handler is run after Drmingw handler and allows us to do things on our own, and in particular we could display the content of the debug traces. Right now it simply prints these to stderr, which actually won't be of much use on Win32, first because the console is deactivated on stable releases, also because after tests, it doesn't look like even running GIMP from cmd outputs to console either. We currently don't use the same debug dialog as the core on purpose, because we don't want everyone to send us traces for every unmaintained third party plug-ins out there. But we should definitely allow easier trace possibilities at some point, first to improve/debug our own core plug-ins, and also to help third party plug-in developers! So this commit is not making visible changes yet but is actually a first step towards these debugging goals.
This commit is contained in:
parent
76bce77d09
commit
fa02a2c64f
|
@ -167,7 +167,11 @@ static void gimp_fatal_func (const gchar *log_domain,
|
|||
GLogLevelFlags flags,
|
||||
const gchar *message,
|
||||
gpointer data);
|
||||
#ifndef G_OS_WIN32
|
||||
#ifdef G_OS_WIN32
|
||||
#ifdef HAVE_EXCHNDL
|
||||
static LONG WINAPI gimp_plugin_sigfatal_handler (PEXCEPTION_POINTERS pExceptionInfo);
|
||||
#endif
|
||||
#else
|
||||
static void gimp_plugin_sigfatal_handler (gint sig_num);
|
||||
#endif
|
||||
static gboolean gimp_plugin_io_error_handler (GIOChannel *channel,
|
||||
|
@ -193,8 +197,13 @@ static void gimp_set_pdb_error (const GimpParam *return_vals,
|
|||
gint n_return_vals);
|
||||
|
||||
|
||||
static GIOChannel *_readchannel = NULL;
|
||||
GIOChannel *_writechannel = NULL;
|
||||
#if defined G_OS_WIN32 && defined HAVE_EXCHNDL
|
||||
static LPTOP_LEVEL_EXCEPTION_FILTER _prevExceptionFilter = NULL;
|
||||
static gchar *plug_in_backtrace_path = NULL;
|
||||
#endif
|
||||
|
||||
static GIOChannel *_readchannel = NULL;
|
||||
GIOChannel *_writechannel = NULL;
|
||||
|
||||
#ifdef USE_WIN32_SHM
|
||||
static HANDLE shm_handle;
|
||||
|
@ -332,10 +341,9 @@ gimp_main (const GimpPlugInInfo *info,
|
|||
#ifdef HAVE_EXCHNDL
|
||||
/* Use Dr. Mingw (dumps backtrace on crash) if it is available. */
|
||||
{
|
||||
time_t t;
|
||||
gchar *filename;
|
||||
gchar *dir;
|
||||
gchar *path;
|
||||
time_t t;
|
||||
gchar *filename;
|
||||
gchar *dir;
|
||||
|
||||
/* This has to be the non-roaming directory (i.e., the local
|
||||
directory) as backtraces correspond to the binaries on this
|
||||
|
@ -349,14 +357,18 @@ gimp_main (const GimpPlugInInfo *info,
|
|||
time (&t);
|
||||
filename = g_strdup_printf ("%s-crash-%" G_GUINT64_FORMAT ".txt",
|
||||
g_get_prgname(), t);
|
||||
path = g_build_filename (dir, filename, NULL);
|
||||
plug_in_backtrace_path = g_build_filename (dir, filename, NULL);
|
||||
g_free (filename);
|
||||
g_free (dir);
|
||||
|
||||
ExcHndlInit ();
|
||||
ExcHndlSetLogFileNameA (path);
|
||||
/* Similar to core crash handling in app/signals.c, the order here
|
||||
* is very important!
|
||||
*/
|
||||
if (! _prevExceptionFilter)
|
||||
_prevExceptionFilter = SetUnhandledExceptionFilter (gimp_plugin_sigfatal_handler);
|
||||
|
||||
g_free (path);
|
||||
ExcHndlInit ();
|
||||
ExcHndlSetLogFileNameA (plug_in_backtrace_path);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -672,6 +684,11 @@ gimp_quit (void)
|
|||
{
|
||||
gimp_close ();
|
||||
|
||||
#if defined G_OS_WIN32 && defined HAVE_EXCHNDL
|
||||
if (plug_in_backtrace_path)
|
||||
g_free (plug_in_backtrace_path);
|
||||
#endif
|
||||
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -1986,7 +2003,46 @@ gimp_fatal_func (const gchar *log_domain,
|
|||
*/
|
||||
}
|
||||
|
||||
#ifndef G_OS_WIN32
|
||||
#ifdef G_OS_WIN32
|
||||
|
||||
#ifdef HAVE_EXCHNDL
|
||||
static LONG WINAPI
|
||||
gimp_plugin_sigfatal_handler (PEXCEPTION_POINTERS pExceptionInfo)
|
||||
{
|
||||
g_printerr ("%s: fatal error\n", progname);
|
||||
|
||||
SetUnhandledExceptionFilter (_prevExceptionFilter);
|
||||
|
||||
/* For simplicity, do not make a difference between QUERY and ALWAYS
|
||||
* on Windows (at least not for now).
|
||||
*/
|
||||
if (stack_trace_mode != GIMP_STACK_TRACE_NEVER &&
|
||||
g_file_test (plug_in_backtrace_path, G_FILE_TEST_IS_REGULAR))
|
||||
{
|
||||
FILE *stream;
|
||||
guchar buffer[256];
|
||||
size_t read_len;
|
||||
|
||||
stream = fopen (plug_in_backtrace_path, "r");
|
||||
do
|
||||
{
|
||||
/* Just read and output directly the file content. */
|
||||
read_len = fread (buffer, 1, sizeof (buffer) - 1, stream);
|
||||
buffer[read_len] = '\0';
|
||||
g_printerr ("%s", buffer);
|
||||
}
|
||||
while (read_len);
|
||||
fclose (stream);
|
||||
}
|
||||
|
||||
if (_prevExceptionFilter && _prevExceptionFilter != gimp_plugin_sigfatal_handler)
|
||||
return _prevExceptionFilter (pExceptionInfo);
|
||||
else
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
static void
|
||||
gimp_plugin_sigfatal_handler (gint sig_num)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue