Commit b8505dcc authored by Manish Singh's avatar Manish Singh Committed by Manish Singh

implemented plug-in debugging hooks. Also, use G_LOG_DOMAIN instead of

2003-02-09  Manish Singh  <yosh@gimp.org>

        * libgimp/gimp.c: implemented plug-in debugging hooks. Also, use
        G_LOG_DOMAIN instead of hardcoding "LibGimp" for g_log_set_handler.

        * devel-docs/debug-plug-ins.txt: documenyed here

        * devel-docs/Makefile.am: add new file
parent 726b75ea
2003-02-09 Manish Singh <yosh@gimp.org>
* libgimp/gimp.c: implemented plug-in debugging hooks. Also, use
G_LOG_DOMAIN instead of hardcoding "LibGimp" for g_log_set_handler.
* devel-docs/debug-plug-ins.txt: documenyed here
* devel-docs/Makefile.am: add new file
2003-02-09 Michael Natterer <mitch@gimp.org>
* app/core/gimpcontext.[ch]: simplified everything a lot by
......
......@@ -9,12 +9,13 @@ SUBDIRS = \
libgimp
EXTRA_DIST = \
ChangeLog \
README \
README.gtkdoc \
gih.txt \
gpb.txt \
includes.txt \
parasites.txt \
undo.txt \
ChangeLog \
README \
README.gtkdoc \
debug-plug-ins.txt \
gih.txt \
gpb.txt \
includes.txt \
parasites.txt \
undo.txt \
xcf.txt
Debugging Plug-ins
==================
Eeek! The plug-in you're working on has a bug in it! And the fix isn't
completely obvious, so you want to use debugger to see what is going on.
But hmm, how does one start a plug-in under a debugger if GIMP is the one
who is starting the plug-in...
To address this issue, libgimp has some hooks controlled by the
GIMP_PLUGIN_DEBUG environment variable. The idea is that you can attach
a debugger to the pid of the plug-in you want to debug. The format is as
follows:
GIMP_PLUGIN_DEBUG=name<,options>
"name" refers to the name of the plug-in binary that you wish to debug.
"options" is one or more of the following options, separated by :'s
run: suspend the plug-in when its run_proc is called.
query: suspend the plug-in when its query_proc is called.
init: suspend the plug-in when its init_proc is called.
pid: just print the pid of the plug-in on run_proc.
fatal-warnings: emulate passing --g-fatal-warnings on the command line.
fw: shorthand for above.
on: shorthand for run:fatal-warnings. This is also the default
in the absence of an options string.
Examples:
GIMP_PLUGIN_DEBUG=blur
When the blur plug-in is called to perform an action, it is suspended
and the following is printed to the console:
(blur:9000): LibGimp-DEBUG: Waiting for debugger...
9000 is the pid of the new plug-in process. You can start your debugger,
attach to it, set breakpoints/watches/etc. and continue from there.
GIMP_PLUGIN_DEBUG=blur,on
Same effect as above.
GIMP_PLUGIN_DEBUG=blur,run:fatal-warnings
Same effect as above.
GIMP_PLUGIN_DEBUG=blur,pid
Prints:
(blur:9000): LibGimp-DEBUG: Here I am!
This simply prints the pid but doesn't halt the plug-in. It is simply
convenience, since if your plug-in has a GUI, the GUI can start up
and you can attach to it there while it is waiting for user input.
GIMP_PLUGIN_DEBUG=blur,query
Same effect as if you did run, but instead suspends when the plug-in
is queried on GIMP startup.
GIMP_PLUGIN_DEBUG=blur,init
Same as above, but in the init phase of startup.
......@@ -89,6 +89,16 @@
#include "gimp.h"
/* Maybe this should go in a public header if we add other things to it */
typedef enum {
GIMP_DEBUG_PID = 1 << 0,
GIMP_DEBUG_FATAL_WARNINGS = 1 << 1,
GIMP_DEBUG_QUERY = 1 << 2,
GIMP_DEBUG_INIT = 1 << 3,
GIMP_DEBUG_RUN = 1 << 4,
GIMP_DEBUG_DEFAULT = (GIMP_DEBUG_RUN | GIMP_DEBUG_FATAL_WARNINGS)
} GimpDebugFlag;
#define WRITE_BUFFER_SIZE 1024
......@@ -98,6 +108,8 @@ void gimp_read_expect_msg (WireMessage *msg,
gint type);
static void gimp_debug_stop (void);
#ifndef G_OS_WIN32
static void gimp_plugin_sigfatal_handler (gint sig_num);
#endif
......@@ -151,6 +163,20 @@ static GimpStackTraceMode stack_trace_mode = GIMP_STACK_TRACE_NEVER;
static GHashTable *temp_proc_ht = NULL;
static guint gimp_debug_flags = 0;
static const GDebugKey gimp_debug_keys[] = {
{"pid", GIMP_DEBUG_PID},
{"fatal-warnings", GIMP_DEBUG_FATAL_WARNINGS},
{"fw", GIMP_DEBUG_FATAL_WARNINGS},
{"query", GIMP_DEBUG_QUERY},
{"init", GIMP_DEBUG_INIT},
{"run", GIMP_DEBUG_RUN},
{"on", GIMP_DEBUG_DEFAULT}
};
static const guint gimp_ndebug_keys = sizeof (gimp_debug_keys) / sizeof (GDebugKey);
#ifdef G_OS_WIN32
static GimpPlugInInfo *PLUG_IN_INFO_PTR;
#define PLUG_IN_INFO (*PLUG_IN_INFO_PTR)
......@@ -176,7 +202,9 @@ int
gimp_main (int argc,
char *argv[])
{
gchar *basename;
gchar *basename;
const gchar *env_string;
gchar *debug_string;
#ifdef G_OS_WIN32
gint i, j, k;
......@@ -228,6 +256,30 @@ gimp_main (int argc,
g_set_prgname (basename);
env_string = g_getenv ("GIMP_PLUGIN_DEBUG");
if (env_string)
{
debug_string = strchr (env_string, ',');
if (debug_string)
{
gint len = debug_string - env_string;
if ((strlen (basename) == len) &&
(strncmp (basename, env_string, len) == 0))
{
gimp_debug_flags = g_parse_debug_string (debug_string + 1,
gimp_debug_keys,
gimp_ndebug_keys);
}
}
else if (strcmp (env_string, basename) == 0)
{
gimp_debug_flags = GIMP_DEBUG_DEFAULT;
}
}
g_free (basename);
stack_trace_mode = (GimpStackTraceMode) CLAMP (atoi (argv[5]),
......@@ -278,7 +330,7 @@ gimp_main (int argc,
/* set handler both for the "LibGimp" and ""
domains */
g_log_set_handler ("LibGimp",
g_log_set_handler (G_LOG_DOMAIN,
G_LOG_LEVEL_MESSAGE,
gimp_message_func,
NULL);
......@@ -287,11 +339,23 @@ gimp_main (int argc,
gimp_message_func,
NULL);
if (gimp_debug_flags & GIMP_DEBUG_FATAL_WARNINGS)
{
GLogLevelFlags fatal_mask;
fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
g_log_set_always_fatal (fatal_mask);
}
if (strcmp (argv[4], "-query") == 0)
{
if (PLUG_IN_INFO.init_proc)
gp_has_init_write (_writechannel, NULL);
if (gimp_debug_flags & GIMP_DEBUG_QUERY)
gimp_debug_stop ();
if (PLUG_IN_INFO.query_proc)
(* PLUG_IN_INFO.query_proc) ();
......@@ -301,6 +365,9 @@ gimp_main (int argc,
if (strcmp (argv[4], "-init") == 0)
{
if (gimp_debug_flags & GIMP_DEBUG_INIT)
gimp_debug_stop ();
if (PLUG_IN_INFO.init_proc)
(* PLUG_IN_INFO.init_proc) ();
......@@ -308,6 +375,11 @@ gimp_main (int argc,
return 0;
}
if (gimp_debug_flags & GIMP_DEBUG_RUN)
gimp_debug_stop ();
else if (gimp_debug_flags & GIMP_DEBUG_PID)
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Here I am!\n");
temp_proc_ht = g_hash_table_new (g_str_hash, g_str_equal);
g_io_add_watch (_readchannel,
......@@ -344,6 +416,17 @@ gimp_quit (void)
exit (0);
}
static void
gimp_debug_stop (void)
{
#ifndef G_OS_WIN32
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Waiting for debugger...\n");
kill (getpid (), SIGSTOP);
#else
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Debugging not implemented on Win32\n");
#endif
}
gint32
gimp_default_display (void)
......
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