From 9f61687787d3f2b8c55f30e23e8da37f28799fdd Mon Sep 17 00:00:00 2001 From: sgranjoux Date: Sun, 10 Feb 2008 11:47:07 +0000 Subject: [PATCH] * plugins/debug-manager/command.c, plugins/debug-manager/command.h, plugins/debug-manager/breakpoints.c, libanjuta/interfaces/libanjuta.idl: Avoid adding the same breakpoint several times * plugins/gdb/debugger.c: Fix bug #515463: Deattaching process kill it git-svn-id: http://svn.gnome.org/svn/anjuta/trunk@3620 1dbfb86a-d425-0410-a06b-cb591aac69f6 --- ChangeLog | 11 +++++++ libanjuta/interfaces/libanjuta.idl | 1 + plugins/debug-manager/breakpoints.c | 3 ++ plugins/debug-manager/command.c | 65 ++++++++++++++++++++++++++++++++----- plugins/debug-manager/command.h | 6 ++-- plugins/gdb/debugger.c | 19 ++++++++--- 6 files changed, 88 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7dad2ebb..28418fbf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,16 @@ 2008-02-10 Sébastien Granjoux + * plugins/debug-manager/command.c, + plugins/debug-manager/command.h, + plugins/debug-manager/breakpoints.c, + libanjuta/interfaces/libanjuta.idl: + Avoid adding the same breakpoint several times + + * plugins/gdb/debugger.c: + Fix bug #515463: Deattaching process kill it + +2008-02-10 Sébastien Granjoux + * manuals/anjuta-manual/C/debugger.xml: Fix translation bug #515459 and #515460 diff --git a/libanjuta/interfaces/libanjuta.idl b/libanjuta/interfaces/libanjuta.idl index 60502cce..bea311e8 100644 --- a/libanjuta/interfaces/libanjuta.idl +++ b/libanjuta/interfaces/libanjuta.idl @@ -2911,6 +2911,7 @@ interface IAnjutaDebugger UNSUPPORTED_FILE_TYPE, UNSUPPORTED_VERSION, UNABLE_TO_FIND_DEBUGGER, + ALREADY_DONE, UNKNOWN_ERROR, OTHER_ERROR } diff --git a/plugins/debug-manager/breakpoints.c b/plugins/debug-manager/breakpoints.c index 4e321b0c..6b05c381 100644 --- a/plugins/debug-manager/breakpoints.c +++ b/plugins/debug-manager/breakpoints.c @@ -746,6 +746,7 @@ breakpoints_dbase_add_in_debugger (BreakpointsDBase *bd, BreakpointItem *bi) breakpoint_item_ref (bi); ok = dma_queue_add_breakpoint_at_line ( bd->debugger, + &(bi->bp.id), bi->bp.file, bi->bp.line, on_breakpoint_callback, @@ -756,6 +757,7 @@ breakpoints_dbase_add_in_debugger (BreakpointsDBase *bd, BreakpointItem *bi) breakpoint_item_ref (bi); ok = dma_queue_add_breakpoint_at_function ( bd->debugger, + &(bi->bp.id), bi->bp.file == NULL ? "" : bi->bp.file, bi->bp.function, on_breakpoint_callback, @@ -767,6 +769,7 @@ breakpoints_dbase_add_in_debugger (BreakpointsDBase *bd, BreakpointItem *bi) breakpoint_item_ref (bi); ok = dma_queue_add_breakpoint_at_address ( bd->debugger, + &(bi->bp.id), bi->bp.address, on_breakpoint_callback, bi); diff --git a/plugins/debug-manager/command.c b/plugins/debug-manager/command.c index ac5efe6a..096705fb 100644 --- a/plugins/debug-manager/command.c +++ b/plugins/debug-manager/command.c @@ -298,6 +298,7 @@ struct _DmaQueueCommand GList *dirs; } attach; struct { + guint *id; gchar *file; guint line; gulong address; @@ -439,18 +440,21 @@ dma_command_new (DmaDebuggerCommand cmd_type,...) cmd->user_data = va_arg (args, gpointer); break; case BREAK_LINE_COMMAND: + cmd->data.pos.id = va_arg (args, guint *); cmd->data.pos.file = g_strdup (va_arg (args, gchar *)); cmd->data.pos.line = va_arg (args, guint); cmd->callback = va_arg (args, IAnjutaDebuggerCallback); cmd->user_data = va_arg (args, gpointer); break; case BREAK_FUNCTION_COMMAND: + cmd->data.pos.id = va_arg (args, guint *); cmd->data.pos.file = g_strdup (va_arg (args, gchar *)); cmd->data.pos.function = g_strdup (va_arg (args, gchar *)); cmd->callback = va_arg (args, IAnjutaDebuggerCallback); cmd->user_data = va_arg (args, gpointer); break; case BREAK_ADDRESS_COMMAND: + cmd->data.pos.id = va_arg (args, guint *); cmd->data.pos.address = va_arg (args, gulong); cmd->callback = va_arg (args, IAnjutaDebuggerCallback); cmd->user_data = va_arg (args, gpointer); @@ -836,21 +840,21 @@ dma_queue_callback (DmaDebuggerQueue *self, IAnjutaDebuggerCallback callback , g } gboolean -dma_queue_add_breakpoint_at_line (DmaDebuggerQueue *self, const gchar* file, guint line, IAnjutaDebuggerCallback callback, gpointer user_data) +dma_queue_add_breakpoint_at_line (DmaDebuggerQueue *self, guint *id, const gchar* file, guint line, IAnjutaDebuggerCallback callback, gpointer user_data) { - return dma_debugger_queue_append (self, dma_command_new (DMA_BREAK_LINE_COMMAND, file, line, callback, user_data)); + return dma_debugger_queue_append (self, dma_command_new (DMA_BREAK_LINE_COMMAND, id, file, line, callback, user_data)); } gboolean -dma_queue_add_breakpoint_at_function (DmaDebuggerQueue *self, const gchar* file, const gchar* function, IAnjutaDebuggerCallback callback, gpointer user_data) +dma_queue_add_breakpoint_at_function (DmaDebuggerQueue *self, guint *id, const gchar* file, const gchar* function, IAnjutaDebuggerCallback callback, gpointer user_data) { - return dma_debugger_queue_append (self, dma_command_new (DMA_BREAK_FUNCTION_COMMAND, file, function, callback, user_data)); + return dma_debugger_queue_append (self, dma_command_new (DMA_BREAK_FUNCTION_COMMAND, id, file, function, callback, user_data)); } gboolean -dma_queue_add_breakpoint_at_address (DmaDebuggerQueue *self, gulong address, IAnjutaDebuggerCallback callback, gpointer user_data) +dma_queue_add_breakpoint_at_address (DmaDebuggerQueue *self, guint *id, gulong address, IAnjutaDebuggerCallback callback, gpointer user_data) { - return dma_debugger_queue_append (self, dma_command_new (DMA_BREAK_ADDRESS_COMMAND, address, callback, user_data)); + return dma_debugger_queue_append (self, dma_command_new (DMA_BREAK_ADDRESS_COMMAND, id, address, callback, user_data)); } gboolean @@ -1065,6 +1069,28 @@ dma_command_cancel (DmaQueueCommand *cmd) dma_command_free (cmd); } +/* It is possible that the queue contains several add breakpoint command + * for the same one. Just before sending the command to the debugger check + * that the breakpoint is still not set */ + +static gboolean +dma_command_is_breakpoint_pending (DmaQueueCommand *cmd) +{ + GError *err; + + if (*cmd->data.pos.id == 0) return TRUE; /* Breakpoint is not set, can add it */ + + err = g_error_new (IANJUTA_DEBUGGER_ERROR , IANJUTA_DEBUGGER_ALREADY_DONE, "Breakpoint is already set with id %d", *cmd->data.pos.id); + + if (cmd->callback != NULL) + { + cmd->callback (NULL, cmd->user_data, err); + } + g_error_free (err); + + return FALSE; +} + gboolean dma_command_run (DmaQueueCommand *cmd, IAnjutaDebugger *debugger, DmaDebuggerQueue *queue, GError **err) @@ -1140,13 +1166,34 @@ dma_command_run (DmaQueueCommand *cmd, IAnjutaDebugger *debugger, ret = ianjuta_debugger_breakpoint_clear (IANJUTA_DEBUGGER_BREAKPOINT (debugger), cmd->data.brk.id, callback, queue, err); break; case BREAK_LINE_COMMAND: - ret = ianjuta_debugger_breakpoint_set_at_line (IANJUTA_DEBUGGER_BREAKPOINT (debugger), cmd->data.pos.file, cmd->data.pos.line, callback, queue, err); + if (dma_command_is_breakpoint_pending (cmd)) + { + ret = ianjuta_debugger_breakpoint_set_at_line (IANJUTA_DEBUGGER_BREAKPOINT (debugger), cmd->data.pos.file, cmd->data.pos.line, callback, queue, err); + } + else + { + ret = FALSE; + } break; case BREAK_FUNCTION_COMMAND: - ret = ianjuta_debugger_breakpoint_set_at_function (IANJUTA_DEBUGGER_BREAKPOINT (debugger), cmd->data.pos.file, cmd->data.pos.function, callback, queue, err); + if (dma_command_is_breakpoint_pending (cmd)) + { + ret = ianjuta_debugger_breakpoint_set_at_function (IANJUTA_DEBUGGER_BREAKPOINT (debugger), cmd->data.pos.file, cmd->data.pos.function, callback, queue, err); + } + else + { + ret = FALSE; + } break; case BREAK_ADDRESS_COMMAND: - ret = ianjuta_debugger_breakpoint_set_at_address (IANJUTA_DEBUGGER_BREAKPOINT (debugger), cmd->data.pos.address, callback, queue, err); + if (dma_command_is_breakpoint_pending (cmd)) + { + ret = ianjuta_debugger_breakpoint_set_at_address (IANJUTA_DEBUGGER_BREAKPOINT (debugger), cmd->data.pos.address, callback, queue, err); + } + else + { + ret = FALSE; + } break; case CONDITION_BREAK_COMMAND: ret = ianjuta_debugger_breakpoint_condition (IANJUTA_DEBUGGER_BREAKPOINT (debugger), cmd->data.brk.id, cmd->data.brk.condition, callback, queue, err); diff --git a/plugins/debug-manager/command.h b/plugins/debug-manager/command.h index 610f33c5..fd45e6bf 100644 --- a/plugins/debug-manager/command.h +++ b/plugins/debug-manager/command.h @@ -98,9 +98,9 @@ gboolean dma_queue_list_register (DmaDebuggerQueue *self, IAnjutaDebuggerCallbac gboolean dma_queue_callback (DmaDebuggerQueue *self, IAnjutaDebuggerCallback callback , gpointer user_data); void dma_queue_enable_log (DmaDebuggerQueue *self, IAnjutaMessageView *log); void dma_queue_disable_log (DmaDebuggerQueue *self); -gboolean dma_queue_add_breakpoint_at_line (DmaDebuggerQueue *self, const gchar* file, guint line, IAnjutaDebuggerCallback callback, gpointer user_data); -gboolean dma_queue_add_breakpoint_at_function (DmaDebuggerQueue *self, const gchar* file, const gchar* function, IAnjutaDebuggerCallback callback, gpointer user_data); -gboolean dma_queue_add_breakpoint_at_address (DmaDebuggerQueue *self, gulong address, IAnjutaDebuggerCallback callback, gpointer user_data); +gboolean dma_queue_add_breakpoint_at_line (DmaDebuggerQueue *self, guint *id, const gchar* file, guint line, IAnjutaDebuggerCallback callback, gpointer user_data); +gboolean dma_queue_add_breakpoint_at_function (DmaDebuggerQueue *self, guint *id, const gchar* file, const gchar* function, IAnjutaDebuggerCallback callback, gpointer user_data); +gboolean dma_queue_add_breakpoint_at_address (DmaDebuggerQueue *self, guint *id, gulong address, IAnjutaDebuggerCallback callback, gpointer user_data); gboolean dma_queue_enable_breakpoint (DmaDebuggerQueue *self, guint id, gboolean enable, IAnjutaDebuggerCallback callback, gpointer user_data); gboolean dma_queue_ignore_breakpoint (DmaDebuggerQueue *self, guint id, guint ignore, IAnjutaDebuggerCallback callback, gpointer user_data); gboolean dma_queue_condition_breakpoint (DmaDebuggerQueue *self, guint id, const gchar *condition, IAnjutaDebuggerCallback callback, gpointer user_data); diff --git a/plugins/gdb/debugger.c b/plugins/gdb/debugger.c index 78858492..47d31387 100644 --- a/plugins/gdb/debugger.c +++ b/plugins/gdb/debugger.c @@ -1573,7 +1573,9 @@ debugger_stop_real (Debugger *debugger) /* if program is attached - detach from it before quiting */ if (debugger->priv->prog_is_attached == TRUE) - debugger_queue_command (debugger, "detach", FALSE, FALSE, NULL, NULL, NULL); + { + debugger_detach_process(debugger); + } debugger->priv->terminating = TRUE; debugger_queue_command (debugger, "-gdb-exit", FALSE, FALSE, NULL, NULL, NULL); @@ -1645,6 +1647,7 @@ debugger_abort (Debugger *debugger) /* Emit signal, state of the debugger must be DEBUGGER_STOPPED */ debugger->priv->prog_is_running = FALSE; debugger->priv->prog_is_attached = FALSE; + debugger->priv->inferior_pid = 0; debugger->priv->prog_is_loaded = FALSE; debugger->priv->debugger_is_busy = 0; debugger->priv->debugger_is_started = FALSE; @@ -1785,7 +1788,11 @@ debugger_attach_process_finish (Debugger *debugger, const GDBMIValue *mi_results } debugger->priv->prog_is_attached = TRUE; debugger->priv->prog_is_running = TRUE; - //debugger_emit_status (debugger); + /* It is not really a shared lib event, but it allows to restart + * the program after setting breakpoints. It is better to restart + * it because we don't have the normal stop frame that tell where + * the program is stopped */ + debugger->priv->solib_event = TRUE; } static void @@ -1876,7 +1883,9 @@ debugger_stop_program (Debugger *debugger) g_return_if_fail (debugger->priv->prog_is_running == TRUE); if (debugger->priv->prog_is_attached == TRUE) - debugger_queue_command (debugger, "detach", FALSE, FALSE, NULL, NULL, NULL); + { + debugger_detach_process (debugger); + } else { /* FIXME: Why doesn't -exec-abort work??? */ @@ -1906,6 +1915,7 @@ debugger_detach_process_finish (Debugger *debugger, const GDBMIValue *mi_results _("Program detached\n"), debugger->priv->output_user_data); } + debugger->priv->inferior_pid = 0; debugger->priv->prog_is_attached = FALSE; debugger->priv->prog_is_running = FALSE; g_signal_emit_by_name (debugger->priv->instance, "program-exited"); @@ -1917,7 +1927,7 @@ debugger_detach_process (Debugger *debugger) gchar *buff; DEBUG_PRINT ("In function: debugger_detach_process()"); - + g_return_if_fail (debugger->priv->prog_is_attached == TRUE); if (debugger->priv->output_callback) @@ -1930,7 +1940,6 @@ debugger_detach_process (Debugger *debugger) debugger_queue_command (debugger, "detach", FALSE, FALSE, debugger_detach_process_finish, NULL, NULL); - debugger->priv->prog_is_attached = FALSE; } void -- 2.11.4.GIT