Commit 96e7d31f authored by Manish Singh's avatar Manish Singh Committed by Manish Singh
Browse files

added hooks for running plug-ins under a memory debugger. Also, removed

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

        * app/plug-in/plug-in.[ch]: added hooks for running plug-ins under
        a memory debugger. Also, removed the args array from the PlugIn
        structure, replacing with simply a variable for the path to the
        plug-in (and one for a precalculated basename).

        * app/plug-in/plug-in-debug.[ch]: helper routines for the above

        * app/plug-in/plug-in-message.c
        * app/plug-in/plug-in-proc.c
        * app/plug-in/plug-in-progress.c: reflect new and renamed args members

        * app/plug-in/Makefile.am: added plug-in-debug.[ch]

        * app/core/core-types.h: added forward declaration for GimpPlugInDebug

        * app/core/gimp.[ch]: added structure member for GimpPlugInDebug

        * devel-docs/debug-plug-ins.txt: documented new feature
parent d5537906
2003-02-10 Manish Singh <yosh@gimp.org>
* app/plug-in/plug-in.[ch]: added hooks for running plug-ins under
a memory debugger. Also, removed the args array from the PlugIn
structure, replacing with simply a variable for the path to the
plug-in (and one for a precalculated basename).
* app/plug-in/plug-in-debug.[ch]: helper routines for the above
* app/plug-in/plug-in-message.c
* app/plug-in/plug-in-proc.c
* app/plug-in/plug-in-progress.c: reflect new and renamed args members
* app/plug-in/Makefile.am: added plug-in-debug.[ch]
* app/core/core-types.h: added forward declaration for GimpPlugInDebug
* app/core/gimp.[ch]: added structure member for GimpPlugInDebug
* devel-docs/debug-plug-ins.txt: documented new feature
2003-02-10 Sven Neumann <sven@gimp.org>
 
* plug-ins/common/uniteditor.c: use the "cell-background-gdk"
......@@ -122,7 +143,7 @@
* 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/debug-plug-ins.txt: documented here
 
* devel-docs/Makefile.am: add new file
 
......
......@@ -169,6 +169,8 @@ typedef guint32 GimpTattoo;
typedef struct _GimpPaletteEntry GimpPaletteEntry;
typedef struct _GimpPlugInDebug GimpPlugInDebug;
/* EEK stuff */
......
......@@ -200,7 +200,9 @@ gimp_init (Gimp *gimp)
gimp_modules_init (gimp);
gimp->environ_table = gimp_environ_table_new ();
gimp->environ_table = gimp_environ_table_new ();
gimp->plug_in_debug = NULL;
gimp->images = gimp_list_new (GIMP_TYPE_IMAGE,
GIMP_CONTAINER_POLICY_WEAK);
......
......@@ -44,91 +44,93 @@ typedef struct _GimpClass GimpClass;
struct _Gimp
{
GimpObject parent_instance;
GimpObject parent_instance;
GimpCoreConfig *config;
GimpCoreConfig *edit_config; /* don't use this one, it's just
GimpCoreConfig *config;
GimpCoreConfig *edit_config; /* don't use this one, it's just
* for the preferences dialog
*/
gboolean be_verbose;
gboolean no_data;
gboolean no_interface;
gboolean use_shm;
GimpMessageHandlerType message_handler;
GimpStackTraceMode stack_trace_mode;
gboolean be_verbose;
gboolean no_data;
gboolean no_interface;
gboolean use_shm;
GimpMessageHandlerType message_handler;
GimpStackTraceMode stack_trace_mode;
GimpThreadFunc gui_threads_enter_func;
GimpThreadFunc gui_threads_leave_func;
GimpCreateDisplayFunc gui_create_display_func;
GimpSetBusyFunc gui_set_busy_func;
GimpUnsetBusyFunc gui_unset_busy_func;
GimpMessageFunc gui_message_func;
GimpThreadFunc gui_threads_enter_func;
GimpThreadFunc gui_threads_leave_func;
GimpCreateDisplayFunc gui_create_display_func;
GimpSetBusyFunc gui_set_busy_func;
GimpUnsetBusyFunc gui_unset_busy_func;
GimpMessageFunc gui_message_func;
gint busy;
guint busy_idle_id;
gint busy;
guint busy_idle_id;
GList *user_units;
gint n_user_units;
GList *user_units;
gint n_user_units;
GimpParasiteList *parasites;
GimpParasiteList *parasites;
GimpContainer *paint_info_list;
GimpContainer *paint_info_list;
GimpModuleDB *module_db;
gboolean write_modulerc;
GimpModuleDB *module_db;
gboolean write_modulerc;
GimpEnvironTable *environ_table;
GimpEnvironTable *environ_table;
GimpContainer *images;
gint next_image_ID;
guint32 next_guide_ID;
GHashTable *image_table;
GimpPlugInDebug *plug_in_debug;
gint next_item_ID;
GHashTable *item_table;
GimpContainer *images;
gint next_image_ID;
guint32 next_guide_ID;
GHashTable *image_table;
GimpContainer *displays;
gint next_display_ID;
gint next_item_ID;
GHashTable *item_table;
GimpBuffer *global_buffer;
GimpContainer *named_buffers;
GimpContainer *displays;
gint next_display_ID;
GimpDataFactory *brush_factory;
GimpDataFactory *pattern_factory;
GimpDataFactory *gradient_factory;
GimpDataFactory *palette_factory;
GimpBuffer *global_buffer;
GimpContainer *named_buffers;
GimpDataFactory *brush_factory;
GimpDataFactory *pattern_factory;
GimpDataFactory *gradient_factory;
GimpDataFactory *palette_factory;
GHashTable *procedural_ht;
GList *procedural_db_data_list;
GHashTable *procedural_ht;
GList *procedural_db_data_list;
GSList *load_procs;
GSList *save_procs;
GimpContainer *tool_info_list;
GimpToolInfo *standard_tool_info;
GSList *load_procs;
GSList *save_procs;
GimpContainer *tool_info_list;
GimpToolInfo *standard_tool_info;
/* the opened and saved images in MRU order */
GimpContainer *documents;
GimpContainer *documents;
/* image_new values */
GimpImageNewValues image_new_last_values;
gboolean have_current_cut_buffer;
GimpImageNewValues image_new_last_values;
gboolean have_current_cut_buffer;
/* the list of all contexts */
GList *context_list;
GList *context_list;
/* the hardcoded standard context */
GimpContext *standard_context;
GimpContext *standard_context;
/* the default context which is initialized from gimprc */
GimpContext *default_context;
GimpContext *default_context;
/* the context used by the interface */
GimpContext *user_context;
GimpContext *user_context;
/* the currently active context */
GimpContext *current_context;
GimpContext *current_context;
};
struct _GimpClass
......
......@@ -96,7 +96,7 @@ plug_in_proc_def_get_progname (PlugInProcDef *proc_def)
return proc_def->prog;
case GIMP_TEMPORARY:
return ((PlugIn *) proc_def->db_info.exec_method.temporary.plug_in)->args[0];
return ((PlugIn *) proc_def->db_info.exec_method.temporary.plug_in)->prog;
default:
break;
......
......@@ -19,6 +19,8 @@ libappplug_in_a_SOURCES = \
plug-in.h \
plug-ins.c \
plug-ins.h \
plug-in-debug.c \
plug-in-debug.h \
plug-in-def.c \
plug-in-def.h \
plug-in-message.c \
......
......@@ -495,8 +495,8 @@ plug_in_handle_proc_install (PlugIn *plug_in,
g_message ("Plug-In \"%s\"\n(%s)\n"
"attempted to install procedure \"%s\"\n"
"which does not take the standard Plug-In args.",
g_path_get_basename (plug_in->args[0]),
plug_in->args[0],
plug_in->name,
plug_in->prog,
proc_install->name);
return;
}
......@@ -511,8 +511,8 @@ plug_in_handle_proc_install (PlugIn *plug_in,
g_message ("Plug-In \"%s\"\n(%s)\n"
"attempted to install procedure \"%s\"\n"
"which does not take the standard Plug-In args.",
g_path_get_basename (plug_in->args[0]),
plug_in->args[0],
plug_in->name,
plug_in->prog,
proc_install->name);
return;
}
......@@ -527,8 +527,8 @@ plug_in_handle_proc_install (PlugIn *plug_in,
g_message ("Plug-In \"%s\"\n(%s)\n"
"attempted to install procedure \"%s\"\n"
"which does not take the standard Plug-In args.",
g_path_get_basename (plug_in->args[0]),
plug_in->args[0],
plug_in->name,
plug_in->prog,
proc_install->name);
return;
}
......@@ -545,8 +545,8 @@ plug_in_handle_proc_install (PlugIn *plug_in,
g_message ("Plug-In \"%s\"\n(%s)\n"
"attempted to install procedure \"%s\"\n"
"which does not take the standard Plug-In args.",
g_path_get_basename (plug_in->args[0]),
plug_in->args[0],
plug_in->name,
plug_in->prog,
proc_install->name);
return;
}
......@@ -558,8 +558,8 @@ plug_in_handle_proc_install (PlugIn *plug_in,
"in an invalid menu location.\n"
"Use either \"<Toolbox>\", \"<Image>\", "
"\"<Load>\", or \"<Save>\".",
g_path_get_basename (plug_in->args[0]),
plug_in->args[0],
plug_in->name,
plug_in->prog,
proc_install->name);
return;
}
......@@ -580,8 +580,8 @@ plug_in_handle_proc_install (PlugIn *plug_in,
"attempted to install procedure \"%s\"\n"
"which fails to comply with the array parameter\n"
"passing standard. Argument %d is noncompliant.",
g_path_get_basename (plug_in->args[0]),
plug_in->args[0],
plug_in->name,
plug_in->prog,
proc_install->name, i);
return;
}
......@@ -626,8 +626,8 @@ plug_in_handle_proc_install (PlugIn *plug_in,
{
g_message ("Plug-In \"%s\"\n(%s)\n"
"attempted to install a procedure with invalid UTF-8 strings.\n",
g_path_get_basename (plug_in->args[0]),
plug_in->args[0]);
plug_in->name,
plug_in->prog);
return;
}
......@@ -739,10 +739,10 @@ plug_in_handle_proc_install (PlugIn *plug_in,
plug_ins_temp_proc_def_add (plug_in->gimp, proc_def,
plug_ins_locale_domain (plug_in->gimp,
plug_in->args[0],
plug_in->prog,
NULL),
plug_ins_help_path (plug_in->gimp,
plug_in->args[0]));
plug_in->prog));
break;
}
}
......
......@@ -54,7 +54,7 @@ plug_in_progress_start (PlugIn *plug_in,
g_return_if_fail (plug_in != NULL);
if (! message)
message = plug_in->args[0];
message = plug_in->prog;
if (gdisp_ID > 0)
gdisp = gimp_display_get_by_ID (plug_in->gimp, gdisp_ID);
......
......@@ -95,6 +95,7 @@
#include "plug-in.h"
#include "plug-ins.h"
#include "plug-in-debug.h"
#include "plug-in-def.h"
#include "plug-in-message.h"
#include "plug-in-params.h"
......@@ -150,6 +151,8 @@ plug_in_init (Gimp *gimp)
*/
if (gimp->use_shm)
plug_in_shm_init (gimp);
plug_in_debug_init (gimp);
}
void
......@@ -159,6 +162,8 @@ plug_in_exit (Gimp *gimp)
g_return_if_fail (GIMP_IS_GIMP (gimp));
plug_in_debug_exit (gimp);
if (gimp->use_shm)
plug_in_shm_exit (gimp);
......@@ -257,14 +262,14 @@ plug_in_call_init (Gimp *gimp,
}
PlugIn *
plug_in_new (Gimp *gimp,
gchar *name)
plug_in_new (Gimp *gimp,
const gchar *prog)
{
PlugIn *plug_in;
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
g_return_val_if_fail (name != NULL, NULL);
g_return_val_if_fail (g_path_is_absolute (name), NULL);
g_return_val_if_fail (prog != NULL, NULL);
g_return_val_if_fail (g_path_is_absolute (prog), NULL);
plug_in = g_new0 (PlugIn, 1);
......@@ -281,13 +286,8 @@ plug_in_new (Gimp *gimp,
plug_in->starting_ext = FALSE;
plug_in->pid = 0;
plug_in->args[0] = g_strdup (name);
plug_in->args[1] = g_strdup ("-gimp");
plug_in->args[2] = NULL;
plug_in->args[3] = NULL;
plug_in->args[4] = NULL;
plug_in->args[5] = NULL;
plug_in->args[6] = NULL;
plug_in->name = g_path_get_basename (prog);
plug_in->prog = g_strdup (prog);
plug_in->my_read = NULL;
plug_in->my_write = NULL;
......@@ -329,18 +329,8 @@ plug_in_unref (PlugIn *plug_in)
if (plug_in->open)
plug_in_close (plug_in, TRUE);
if (plug_in->args[0])
g_free (plug_in->args[0]);
if (plug_in->args[1])
g_free (plug_in->args[1]);
if (plug_in->args[2])
g_free (plug_in->args[2]);
if (plug_in->args[3])
g_free (plug_in->args[3]);
if (plug_in->args[4])
g_free (plug_in->args[4]);
if (plug_in->args[5])
g_free (plug_in->args[5]);
g_free (plug_in->name);
g_free (plug_in->prog);
if (plug_in->progress)
plug_in_progress_end (plug_in);
......@@ -366,20 +356,29 @@ plug_in_prep_for_exec (gpointer data)
gboolean
plug_in_open (PlugIn *plug_in)
{
gint my_read[2];
gint my_write[2];
gchar **envp;
GError *error = NULL;
gint my_read[2];
gint my_write[2];
gchar **envp;
gchar *args[7], **argv, **debug_argv;
gchar *read_fd, *write_fd;
gchar *mode, *stm;
GError *error = NULL;
Gimp *gimp;
gboolean debug;
guint debug_flag;
guint spawn_flags;
g_return_val_if_fail (plug_in != NULL, FALSE);
gimp = plug_in->gimp;
/* Open two pipes. (Bidirectional communication).
*/
if ((pipe (my_read) == -1) || (pipe (my_write) == -1))
{
g_message ("pipe() failed: Unable to start Plug-In \"%s\"\n(%s)",
g_path_get_basename (plug_in->args[0]),
plug_in->args[0]);
plug_in->name,
plug_in->prog);
return FALSE;
}
......@@ -413,9 +412,9 @@ plug_in_open (PlugIn *plug_in)
/* Remember the file descriptors for the pipes.
*/
plug_in->args[2] =
read_fd =
g_strdup_printf ("%d", g_io_channel_unix_get_fd (plug_in->his_read));
plug_in->args[3] =
write_fd =
g_strdup_printf ("%d", g_io_channel_unix_get_fd (plug_in->his_write));
/* Set the rest of the command line arguments.
......@@ -423,41 +422,67 @@ plug_in_open (PlugIn *plug_in)
*/
if (plug_in->query)
{
plug_in->args[4] = g_strdup ("-query");
mode = "-query";
debug_flag = GIMP_DEBUG_WRAP_QUERY;
}
else if (plug_in->init)
{
plug_in->args[4] = g_strdup ("-init");
mode = "-init";
debug_flag = GIMP_DEBUG_WRAP_INIT;
}
else
{
plug_in->args[4] = g_strdup ("-run");
mode = "-run";
debug_flag = GIMP_DEBUG_WRAP_RUN;
}
plug_in->args[5] = g_strdup_printf ("%d", plug_in->gimp->stack_trace_mode);
stm = g_strdup_printf ("%d", plug_in->gimp->stack_trace_mode);
#ifdef __EMX__
fcntl (my_read[0], F_SETFD, 1);
fcntl (my_write[1], F_SETFD, 1);
#endif
args[0] = plug_in->prog;
args[1] = "-gimp";
args[2] = read_fd;
args[3] = write_fd;
args[4] = mode;
args[5] = stm;
args[6] = NULL;
argv = args;
envp = gimp_environ_table_get_envp (plug_in->gimp->environ_table);
spawn_flags = G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_DO_NOT_REAP_CHILD;
debug = FALSE;
if (gimp->plug_in_debug)
{
debug_argv = plug_in_debug_argv (gimp, plug_in->name, debug_flag, args);
if (debug_argv)
{
debug = TRUE;
argv = debug_argv;
spawn_flags |= G_SPAWN_SEARCH_PATH;
}
}
/* Fork another process. We'll remember the process id so that we
* can later use it to kill the filter if necessary.
*/
envp = gimp_environ_table_get_envp (plug_in->gimp->environ_table);
if (! g_spawn_async (NULL, plug_in->args, envp,
G_SPAWN_LEAVE_DESCRIPTORS_OPEN |
G_SPAWN_DO_NOT_REAP_CHILD,
if (! g_spawn_async (NULL, argv, envp, spawn_flags,
plug_in_prep_for_exec, plug_in,
&plug_in->pid,
&error))
{
g_message ("Unable to run Plug-In: \"%s\"\n(%s)\n%s",
g_path_get_basename (plug_in->args[0]),
plug_in->args[0],
plug_in->name,
plug_in->prog,
error->message);
g_error_free (error);
return FALSE;
goto cleanup;
}
g_io_channel_unref (plug_in->his_read);
......@@ -478,7 +503,17 @@ plug_in_open (PlugIn *plug_in)
}
plug_in->open = TRUE;
return TRUE;
cleanup:
if (debug)
g_free (argv);
g_free (read_fd);
g_free (write_fd);
g_free (stm);
return plug_in->open;
}
void
......@@ -541,7 +576,7 @@ plug_in_close (PlugIn *plug_in,
}
if (STILL_ACTIVE == dwExitCode)
{
g_warning ("Terminating %s ...", plug_in->args[0]);
g_warning ("Terminating %s ...", plug_in->prog);
TerminateProcess ((HANDLE) plug_in->pid, 0);
}
}
......@@ -662,8 +697,8 @@ plug_in_recv_message (GIOChannel *channel,
"The dying Plug-In may have messed up GIMP's internal state.\n"
"You may want to save your images and restart GIMP\n"
"to be on the safe side."),
g_path_get_basename (plug_in->args[0]),
plug_in->args[0]);
plug_in->name,
plug_in->prog);
if (! plug_in->open)
plug_in_unref (plug_in);
......
......@@ -39,8 +39,10 @@ struct _PlugIn
guint recurse : 1; /* Do we have an own GMainLoop? */
guint in_temp_proc : 1; /* Is the plug-in busy with a temp proc? */
guint starting_ext : 1; /* Does the plug-in wait for extension_ack?*/
pid_t pid; /* Plug-ins process id */
gchar *args[7]; /* Plug-ins command line arguments */
pid_t pid; /* Plug-in's process id */
gchar *name; /* Plug-in's name */
gchar *prog; /* Plug-in's full path name */
GIOChannel *my_read; /* App's read and write channels */
GIOChannel *my_write;
......@@ -64,29 +66,29 @@ struct _PlugIn
};
void plug_in_init (Gimp *gimp);
void plug_in_exit (Gimp *gimp);
void plug_in_init (Gimp *gimp);
void plug_in_exit (Gimp *gimp);
void plug_in_call_query (Gimp *gimp,
PlugInDef *plug_in_def);
void plug_in_call_init (Gimp *gimp,
PlugInDef *plug_in_def);
void plug_in_call_query (Gimp *gimp,
PlugInDef *plug_in_def);
void plug_in_call_init (Gimp *gimp,
PlugInDef *plug_in_def);
PlugIn * plug_in_new (Gimp *gimp,
gchar *name);
PlugIn * plug_in_new (Gimp *gimp,
const gchar *prog);
void plug_in_ref (PlugIn *plug_in);
void plug_in_unref (PlugIn *plug_in);
void plug_in_ref (PlugIn *plug_in);
void plug_in_unref (PlugIn *plug_in);
gboolean plug_in_open (PlugIn *plug_in);
void plug_in_close (PlugIn *plug_in,
gboolean kill_it);
gboolean plug_in_open (PlugIn *plug_in);
void plug_in_close (PlugIn *plug_in,
gboolean kill_it);
void plug_in_push (PlugIn *plug_in);
void plug_in_push (PlugIn *plug_in);
void plug_in_pop (void);
void plug_in_main_loop (PlugIn *plug_in);
void plug_in_main_loop_quit (PlugIn *plug_in);
void plug_in_main_loop (PlugIn *plug_in);
void plug_in_main_loop_quit (PlugIn *plug_in);
extern PlugIn *current_plug_in;
......