[anjuta] debug-manager: Merge stack and thread debugger window
- From: Sebastien Granjoux <sgranjoux src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [anjuta] debug-manager: Merge stack and thread debugger window
- Date: Fri, 21 Oct 2011 21:10:49 +0000 (UTC)
commit bb16c16f9d2abfe3beb1bd6cce909a3bdce7f9ad
Author: SÃbastien Granjoux <seb sfo free fr>
Date: Fri Oct 21 22:20:31 2011 +0200
debug-manager: Merge stack and thread debugger window
manuals/anjuta-manual/C/debug-stack.page | 19 +-
manuals/anjuta-manual/C/debug-thread.page | 105 ----
manuals/anjuta-manual/Makefile.am | 1 -
plugins/debug-manager/Makefile.am | 2 -
plugins/debug-manager/anjuta-debug-manager.xml | 4 -
plugins/debug-manager/plugin.c | 186 +++----
plugins/debug-manager/stack_trace.c | 685 +++++++++++++++---------
plugins/debug-manager/threads.c | 644 ----------------------
plugins/debug-manager/threads.h | 38 --
po/POTFILES.in | 1 -
10 files changed, 533 insertions(+), 1152 deletions(-)
---
diff --git a/manuals/anjuta-manual/C/debug-stack.page b/manuals/anjuta-manual/C/debug-stack.page
index fb2c37c..e59b1a2 100644
--- a/manuals/anjuta-manual/C/debug-stack.page
+++ b/manuals/anjuta-manual/C/debug-stack.page
@@ -29,6 +29,10 @@
Each stack frame is numbered starting from 0 for the current function.
You can only view the stack frames while the debugger is running.</p>
+ <p>Moreover, a program can be composed of several threads. Each thread is
+ executed independently and has its own registers, stack and local
+ variables, but shares all global variables.</p>
+
<steps>
<item>
<p>From the <gui>main menu</gui>, select <guiseq><gui>View</gui>
@@ -37,7 +41,8 @@
</item>
</steps>
- <p>Each stack frame contains the following information:</p>
+ <p>The stacks are displayed in a tree view having their corresponding
+ thread as parent and displaying the following information:</p>
<terms>
<item>
@@ -48,6 +53,10 @@
the active stack frame to examine local variables in other functions.</p>
</item>
<item>
+ <title>Thread</title>
+ <p>This is a number corresponding to each thread.</p>
+ </item>
+ <item>
<title>Frame</title>
<p>This is the frame number starting from 0 for the current function.
The first function of your program, for example <code>main()</code> in a C program,
@@ -80,7 +89,7 @@
<section>
- <title>Change the current stack frame</title>
+ <title>Change the current stack frame or thread</title>
<steps>
<item>
@@ -90,6 +99,12 @@
<p>Right-click and select <gui>Set current frame</gui>.</p>
</item>
</steps>
+
+ <p>Clicking on a stack frame in the same thread changes only the
+ stack frame, allowing to see other local variables. But doing it
+ in another thread will change both the stack frame
+ and the thread. The register values will be different and the
+ debugger will restart in the selected thread.</p>
</section>
diff --git a/manuals/anjuta-manual/Makefile.am b/manuals/anjuta-manual/Makefile.am
index b7af61a..d247eaf 100644
--- a/manuals/anjuta-manual/Makefile.am
+++ b/manuals/anjuta-manual/Makefile.am
@@ -33,7 +33,6 @@ DOC_PAGES = \
debug-run.page \
debug-stack.page \
debug-step.page \
- debug-thread.page \
debug-tips.page \
debug-watch.page \
directory-project-backend.page \
diff --git a/plugins/debug-manager/Makefile.am b/plugins/debug-manager/Makefile.am
index 90f9e98..cd7ba5c 100644
--- a/plugins/debug-manager/Makefile.am
+++ b/plugins/debug-manager/Makefile.am
@@ -87,8 +87,6 @@ libanjuta_debug_manager_la_SOURCES = \
sparse_buffer.h \
sparse_view.c \
sparse_view.h \
- threads.c \
- threads.h \
command.c \
command.h \
variable.c \
diff --git a/plugins/debug-manager/anjuta-debug-manager.xml b/plugins/debug-manager/anjuta-debug-manager.xml
index 168e973..44c8f92 100644
--- a/plugins/debug-manager/anjuta-debug-manager.xml
+++ b/plugins/debug-manager/anjuta-debug-manager.xml
@@ -86,10 +86,6 @@
<menuitem name="UpdateAllWatch" action="ActionDmaUpdateAllWatch" />
<menuitem name="RemoveAllWatch" action="ActionDmaRemoveAllWatch" />
</popup>
- <popup name="PopupThread">
- <menuitem name="SetCurrentThread" action="ActionDmaSetCurrentThread" />
- <menuitem name="JumpToThread" action="ActionDmaJumpToThread" />
- </popup>
<popup name="PopupSignals">
<menuitem name="SendSignal" action="ActionDmaSignalSend" />
<menuitem name="UpdateSignalList" action="ActionDmaSignalUpdate" />
diff --git a/plugins/debug-manager/plugin.c b/plugins/debug-manager/plugin.c
index e9b5831..5224347 100644
--- a/plugins/debug-manager/plugin.c
+++ b/plugins/debug-manager/plugin.c
@@ -26,7 +26,6 @@
#include "breakpoints.h"
#include "stack_trace.h"
-#include "threads.h"
#include "info.h"
#include "memory.h"
#include "disassemble.h"
@@ -68,7 +67,7 @@ struct _DebugManagerPlugin
/* Debugger queue */
DmaDebuggerQueue *queue;
-
+
/* Menu item */
gint uiid;
GtkActionGroup *start_group;
@@ -88,22 +87,21 @@ struct _DebugManagerPlugin
guint pc_line;
gulong pc_address;
gboolean busy;
-
+
/* Debugger components */
BreakpointsDBase *breakpoints;
DmaStart *start;
StackTrace *stack;
CpuRegisters *registers;
Sharedlibs *sharedlibs;
- Signals *signals;
+ Signals *signals;
DmaMemory *memory;
DmaDisassemble *disassemble;
- DmaThreads *thread;
DmaVariableDBase *variable;
-
+
GtkWidget *user_command_dialog;
-
+
/* Logging view */
IAnjutaMessageView* view;
};
@@ -132,10 +130,10 @@ register_stock_icons (AnjutaPlugin *plugin)
REGISTER_ICON ("locals.png", "gdb-locals-icon");
REGISTER_ICON_FULL ("anjuta-watch", "gdb-watch-icon");
REGISTER_ICON_FULL ("anjuta-breakpoint-toggle", ANJUTA_STOCK_BREAKPOINT_TOGGLE);
- REGISTER_ICON_FULL ("anjuta-breakpoint-clear", ANJUTA_STOCK_BREAKPOINT_CLEAR);
+ REGISTER_ICON_FULL ("anjuta-breakpoint-clear", ANJUTA_STOCK_BREAKPOINT_CLEAR);
/* We have no -24 version for the next two */
REGISTER_ICON ("anjuta-breakpoint-disabled-16.png", ANJUTA_STOCK_BREAKPOINT_DISABLED);
- REGISTER_ICON ("anjuta-breakpoint-enabled-16.png", ANJUTA_STOCK_BREAKPOINT_ENABLED);
+ REGISTER_ICON ("anjuta-breakpoint-enabled-16.png", ANJUTA_STOCK_BREAKPOINT_ENABLED);
REGISTER_ICON_FULL ("anjuta-attach", "debugger-attach");
REGISTER_ICON_FULL ("anjuta-step-into", "debugger-step-into");
REGISTER_ICON_FULL ("anjuta-step-out", "debugger-step-out");
@@ -153,7 +151,7 @@ static void
show_program_counter_in_editor(DebugManagerPlugin *self)
{
IAnjutaEditor *editor = self->current_editor;
-
+
if ((editor != NULL) && (self->pc_editor == editor))
{
if (IANJUTA_IS_MARKABLE (editor))
@@ -166,12 +164,12 @@ show_program_counter_in_editor(DebugManagerPlugin *self)
ianjuta_editor_get_line_begin_position(editor, self->pc_line, NULL);
IAnjutaIterable *end =
ianjuta_editor_get_line_end_position(editor, self->pc_line, NULL);
-
+
ianjuta_indicable_set(IANJUTA_INDICABLE(editor), begin, end,
IANJUTA_INDICABLE_IMPORTANT, NULL);
g_object_unref (begin);
g_object_unref (end);
- }
+ }
}
}
@@ -179,7 +177,7 @@ static void
hide_program_counter_in_editor(DebugManagerPlugin *self)
{
IAnjutaEditor *editor = self->current_editor;
-
+
if ((editor != NULL) && (self->pc_editor == editor))
{
if (IANJUTA_IS_MARKABLE (editor))
@@ -188,8 +186,8 @@ hide_program_counter_in_editor(DebugManagerPlugin *self)
}
if (IANJUTA_IS_INDICABLE(editor))
{
- ianjuta_indicable_clear(IANJUTA_INDICABLE(editor), NULL);
- }
+ ianjuta_indicable_clear(IANJUTA_INDICABLE(editor), NULL);
+ }
}
}
@@ -215,9 +213,9 @@ set_program_counter(DebugManagerPlugin *self, const gchar* filename, guint line,
if (docman)
{
IAnjutaEditor* editor;
-
+
editor = ianjuta_document_manager_goto_file_line(docman, file, line, NULL);
-
+
if (editor != NULL)
{
self->pc_editor = editor;
@@ -225,7 +223,7 @@ set_program_counter(DebugManagerPlugin *self, const gchar* filename, guint line,
self->pc_line = line;
show_program_counter_in_editor (self);
}
- }
+ }
g_object_unref (file);
}
}
@@ -238,11 +236,11 @@ value_added_project_root_uri (AnjutaPlugin *plugin, const gchar *name,
const gchar *root_uri;
dm_plugin = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
-
+
if (dm_plugin->project_root_uri)
g_free (dm_plugin->project_root_uri);
dm_plugin->project_root_uri = NULL;
-
+
root_uri = g_value_get_string (value);
if (root_uri)
{
@@ -257,7 +255,7 @@ value_removed_project_root_uri (AnjutaPlugin *plugin, const gchar *name,
DebugManagerPlugin *dm_plugin;
dm_plugin = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
-
+
if (dm_plugin->project_root_uri)
g_free (dm_plugin->project_root_uri);
dm_plugin->project_root_uri = NULL;
@@ -274,7 +272,7 @@ value_added_current_editor (AnjutaPlugin *plugin, const char *name,
editor = g_value_get_object (value);
DEBUG_PRINT("add value current editor %p", editor);
-
+
if (!IANJUTA_IS_EDITOR(editor))
{
self->current_editor = NULL;
@@ -283,7 +281,7 @@ value_added_current_editor (AnjutaPlugin *plugin, const char *name,
self->current_editor = IANJUTA_EDITOR (editor);
g_object_add_weak_pointer (G_OBJECT (self->current_editor), (gpointer *)(gpointer)&self->current_editor);
-
+
/* Restore program counter marker */
show_program_counter_in_editor (self);
@@ -395,9 +393,9 @@ dma_plugin_debugger_started (DebugManagerPlugin *this)
AnjutaStatus* status;
DEBUG_PRINT ("%s", "DMA: dma_plugin_debugger_started");
-
+
ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
-
+
/* Update ui */
action = gtk_action_group_get_action (this->start_group, "ActionDebuggerStop");
gtk_action_set_sensitive (action, TRUE);
@@ -421,7 +419,7 @@ dma_plugin_program_loaded (DebugManagerPlugin *this)
AnjutaStatus* status;
DEBUG_PRINT ("%s", "DMA: dma_plugin_program_loaded");
-
+
/* Update ui */
ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
gtk_action_group_set_sensitive (this->loaded_group, TRUE);
@@ -443,18 +441,18 @@ dma_plugin_program_running (DebugManagerPlugin *this)
AnjutaStatus* status;
DEBUG_PRINT ("%s", "DMA: dma_plugin_program_running");
-
+
/* Update ui */
ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
gtk_action_group_set_sensitive (this->loaded_group, TRUE);
gtk_action_group_set_sensitive (this->stopped_group, FALSE);
gtk_action_group_set_sensitive (this->running_group, TRUE);
-
+
gtk_action_set_sensitive (this->run_stop_action, TRUE);
gtk_action_set_stock_id (this->run_stop_action, GTK_STOCK_MEDIA_PAUSE);
gtk_action_set_label (this->run_stop_action, _("Pa_use Program"));
gtk_action_set_tooltip (this->run_stop_action, _("Pauses the execution of the program"));
-
+
status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
anjuta_status_set_default (status, _("Debugger"), _("Runningâ"));
@@ -468,9 +466,9 @@ dma_plugin_program_stopped (DebugManagerPlugin *this)
{
AnjutaUI *ui;
AnjutaStatus* status;
-
+
DEBUG_PRINT ("%s", "DMA: dma_plugin_program_broken");
-
+
/* Update ui */
ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
gtk_action_group_set_sensitive (this->loaded_group, TRUE);
@@ -504,7 +502,7 @@ dma_plugin_program_unload (DebugManagerPlugin *this)
AnjutaStatus* status;
DEBUG_PRINT ("%s", "DMA: dma_plugin_program_unload");
-
+
/* Update ui */
ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
gtk_action_group_set_visible (this->start_group, TRUE);
@@ -515,7 +513,7 @@ dma_plugin_program_unload (DebugManagerPlugin *this)
gtk_action_group_set_sensitive (this->stopped_group, FALSE);
gtk_action_group_set_visible (this->running_group, TRUE);
gtk_action_group_set_sensitive (this->running_group, FALSE);
-
+
status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
anjuta_status_set_default (status, _("Debugger"), _("Unloaded"));
}
@@ -532,7 +530,7 @@ dma_plugin_debugger_stopped (DebugManagerPlugin *self, GError *err)
DEBUG_PRINT ("%s", "DMA: dma_plugin_debugger_stopped");
dma_plugin_program_unload (self);
-
+
/* Update ui */
ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (self)->shell, NULL);
gtk_action_group_set_visible (self->start_group, TRUE);
@@ -554,21 +552,21 @@ dma_plugin_debugger_stopped (DebugManagerPlugin *self, GError *err)
/* Remove user command dialog if existing */
if (self->user_command_dialog) gtk_widget_destroy (GTK_WIDGET (self->user_command_dialog));
-
+
/* Display a warning if debugger stop unexpectedly */
if (err != NULL)
{
GtkWindow *parent = GTK_WINDOW (ANJUTA_PLUGIN(self)->shell);
anjuta_util_dialog_error (parent, _("Debugger terminated with error %d: %s\n"), err->code, err->message);
}
-
+
}
static void
dma_plugin_signal_received (DebugManagerPlugin *self, const gchar *name, const gchar *description)
{
GtkWindow *parent = GTK_WINDOW (ANJUTA_PLUGIN (self)->shell);
-
+
/* Skip SIGINT signal */
if (strcmp(name, "SIGINT") != 0)
{
@@ -597,7 +595,7 @@ dma_plugin_location_changed (DebugManagerPlugin *self, gulong address, const gch
/* Start/Stop menu functions
*---------------------------------------------------------------------------*/
-
+
static void
on_start_debug_activate (GtkAction* action, DebugManagerPlugin* this)
{
@@ -708,7 +706,7 @@ on_run_to_cursor_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
if ((plugin->disassemble != NULL) && (dma_disassemble_is_focus (plugin->disassemble)))
{
gulong address;
-
+
address = dma_disassemble_get_current_address (plugin->disassemble);
dma_queue_run_to_address (plugin->queue, address);
}
@@ -725,9 +723,9 @@ on_run_to_cursor_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
file = ianjuta_file_get_file (IANJUTA_FILE (editor), NULL);
if (file == NULL)
return;
-
+
filename = g_file_get_path (file);
-
+
line = ianjuta_editor_get_lineno (editor, NULL);
dma_queue_run_to (plugin->queue, filename, line);
g_free (filename);
@@ -744,7 +742,7 @@ on_run_from_cursor_action_activate (GtkAction* action, DebugManagerPlugin* plugi
if ((plugin->disassemble != NULL) && (dma_disassemble_is_focus (plugin->disassemble)))
{
gulong address;
-
+
address = dma_disassemble_get_current_address (plugin->disassemble);
dma_queue_run_from_address (plugin->queue, address);
}
@@ -761,9 +759,9 @@ on_run_from_cursor_action_activate (GtkAction* action, DebugManagerPlugin* plugi
file = ianjuta_file_get_file (IANJUTA_FILE (editor), NULL);
if (file == NULL)
return;
-
+
filename = g_file_get_path (file);
-
+
line = ianjuta_editor_get_lineno (editor, NULL);
dma_queue_run_from (plugin->queue, filename, line);
g_free (filename);
@@ -812,7 +810,7 @@ on_debugger_custom_command_activate (GtkAction * action, DebugManagerPlugin *plu
gtk_window_set_transient_for (GTK_WINDOW (plugin->user_command_dialog), GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell));
g_object_add_weak_pointer (G_OBJECT (plugin->user_command_dialog), (gpointer *)&plugin->user_command_dialog);
-
+
g_signal_connect_swapped (plugin->user_command_dialog, "response",
G_CALLBACK (gtk_widget_destroy),
plugin->user_command_dialog);
@@ -902,7 +900,7 @@ static GtkActionEntry actions_start[] =
{
"ActionDebuggerStop",
GTK_STOCK_STOP,
- N_("Stop Debugger"),
+ N_("Stop Debugger"),
NULL,
N_("Say goodbye to the debugger"),
G_CALLBACK (on_debugger_stop_activate)
@@ -910,7 +908,7 @@ static GtkActionEntry actions_start[] =
{
"ActionDebuggerAddSource",
NULL,
- N_("Add source pathsâ"),
+ N_("Add source pathsâ"),
NULL,
N_("Add additional source paths"),
G_CALLBACK (on_add_source_activate)
@@ -924,7 +922,7 @@ static GtkActionEntry actions_loaded[] =
NULL, /* Stock icon, if any */
N_("Debugger Commandâ"), /* Display label */
NULL, /* short-cut */
- N_("Custom debugger command"), /* Tooltip */
+ N_("Custom debugger command"), /* Tooltip */
G_CALLBACK (on_debugger_custom_command_activate) /* action callback */
},
{
@@ -977,10 +975,10 @@ static GtkActionEntry actions_stopped[] =
N_("Step _In"),
"F5",
N_("Single step into function"),
- G_CALLBACK (on_step_in_action_activate)
+ G_CALLBACK (on_step_in_action_activate)
},
{
- "ActionDebuggerStepOver",
+ "ActionDebuggerStepOver",
"debugger-step-over",
N_("Step O_ver"),
"F6",
@@ -990,26 +988,26 @@ static GtkActionEntry actions_stopped[] =
{
"ActionDebuggerStepOut",
"debugger-step-out",
- N_("Step _Out"),
- "<shift>F5",
- N_("Single step out of function"),
- G_CALLBACK (on_step_out_action_activate)
+ N_("Step _Out"),
+ "<shift>F5",
+ N_("Single step out of function"),
+ G_CALLBACK (on_step_out_action_activate)
},
{
- "ActionDebuggerRunToPosition",
- "debugger-run-to-cursor",
- N_("_Run to Cursor"),
- "F8",
- N_("Run to the cursor"),
- G_CALLBACK (on_run_to_cursor_action_activate)
+ "ActionDebuggerRunToPosition",
+ "debugger-run-to-cursor",
+ N_("_Run to Cursor"),
+ "F8",
+ N_("Run to the cursor"),
+ G_CALLBACK (on_run_to_cursor_action_activate)
},
{
- "ActionDebuggerRunFromPosition",
- "debugger-run-from-cursor",
- N_("_Run from Cursor"),
- NULL,
- N_("Run from the cursor"),
- G_CALLBACK (on_run_from_cursor_action_activate)
+ "ActionDebuggerRunFromPosition",
+ "debugger-run-from-cursor",
+ N_("_Run from Cursor"),
+ NULL,
+ N_("Run from the cursor"),
+ G_CALLBACK (on_run_from_cursor_action_activate)
},
{
"ActionGdbCommand",
@@ -1066,10 +1064,10 @@ dma_plugin_activate (AnjutaPlugin* plugin)
DebugManagerPlugin *this;
static gboolean initialized = FALSE;
AnjutaUI *ui;
-
+
DEBUG_PRINT ("%s", "DebugManagerPlugin: Activating Debug Manager pluginâ");
this = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
-
+
if (!initialized)
{
initialized = TRUE;
@@ -1087,7 +1085,7 @@ dma_plugin_activate (AnjutaPlugin* plugin)
g_signal_connect (this, "program-moved", G_CALLBACK (dma_plugin_program_moved), this);
g_signal_connect (this, "signal-received", G_CALLBACK (dma_plugin_signal_received), this);
g_signal_connect (this, "location-changed", G_CALLBACK (dma_plugin_location_changed), this);
-
+
/* Add all our debug manager actions */
ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin)->shell, NULL);
this->start_group =
@@ -1113,21 +1111,18 @@ dma_plugin_activate (AnjutaPlugin* plugin)
_("Debugger operations"),
actions_running,
G_N_ELEMENTS (actions_running),
- GETTEXT_PACKAGE, TRUE, this);
+ GETTEXT_PACKAGE, TRUE, this);
this->uiid = anjuta_ui_merge (ui, UI_FILE);
-
+
/* Get run_stop_action */
this->run_stop_action = anjuta_ui_get_action (ui, "ActionGroupDebugLoaded", "ActionDebuggerContinueSuspend");
/* Variable */
this->variable = dma_variable_dbase_new (this);
-
+
/* Stack trace */
this->stack = stack_trace_new (this);
- /* Thread list */
- this->thread = dma_threads_new (this);
-
/* Create breakpoints list */
this->breakpoints = breakpoints_dbase_new (this);
@@ -1150,20 +1145,20 @@ dma_plugin_activate (AnjutaPlugin* plugin)
this->signals = signals_new (this);
dma_plugin_debugger_stopped (this, 0);
-
+
/* Add watches */
- this->project_watch_id =
+ this->project_watch_id =
anjuta_plugin_add_watch (plugin, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI,
value_added_project_root_uri,
value_removed_project_root_uri, NULL);
- this->editor_watch_id =
+ this->editor_watch_id =
anjuta_plugin_add_watch (plugin, IANJUTA_DOCUMENT_MANAGER_CURRENT_DOCUMENT,
value_added_current_editor,
value_removed_current_editor, NULL);
-
+
/* Connect to save session */
g_signal_connect (G_OBJECT (plugin->shell), "save_session",
- G_CALLBACK (on_session_save), plugin);
+ G_CALLBACK (on_session_save), plugin);
return TRUE;
}
@@ -1182,11 +1177,11 @@ dma_plugin_deactivate (AnjutaPlugin* plugin)
dma_plugin_debugger_stopped (this, 0);
g_signal_handlers_disconnect_by_func (plugin->shell, G_CALLBACK (on_session_save), plugin);
- g_signal_handlers_disconnect_matched (plugin, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, plugin);
+ g_signal_handlers_disconnect_matched (plugin, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, plugin);
anjuta_plugin_remove_watch (plugin, this->project_watch_id, FALSE);
anjuta_plugin_remove_watch (plugin, this->editor_watch_id, FALSE);
-
+
dma_debugger_queue_free (this->queue);
this->queue = NULL;
@@ -1195,25 +1190,22 @@ dma_plugin_deactivate (AnjutaPlugin* plugin)
dma_variable_dbase_free (this->variable);
this->variable = NULL;
-
+
breakpoints_dbase_destroy (this->breakpoints);
this->breakpoints = NULL;
-
+
stack_trace_free (this->stack);
this->stack = NULL;
cpu_registers_free (this->registers);
this->registers = NULL;
-
+
dma_memory_free (this->memory);
this->memory = NULL;
-
+
dma_disassemble_free (this->disassemble);
this->disassemble = NULL;
-
- dma_threads_free (this->thread);
- this->thread = NULL;
-
+
dma_start_free (this->start);
this->start = NULL;
@@ -1241,7 +1233,7 @@ dma_plugin_deactivate (AnjutaPlugin* plugin)
/* Public functions
*---------------------------------------------------------------------------*/
-DmaDebuggerQueue*
+DmaDebuggerQueue*
dma_debug_manager_get_queue (DebugManagerPlugin *self)
{
return self->queue;
@@ -1260,9 +1252,9 @@ static void
dma_plugin_instance_init (GObject* obj)
{
DebugManagerPlugin *plugin = ANJUTA_PLUGIN_DEBUG_MANAGER (obj);
-
+
plugin->uiid = 0;
-
+
plugin->project_root_uri = NULL;
plugin->queue = NULL;
plugin->current_editor = NULL;
@@ -1276,7 +1268,7 @@ dma_plugin_instance_init (GObject* obj)
plugin->view = NULL;
plugin->user_command_dialog = NULL;
-
+
/* plugin->uri = NULL; */
}
@@ -1289,7 +1281,7 @@ static void
dma_plugin_dispose (GObject* obj)
{
DebugManagerPlugin *plugin = ANJUTA_PLUGIN_DEBUG_MANAGER (obj);
-
+
if (plugin->user_command_dialog != NULL) gtk_widget_destroy (GTK_WIDGET (plugin->user_command_dialog));
G_OBJECT_CLASS (parent_class)->dispose (obj);
@@ -1312,14 +1304,14 @@ dma_plugin_finalize (GObject* obj)
{
g_object_remove_weak_pointer (G_OBJECT (self->current_editor), (gpointer *)(gpointer)&self->current_editor);
}
-
+
G_OBJECT_CLASS (parent_class)->finalize (obj);
}
/* class_init intialize the class itself not the instance */
static void
-dma_plugin_class_init (GObjectClass* klass)
+dma_plugin_class_init (GObjectClass* klass)
{
AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
diff --git a/plugins/debug-manager/stack_trace.c b/plugins/debug-manager/stack_trace.c
index 6cef131..fb05499 100644
--- a/plugins/debug-manager/stack_trace.c
+++ b/plugins/debug-manager/stack_trace.c
@@ -43,39 +43,42 @@
#define ANJUTA_PIXMAP_POINTER PACKAGE_PIXMAPS_DIR"/pointer.png"
-typedef struct _DmaThreadStackTrace
-{
- GtkTreeModel *model;
- gint thread;
- guint last_update;
-} DmaThreadStackTrace;
-
struct _StackTrace
{
DebugManagerPlugin *plugin;
DmaDebuggerQueue *debugger;
-
+
GtkActionGroup *action_group;
-
- DmaThreadStackTrace* current;
- GList *list;
- gint current_frame;
- guint current_update;
-
+ gint current_thread;
+ guint current_frame;
+
+ gulong changed_handler;
+
GtkTreeView *treeview;
GtkMenu *menu;
GtkWidget *scrolledwindow;
};
+typedef struct _StackPacket StackPacket;
+
+struct _StackPacket {
+ StackTrace* self;
+ guint thread;
+ gboolean scroll;
+ gboolean unblock;
+};
+
enum {
STACK_TRACE_ACTIVE_COLUMN,
+ STACK_TRACE_THREAD_COLUMN,
STACK_TRACE_FRAME_COLUMN,
STACK_TRACE_FILE_COLUMN,
STACK_TRACE_LINE_COLUMN,
STACK_TRACE_FUNC_COLUMN,
STACK_TRACE_ADDR_COLUMN,
STACK_TRACE_ARGS_COLUMN,
+ STACK_TRACE_DIRTY_COLUMN,
STACK_TRACE_URI_COLUMN,
STACK_TRACE_COLOR_COLUMN,
STACK_TRACE_N_COLUMNS
@@ -84,46 +87,63 @@ enum {
/* Helpers functions
*---------------------------------------------------------------------------*/
-static gboolean
+static gboolean
get_current_iter (GtkTreeView *view, GtkTreeIter* iter)
{
GtkTreeSelection *selection;
-
+
selection = gtk_tree_view_get_selection (view);
return gtk_tree_selection_get_selected (selection, NULL, iter);
}
/*
- * returns the current stack frame or -1 on error
+ * returns TRUE if a frame is selected
*/
-static gint
-get_current_index (StackTrace* st)
+static gboolean
+get_current_frame_and_thread (StackTrace* st, guint *frame, gint *thread)
{
GtkTreeIter iter;
-
+
if (get_current_iter (st->treeview, &iter))
{
GtkTreeModel *model;
- gint frame_no;
-
- model = gtk_tree_view_get_model (st->treeview);
- gtk_tree_model_get (model, &iter, STACK_TRACE_FRAME_COLUMN, &frame_no, -1);
-
- return frame_no;
+ GtkTreeIter parent;
+ gchar *str;
+
+ model = gtk_tree_view_get_model (st->treeview);
+ *frame = 0;
+ if (gtk_tree_model_iter_parent (model, &parent, &iter))
+ {
+ gtk_tree_model_get (model, &iter, STACK_TRACE_FRAME_COLUMN, &str, -1);
+ if (str != NULL)
+ {
+ *frame = strtoul (str, NULL, 10);
+ g_free (str);
+ }
+ gtk_tree_model_get (model, &parent, STACK_TRACE_THREAD_COLUMN, &str, -1);
+ }
+ else
+ {
+ gtk_tree_model_get (model, &iter, STACK_TRACE_THREAD_COLUMN, &str, -1);
+ }
+ *thread = (str != NULL) ? strtoul (str, NULL, 10) : 0;
+ g_free (str);
+
+ return thread != 0 ? TRUE : FALSE;
}
else
{
- return -1;
+ return FALSE;
}
}
static gboolean
-my_gtk_tree_model_get_iter_last(GtkTreeModel *model, GtkTreeIter *last)
+my_gtk_tree_model_get_iter_last(GtkTreeModel *model, GtkTreeIter *parent, GtkTreeIter *last)
{
gboolean exist;
GtkTreeIter iter;
- exist = gtk_tree_model_get_iter_first(model, &iter);
+ exist = gtk_tree_model_iter_children(model, &iter, parent);
if (!exist) return FALSE;
do
@@ -132,7 +152,7 @@ my_gtk_tree_model_get_iter_last(GtkTreeModel *model, GtkTreeIter *last)
exist = gtk_tree_model_iter_next(model, &iter);
}
while (exist);
-
+
return TRUE;
}
@@ -141,7 +161,7 @@ my_gtk_tree_model_iter_prev(GtkTreeModel *model, GtkTreeIter *iter)
{
GtkTreePath* path;
gboolean exist;
-
+
path = gtk_tree_model_get_path (model, iter);
exist = gtk_tree_path_prev (path);
if (exist)
@@ -149,7 +169,7 @@ my_gtk_tree_model_iter_prev(GtkTreeModel *model, GtkTreeIter *iter)
exist = gtk_tree_model_get_iter (model, iter, path);
}
gtk_tree_path_free (path);
-
+
return exist;
}
@@ -164,58 +184,132 @@ my_gtk_tree_iter_compare(GtkTreeModel *model, GtkTreeIter *itera, GtkTreeIter *i
pathb = gtk_tree_model_get_path (model, iterb);
comp = gtk_tree_path_compare (patha, pathb);
-
+
gtk_tree_path_free (patha);
gtk_tree_path_free (pathb);
-
+
return comp;
}
+static gboolean
+find_thread (GtkTreeModel *model, GtkTreeIter *iter, guint thread)
+{
+ gboolean found;
+
+ for (found = gtk_tree_model_get_iter_first (model, iter); found; found = gtk_tree_model_iter_next (model, iter))
+ {
+ gchar *str;
+ guint id;
+
+ gtk_tree_model_get (model, iter, STACK_TRACE_THREAD_COLUMN, &str, -1);
+ if (str != NULL)
+ {
+ id = strtoul (str, NULL, 10);
+ g_free (str);
+ if (id == thread) break;
+ }
+ }
+
+ return found;
+}
+
/* Private functions
*---------------------------------------------------------------------------*/
static void
-on_clear_stack_trace (gpointer data, gpointer user_data)
+set_stack_frame (StackTrace *self, guint frame, gint thread)
{
- DmaThreadStackTrace *trace = (DmaThreadStackTrace *) data;
-
- g_object_unref (G_OBJECT (trace->model));
- g_free (trace);
-}
+ GtkTreeIter parent;
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ gboolean valid;
-static void
-dma_thread_clear_all_stack_trace (StackTrace *self)
-{
- /* Clear all GtkListStore */
- g_list_foreach (self->list, (GFunc)on_clear_stack_trace, NULL);
- g_list_free (self->list);
-
- self->current = NULL;
- self->list = NULL;
+ model = gtk_tree_view_get_model (self->treeview);
+
+ /* Clear old pointer */
+ valid = find_thread (model, &parent, self->current_thread);
+ if (valid)
+ {
+ if (gtk_tree_model_iter_nth_child (model, &iter, &parent, self->current_frame))
+ {
+ /* clear pixmap on the previous active frame */
+ gtk_tree_store_set (GTK_TREE_STORE (model), &iter,
+ STACK_TRACE_ACTIVE_COLUMN, NULL, -1);
+ }
+ }
+
+ if (self->current_thread != thread)
+ {
+ self->current_thread = thread;
+ valid = find_thread (model, &parent, self->current_thread);
+ }
+
+ /* Set pointer on current frame if possible */
+ self->current_frame = frame;
+ if (valid)
+ {
+ if (gtk_tree_model_iter_nth_child (model, &iter, &parent, self->current_frame))
+ {
+ GdkPixbuf *pointer_pix = gdk_pixbuf_new_from_file (ANJUTA_PIXMAP_POINTER, NULL);
+
+ gtk_tree_store_set (GTK_TREE_STORE(model), &iter,
+ STACK_TRACE_ACTIVE_COLUMN, pointer_pix,
+ -1);
+ g_object_unref (pointer_pix);
+ }
+ }
}
static void
on_stack_trace_updated (const GList *stack, gpointer user_data, GError *error)
{
- StackTrace *self = (StackTrace *)user_data;
- const GList *node;
- GtkListStore *model;
+ StackPacket *packet = (StackPacket *)user_data;
+ StackTrace *self;
+ guint thread;
+ gboolean scroll;
+ GtkTreeModel *model;
GtkTreeIter iter;
+ GtkTreeIter parent;
+ const GList *node;
gboolean exist;
- GdkPixbuf *pic;
+ GtkTreePath *path;
+
+ g_return_if_fail (packet != NULL);
+
+ self = packet->self;
+ thread = packet->thread;
+ scroll = packet->scroll;
+ if (packet->unblock) g_signal_handler_unblock (self->plugin, self->changed_handler);
+ g_slice_free (StackPacket, packet);
if (error != NULL) return;
-
- model = GTK_LIST_STORE (self->current->model);
- pic = gdk_pixbuf_new_from_file (ANJUTA_PIXMAP_POINTER, NULL);
-
- exist = my_gtk_tree_model_get_iter_last (GTK_TREE_MODEL (model), &iter);
-
+ model = gtk_tree_view_get_model (self->treeview);
+
+ if (!find_thread (model, &parent, thread)) return;
+
+ /* Check if there are already some data */
+ exist = my_gtk_tree_model_get_iter_last (GTK_TREE_MODEL (model), &parent, &iter);
+ if (exist)
+ {
+ GValue val = {0};
+
+ gtk_tree_model_get_value(model, &iter, STACK_TRACE_FRAME_COLUMN, &val);
+ if (!G_IS_VALUE (&val))
+ {
+ /* Remove dummy child */
+ gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
+
+ exist = FALSE;
+ }
+ }
+
for (node = (const GList *)g_list_last((GList *)stack); node != NULL; node = node->prev)
{
IAnjutaDebuggerFrame *frame;
- gchar *adr;
+ gchar *frame_str;
+ gchar *adr_str;
+ gchar *line_str;
gchar *uri;
gchar *file;
@@ -224,18 +318,18 @@ on_stack_trace_updated (const GList *stack, gpointer user_data, GError *error)
if (exist)
{
/* Check if it's the same stack frame */
- gchar *adr;
gchar *args;
gulong address;
guint line;
gboolean same;
-
+
gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
- STACK_TRACE_ADDR_COLUMN, &adr,
- STACK_TRACE_LINE_COLUMN, &line,
+ STACK_TRACE_ADDR_COLUMN, &adr_str,
+ STACK_TRACE_LINE_COLUMN, &line_str,
STACK_TRACE_ARGS_COLUMN, &args,
-1);
- address = adr != NULL ? strtoul (adr, NULL, 0) : 0;
+ address = adr_str != NULL ? strtoul (adr_str, NULL, 0) : 0;
+ line = line_str != NULL ? strtoul (line_str, NULL, 10) : 0;
same = (address == frame->address) && (line == frame->line);
if ((args == NULL) || (frame->args == NULL))
{
@@ -245,19 +339,18 @@ on_stack_trace_updated (const GList *stack, gpointer user_data, GError *error)
{
same = same && (strcmp (args, frame->args) == 0);
}
- g_free (adr);
- g_free (args);
-
+
if (same)
{
/* Same frame, just change the color */
- gtk_list_store_set (model, &iter,
- STACK_TRACE_ACTIVE_COLUMN, frame->level == self->current_frame ? pic : NULL,
- STACK_TRACE_FRAME_COLUMN, frame->level,
+ frame_str = g_strdup_printf ("%d", frame->level);
+ gtk_tree_store_set (GTK_TREE_STORE (model), &iter,
+ STACK_TRACE_ACTIVE_COLUMN, NULL,
+ STACK_TRACE_FRAME_COLUMN, frame_str,
STACK_TRACE_COLOR_COLUMN, "black", -1);
-
+
/* Check previous frame */
- exist = my_gtk_tree_model_iter_prev (GTK_TREE_MODEL (model), &iter);
+ exist = my_gtk_tree_model_iter_prev (model, &iter);
if (!exist || (node->prev != NULL))
{
/* Last frame or Upper frame still exist */
@@ -265,16 +358,19 @@ on_stack_trace_updated (const GList *stack, gpointer user_data, GError *error)
}
/* Upper frame do not exist, remove all them */
}
-
+ g_free (frame_str);
+ g_free (adr_str);
+ g_free (args);
+
/* New frame, remove all previous frame */
GtkTreeIter first;
-
- gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &first);
- while (my_gtk_tree_iter_compare (GTK_TREE_MODEL (model), &first, &iter) < 0)
+
+ gtk_tree_model_iter_children (model, &first, &parent);
+ while (my_gtk_tree_iter_compare (model, &first, &iter) < 0)
{
- gtk_list_store_remove (model, &first);
+ gtk_tree_store_remove (GTK_TREE_STORE (model), &first);
}
- gtk_list_store_remove (model, &first);
+ gtk_tree_store_remove (GTK_TREE_STORE (model), &first);
if (same)
{
@@ -285,14 +381,15 @@ on_stack_trace_updated (const GList *stack, gpointer user_data, GError *error)
exist = FALSE;
}
}
-
- gtk_list_store_prepend (model, &iter);
- adr = g_strdup_printf ("0x%lx", frame->address);
+ gtk_tree_store_prepend (GTK_TREE_STORE (model), &iter, &parent);
+
+ frame_str = g_strdup_printf ("%d", frame->level);
+ adr_str = g_strdup_printf ("0x%lx", frame->address);
if (frame->file)
{
if (g_path_is_absolute (frame->file))
- {
+ {
GFile *gio_file = g_file_new_for_path (frame->file);
uri = g_file_get_uri (gio_file);
file = strrchr(frame->file, G_DIR_SEPARATOR) + 1;
@@ -303,186 +400,214 @@ on_stack_trace_updated (const GList *stack, gpointer user_data, GError *error)
uri = NULL;
file = frame->file;
}
+ line_str = g_strdup_printf ("%d", frame->line);
}
else
{
uri = NULL;
file = frame->library;
+ line_str = NULL;
}
-
- gtk_list_store_set(model, &iter,
- STACK_TRACE_ACTIVE_COLUMN, frame->level == self->current_frame ? pic : NULL,
- STACK_TRACE_FRAME_COLUMN, frame->level,
+
+ gtk_tree_store_set(GTK_TREE_STORE (model), &iter,
+ STACK_TRACE_ACTIVE_COLUMN, NULL,
+ STACK_TRACE_FRAME_COLUMN, frame_str,
STACK_TRACE_FILE_COLUMN, file,
- STACK_TRACE_LINE_COLUMN, frame->line,
+ STACK_TRACE_LINE_COLUMN, line_str,
STACK_TRACE_FUNC_COLUMN, frame->function,
- STACK_TRACE_ADDR_COLUMN, adr,
+ STACK_TRACE_ADDR_COLUMN, adr_str,
STACK_TRACE_ARGS_COLUMN, frame->args,
STACK_TRACE_URI_COLUMN, uri,
STACK_TRACE_COLOR_COLUMN, "red",
-1);
g_free (uri);
- g_free (adr);
+ g_free (line_str);
+ g_free (adr_str);
+ g_free (frame_str);
+ }
+ gtk_tree_store_set(GTK_TREE_STORE (model), &parent,
+ STACK_TRACE_DIRTY_COLUMN, FALSE,
+ -1);
+
+ /* Expand and show new path */
+ path = gtk_tree_model_get_path (model, &parent);
+ gtk_tree_view_expand_row (self->treeview, path, FALSE);
+ if (self->current_thread == thread)
+ {
+ set_stack_frame (self, self->current_frame, self->current_thread);
+ gtk_tree_view_scroll_to_cell (self->treeview, path, NULL, FALSE, 0, 0);
}
- g_object_unref (pic);
-
+ gtk_tree_path_free (path);
}
-static DmaThreadStackTrace*
-dma_thread_create_new_stack_trace (StackTrace *self, gint thread)
-{
- DmaThreadStackTrace *trace;
- GtkListStore *store;
-
- /* Create new list store */
- store = gtk_list_store_new (STACK_TRACE_N_COLUMNS,
- GDK_TYPE_PIXBUF,
- G_TYPE_UINT,
- G_TYPE_STRING,
- G_TYPE_UINT,
- G_TYPE_STRING,
- G_TYPE_STRING,
- G_TYPE_STRING,
- G_TYPE_STRING,
- G_TYPE_STRING);
-
- trace = g_new (DmaThreadStackTrace, 1);
- trace->thread = thread;
- trace->model = GTK_TREE_MODEL (store);
- trace->last_update = self->current_update;
-
- self->current = trace;
-
- /* Ask debugger to get all frame data */
- dma_queue_list_frame (
- self->debugger,
- (IAnjutaDebuggerCallback)on_stack_trace_updated,
- self);
-
- self->list = g_list_append (self->list, trace);
-
- return trace;
-}
-static DmaThreadStackTrace*
-dma_thread_update_stack_trace (StackTrace *self, DmaThreadStackTrace *trace)
+static void
+list_stack_frame (StackTrace *self, guint thread, gboolean update)
{
- trace->last_update = self->current_update;
-
- /* Ask debugger to get all frame data */
- dma_queue_list_frame (
- self->debugger,
- (IAnjutaDebuggerCallback)on_stack_trace_updated,
- self);
-
- return trace;
-}
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gboolean found;
+ gboolean dirty;
-static gboolean
-on_find_stack_trace (gconstpointer a, gconstpointer b)
-{
- const DmaThreadStackTrace *trace = (const DmaThreadStackTrace *)a;
- guint thread = GPOINTER_TO_UINT(b);
-
- return trace->thread != thread;
+ model = gtk_tree_view_get_model (self->treeview);
+
+ if (!update)
+ {
+ /* Search thread */
+ found = find_thread (model, &iter, thread);
+ if (found)
+ {
+ /* Check if stack trace need to be updated */
+ gtk_tree_model_get(model, &iter, STACK_TRACE_DIRTY_COLUMN, &dirty, -1);
+ }
+ }
+
+ /* Update stack trace */
+ if (update || !found || dirty)
+ {
+ StackPacket *packet;
+
+ if (thread != self->current_thread)
+ {
+ /* Change current thread temporarily */
+ dma_queue_set_thread (self->debugger, thread);
+ g_signal_handler_block (self->plugin, self->changed_handler);
+ }
+ packet = g_slice_new (StackPacket);
+ packet->thread = thread;
+ packet->self = self;
+ packet->scroll = update;
+ packet->unblock = thread != self->current_thread;
+ dma_queue_list_frame (self->debugger,
+ (IAnjutaDebuggerCallback)on_stack_trace_updated,
+ packet);
+ if (thread != self->current_thread) dma_queue_set_thread (self->debugger, self->current_thread);
+ }
}
static void
-dma_thread_set_stack_trace (StackTrace *self, guint thread)
+on_thread_updated (const GList *threads, gpointer user_data)
{
- GList *list;
- DmaThreadStackTrace *trace;
+ StackTrace *self = (StackTrace *)user_data;
+ GList *node;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gboolean valid;
+ GList *new_threads;
+
+ model = gtk_tree_view_get_model (self->treeview);
- if ((self->current == NULL) || (self->current->thread != thread) || (self->current->last_update != self->current_update))
+ /* Remove completed threads */
+ new_threads = g_list_copy ((GList *)threads);
+ valid = gtk_tree_model_get_iter_first (model, &iter);
+ while (valid)
{
- self->current_frame = 0;
-
- list = g_list_find_custom (self->list, GINT_TO_POINTER(thread), on_find_stack_trace);
-
- if (list == NULL)
+ gchar *str;
+ gint thread;
+
+ gtk_tree_model_get(model, &iter, STACK_TRACE_THREAD_COLUMN, &str, -1);
+ thread = (str != NULL) ? strtoul (str, NULL, 10) : 0;
+ g_free (str);
+
+ for (node = new_threads; node != NULL; node = node->next)
{
- /* Create new stack trace */
- trace = dma_thread_create_new_stack_trace(self, thread);
+ if (((IAnjutaDebuggerFrame *)node->data)->thread == thread) break;
}
- else
+
+ if (node != NULL)
{
- trace = (DmaThreadStackTrace *)list->data;
- self->current = trace;
-
- if (trace->last_update != self->current_update)
+ GtkTreePath *path;
+
+ /* Thread still existing */
+ new_threads = g_list_delete_link (new_threads, node);
+ /* Set content as dirty */
+ gtk_tree_store_set(GTK_TREE_STORE (model), &iter,
+ STACK_TRACE_DIRTY_COLUMN, TRUE,
+ STACK_TRACE_COLOR_COLUMN, "black",
+ -1);
+
+ /* Update stack frame if it is visible */
+ path = gtk_tree_model_get_path (model, &iter);
+ if (gtk_tree_view_row_expanded (self->treeview, path))
{
- /* Update stack trace */
- dma_thread_update_stack_trace (self, trace);
+ list_stack_frame (self, thread, TRUE);
}
+ gtk_tree_path_free (path);
+
+ valid = gtk_tree_model_iter_next (model, &iter);
}
- gtk_tree_view_set_model (self->treeview, trace->model);
+ else
+ {
+ /* Thread completed */
+ valid = gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
+ }
+ }
+
+
+ /* Add new threads */
+ while (new_threads != NULL)
+ {
+ GtkTreeIter child;
+ gchar *str;
+
+ str = g_strdup_printf ("%d", ((IAnjutaDebuggerFrame *)new_threads->data)->thread);
+ gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
+ gtk_tree_store_set(GTK_TREE_STORE (model), &iter,
+ STACK_TRACE_THREAD_COLUMN, str,
+ STACK_TRACE_DIRTY_COLUMN, TRUE,
+ STACK_TRACE_COLOR_COLUMN, "red",
+ -1);
+ g_free (str);
+
+ /* Add a dummy child, to get the row expander */
+ gtk_tree_store_append (GTK_TREE_STORE (model), &child, &iter);
+
+ new_threads = g_list_delete_link (new_threads, new_threads);
}
}
+static void
+list_threads (StackTrace *self)
+{
+ dma_queue_list_thread (
+ self->debugger,
+ (IAnjutaDebuggerCallback)on_thread_updated,
+ self);
+}
+
+
+
/* Callback functions
*---------------------------------------------------------------------------*/
static void
-on_frame_changed (StackTrace *self, guint frame, gint thread)
+on_stack_frame_set_activate (GtkAction *action, gpointer user_data)
{
- GtkTreeIter iter;
- GtkTreeModel *model;
+ StackTrace *self;
+ gint thread;
+ guint frame;
- /* Change thread */
- dma_thread_set_stack_trace (self, thread);
-
- /* Change frame */
- self->current_frame = frame;
-
- model = self->current->model;
-
- /* Clear old pointer */
- if(gtk_tree_model_get_iter_first (model, &iter))
+ self = (StackTrace*) user_data;
+
+ if (get_current_frame_and_thread (self, &frame, &thread))
{
- do
+ if (thread != self->current_thread)
{
- /* clear pixmap on the previous active frame */
- gtk_list_store_set (GTK_LIST_STORE (model), &iter,
- STACK_TRACE_ACTIVE_COLUMN, NULL, -1);
- } while (gtk_tree_model_iter_next (model, &iter));
- }
-
- /* Set pointer to current frame */
- if (gtk_tree_model_iter_nth_child (model, &iter, NULL, self->current_frame))
- {
- GdkPixbuf *pointer_pix = gdk_pixbuf_new_from_file (ANJUTA_PIXMAP_POINTER, NULL);
-
- /* set pointer on this frame */
- gtk_list_store_set (GTK_LIST_STORE(model), &iter,
- STACK_TRACE_ACTIVE_COLUMN, pointer_pix,
- -1);
- g_object_unref (pointer_pix);
+ dma_queue_set_thread (self->debugger, thread);
+ dma_queue_set_frame (self->debugger, frame);
+ set_stack_frame (self, frame, thread);
+ list_stack_frame (self, thread, FALSE);
+ }
+ else if (frame != self->current_frame)
+ {
+ dma_queue_set_frame (self->debugger, frame);
+ set_stack_frame (self, frame, thread);
+ list_stack_frame (self, thread, FALSE);
+ }
}
}
static void
-on_stack_frame_set_activate (GtkAction *action, gpointer user_data)
-{
- StackTrace *st;
- guint selected_frame;
-
- st = (StackTrace*) user_data;
-
- selected_frame = get_current_index (st);
-
- /* No frame selected */
- if (selected_frame == -1)
- return;
-
- /* current frame is already active */
- if (selected_frame == st->current_frame)
- return;
-
- /* issue a command to switch active frame to new location */
- dma_queue_set_frame (st->debugger, selected_frame);
-}
-
-static void
on_stack_view_source_activate (GtkAction *action, gpointer user_data)
{
GtkTreeModel *model;
@@ -490,11 +615,12 @@ on_stack_view_source_activate (GtkAction *action, gpointer user_data)
GtkTreeIter iter;
GtkTreeView *view;
gchar *uri;
+ gchar *line_str;
guint line;
- gchar *adr;
+ gchar *adr_str;
gulong address;
-
- StackTrace* st = (StackTrace*) user_data;
+
+ StackTrace* st = (StackTrace*) user_data;
view = st->treeview;
selection = gtk_tree_view_get_selection (view);
@@ -504,14 +630,16 @@ on_stack_view_source_activate (GtkAction *action, gpointer user_data)
/* get the frame info */
gtk_tree_model_get (model, &iter,
STACK_TRACE_URI_COLUMN, &uri,
- STACK_TRACE_LINE_COLUMN, &line,
- STACK_TRACE_ADDR_COLUMN, &adr,
+ STACK_TRACE_LINE_COLUMN, &line_str,
+ STACK_TRACE_ADDR_COLUMN, &adr_str,
-1);
-
- address = adr != NULL ? strtoul (adr, NULL, 0) : 0;
+
+ address = adr_str != NULL ? strtoul (adr_str, NULL, 0) : 0;
+ line = line_str != NULL ? strtoul (line_str, NULL, 0) : 0;
g_signal_emit_by_name (st->plugin, "location-changed", address, uri, line);
g_free (uri);
- g_free (adr);
+ g_free (line_str);
+ g_free (adr_str);
}
static void
@@ -530,7 +658,7 @@ on_got_stack_trace (const gchar *trace, gpointer user_data, GError *error)
static void
on_stack_get_trace (GtkAction *action, gpointer user_data)
{
- StackTrace* st = (StackTrace*) user_data;
+ StackTrace* st = (StackTrace*) user_data;
/* Ask debugger to get all frame data */
dma_queue_dump_stack_trace (
@@ -548,6 +676,25 @@ on_stack_trace_row_activated (GtkTreeView *treeview,
on_stack_frame_set_activate (NULL, st);
}
+static void
+on_stack_trace_row_expanded (GtkTreeView *treeview,
+ GtkTreeIter *iter,
+ GtkTreePath *path,
+ StackTrace *st)
+{
+ GtkTreeModel *model;
+ gchar *str;
+ guint thread;
+
+ model = gtk_tree_view_get_model (treeview);
+
+ gtk_tree_model_get (model, iter, STACK_TRACE_THREAD_COLUMN, &str, -1);
+ thread = (str != NULL) ? strtoul (str, NULL, 10) : 0;
+ g_free (str);
+
+ list_stack_frame (st, thread, FALSE);
+}
+
static gboolean
on_stack_trace_button_press (GtkWidget *widget, GdkEventButton *bevent, gpointer user_data)
{
@@ -565,7 +712,7 @@ on_stack_trace_button_press (GtkWidget *widget, GdkEventButton *bevent, gpointer
/* Double left mouse click */
on_stack_view_source_activate (NULL, user_data);
}
-
+
return FALSE;
}
@@ -597,7 +744,7 @@ static GtkActionEntry actions_stack_trace[] = {
NULL,
G_CALLBACK (on_stack_get_trace)
}
-};
+};
static void
create_stack_trace_gui(StackTrace *st)
@@ -609,21 +756,23 @@ create_stack_trace_gui(StackTrace *st)
AnjutaUI *ui;
g_return_if_fail (st->scrolledwindow == NULL);
-
+
/* Create tree view */
- model = GTK_TREE_MODEL(gtk_list_store_new (STACK_TRACE_N_COLUMNS,
+ model = GTK_TREE_MODEL(gtk_tree_store_new (STACK_TRACE_N_COLUMNS,
GDK_TYPE_PIXBUF,
- G_TYPE_UINT,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
G_TYPE_STRING,
- G_TYPE_UINT,
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_STRING,
+ G_TYPE_BOOLEAN,
G_TYPE_STRING,
G_TYPE_STRING));
st->treeview = GTK_TREE_VIEW (gtk_tree_view_new_with_model (model));
g_object_unref (G_OBJECT (model));
-
+
selection = gtk_tree_view_get_selection (st->treeview);
gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
@@ -636,9 +785,21 @@ create_stack_trace_gui(StackTrace *st)
gtk_tree_view_column_add_attribute (column, renderer, "pixbuf",
STACK_TRACE_ACTIVE_COLUMN);
gtk_tree_view_append_column (st->treeview, column);
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+ gtk_tree_view_column_set_title (column, _("Thread"));
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_column_add_attribute (column, renderer, "text",
+ STACK_TRACE_THREAD_COLUMN);
+ gtk_tree_view_column_add_attribute (column, renderer, "foreground",
+ STACK_TRACE_COLOR_COLUMN);
+ gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+ gtk_tree_view_append_column (st->treeview, column);
gtk_tree_view_set_expander_column (st->treeview,
column);
-
+
column = gtk_tree_view_column_new ();
gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
gtk_tree_view_column_set_title (column, _("Frame"));
@@ -650,9 +811,7 @@ create_stack_trace_gui(StackTrace *st)
STACK_TRACE_COLOR_COLUMN);
gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
gtk_tree_view_append_column (st->treeview, column);
- gtk_tree_view_set_expander_column (st->treeview,
- column);
-
+
column = gtk_tree_view_column_new ();
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, renderer, TRUE);
@@ -674,7 +833,7 @@ create_stack_trace_gui(StackTrace *st)
gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
gtk_tree_view_column_set_title (column, _("Line"));
gtk_tree_view_append_column (st->treeview, column);
-
+
column = gtk_tree_view_column_new ();
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, renderer, TRUE);
@@ -685,7 +844,7 @@ create_stack_trace_gui(StackTrace *st)
gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
gtk_tree_view_column_set_title (column, _("Function"));
gtk_tree_view_append_column (st->treeview, column);
-
+
if (dma_debugger_queue_is_supported (st->debugger, HAS_MEMORY))
{
/* Display address only if debugger has such concept */
@@ -700,7 +859,7 @@ create_stack_trace_gui(StackTrace *st)
gtk_tree_view_column_set_title (column, _("Address"));
gtk_tree_view_append_column (st->treeview, column);
}
-
+
column = gtk_tree_view_column_new ();
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, renderer, TRUE);
@@ -711,15 +870,16 @@ create_stack_trace_gui(StackTrace *st)
gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
gtk_tree_view_column_set_title (column, _("Arguments"));
gtk_tree_view_append_column (st->treeview, column);
-
+
/* Create popup menu */
ui = anjuta_shell_get_ui (ANJUTA_PLUGIN(st->plugin)->shell, NULL);
st->menu = GTK_MENU (gtk_ui_manager_get_widget (GTK_UI_MANAGER (ui), "/PopupStack"));
-
+
/* Connect signal */
- g_signal_connect (st->treeview, "button-press-event", G_CALLBACK (on_stack_trace_button_press), st);
- g_signal_connect (st->treeview, "row-activated", G_CALLBACK (on_stack_trace_row_activated), st);
-
+ g_signal_connect (st->treeview, "button-press-event", G_CALLBACK (on_stack_trace_button_press), st);
+ g_signal_connect (st->treeview, "row-activated", G_CALLBACK (on_stack_trace_row_activated), st);
+ g_signal_connect (st->treeview, "row-expanded", G_CALLBACK (on_stack_trace_row_expanded), st);
+
/* Add stack window */
st->scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (st->scrolledwindow),
@@ -730,7 +890,7 @@ create_stack_trace_gui(StackTrace *st)
gtk_container_add (GTK_CONTAINER (st->scrolledwindow),
GTK_WIDGET (st->treeview));
gtk_widget_show_all (st->scrolledwindow);
-
+
anjuta_shell_add_widget (ANJUTA_PLUGIN(st->plugin)->shell,
st->scrolledwindow,
"AnjutaDebuggerStack", _("Stack"),
@@ -750,10 +910,19 @@ destroy_stack_trace_gui (StackTrace *st)
}
static void
+on_frame_changed (StackTrace *self, guint frame, gint thread)
+{
+ set_stack_frame (self, frame, thread);
+ list_stack_frame (self, thread, FALSE);
+}
+
+static void
on_program_moved (StackTrace *self, guint pid, gint thread)
{
- self->current_update++;
- dma_thread_set_stack_trace (self, thread);
+ set_stack_frame (self, 0, thread);
+
+ list_threads (self);
+ list_stack_frame (self, thread, TRUE);
}
static void
@@ -762,20 +931,20 @@ on_program_exited (StackTrace *self)
g_signal_handlers_disconnect_by_func (self->plugin, G_CALLBACK (on_program_exited), self);
g_signal_handlers_disconnect_by_func (self->plugin, G_CALLBACK (on_program_moved), self);
g_signal_handlers_disconnect_by_func (self->plugin, G_CALLBACK (on_frame_changed), self);
-
- dma_thread_clear_all_stack_trace (self);
+
destroy_stack_trace_gui (self);
}
static void
on_program_started (StackTrace *self)
{
- self->current_update = 0;
create_stack_trace_gui (self);
-
+ self->current_thread = 0;
+ self->current_frame = 0;
+
g_signal_connect_swapped (self->plugin, "program-exited", G_CALLBACK (on_program_exited), self);
g_signal_connect_swapped (self->plugin, "program-moved", G_CALLBACK (on_program_moved), self);
- g_signal_connect_swapped (self->plugin, "frame-changed", G_CALLBACK (on_frame_changed), self);
+ self->changed_handler = g_signal_connect_swapped (self->plugin, "frame-changed", G_CALLBACK (on_frame_changed), self);
}
/* Public functions
@@ -806,7 +975,7 @@ stack_trace_new (DebugManagerPlugin *plugin)
GETTEXT_PACKAGE, TRUE, st);
g_signal_connect_swapped (st->plugin, "program-started", G_CALLBACK (on_program_started), st);
-
+
return st;
}
@@ -814,18 +983,18 @@ void
stack_trace_free (StackTrace * st)
{
AnjutaUI *ui;
-
+
g_return_if_fail (st != NULL);
/* Disconnect from debugger */
- g_signal_handlers_disconnect_matched (st->plugin, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, st);
+ g_signal_handlers_disconnect_matched (st->plugin, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, st);
/* Remove menu actions */
ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (st->plugin)->shell, NULL);
anjuta_ui_remove_action_group (ui, st->action_group);
-
+
/* Destroy menu */
destroy_stack_trace_gui (st);
-
+
g_free (st);
}
diff --git a/po/POTFILES.in b/po/POTFILES.in
index f6eac01..c0b5e3f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -74,7 +74,6 @@ plugins/debug-manager/sparse_buffer.c
plugins/debug-manager/sparse_view.c
plugins/debug-manager/stack_trace.c
plugins/debug-manager/start.c
-plugins/debug-manager/threads.c
plugins/debug-manager/utilities.c
plugins/debug-manager/watch.c
plugins/devhelp/plugin.c
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]