From bb16c16f9d2abfe3beb1bd6cce909a3bdce7f9ad Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Granjoux?= Date: Fri, 21 Oct 2011 22:20:31 +0200 Subject: [PATCH] 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(-) delete mode 100644 manuals/anjuta-manual/C/debug-thread.page delete mode 100644 plugins/debug-manager/threads.c delete mode 100644 plugins/debug-manager/threads.h diff --git a/manuals/anjuta-manual/C/debug-stack.page b/manuals/anjuta-manual/C/debug-stack.page index fb2c37cdf..e59b1a238 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.

+

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.

+

From the main menu, select View @@ -37,7 +41,8 @@ -

Each stack frame contains the following information:

+

The stacks are displayed in a tree view having their corresponding + thread as parent and displaying the following information:

@@ -48,6 +53,10 @@ the active stack frame to examine local variables in other functions.

+ Thread +

This is a number corresponding to each thread.

+
+ Frame

This is the frame number starting from 0 for the current function. The first function of your program, for example main() in a C program, @@ -80,7 +89,7 @@

- Change the current stack frame + Change the current stack frame or thread @@ -90,6 +99,12 @@

Right-click and select Set current frame.

+ +

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.

diff --git a/manuals/anjuta-manual/C/debug-thread.page b/manuals/anjuta-manual/C/debug-thread.page deleted file mode 100644 index ae0965fb3..000000000 --- a/manuals/anjuta-manual/C/debug-thread.page +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - - Examine threads. - - - Sébastien Granjoux - seb.sfo@free.fr - - - Philip Chimento - philip.chimento@gmail.com - - - - Threads - -
- List threads - -

A program can be composed of several threads. All these threads are - executed independently, having their own registers, stack and local - variables, but sharing global variables.

- - - -

From the main menu, select View - Thread to open the Thread - window.

-
-
- -

The window shows the following information about each thread:

- - - - Active -

This contains a yellow arrow that points to the active thread.

-
- - ID -

This is a number corresponding to each thread.

-
- - File -

The name of the file containing the function corresponding to - the current frame of the current thread.

-
- - Line -

The line number of the function corresponding to the current - frame of the current thread.

-
- - Function -

The name of the function corresponding to the frame of the - current thread.

-
- - Address -

The address of the function corresponding to the frame of the - current thread.

-
-
- -
- -
- Change current thread - -

The current thread is the thread whose stack and local variables are - currently displayed in the debugger.

- - - -

In the Thread window, select the thread you want.

-
- -

Right-click and select Set current thread.

-
-
-
- - -
- View current function - - - -

In the Thread window, select the thread you want.

-
- -

Double-click, or right-click and select View Source.

-
-
-
- - -
diff --git a/manuals/anjuta-manual/Makefile.am b/manuals/anjuta-manual/Makefile.am index b7af61a55..d247eaf15 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 90f9e985b..cd7ba5cfc 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 168e97379..44c8f92d9 100644 --- a/plugins/debug-manager/anjuta-debug-manager.xml +++ b/plugins/debug-manager/anjuta-debug-manager.xml @@ -86,10 +86,6 @@ - - - - diff --git a/plugins/debug-manager/plugin.c b/plugins/debug-manager/plugin.c index e9b583172..522434714 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"), - "F5", - N_("Single step out of function"), - G_CALLBACK (on_step_out_action_activate) + N_("Step _Out"), + "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 6cef1310d..fb0549985 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/plugins/debug-manager/threads.c b/plugins/debug-manager/threads.c deleted file mode 100644 index 5f4de8ece..000000000 --- a/plugins/debug-manager/threads.c +++ /dev/null @@ -1,644 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ -/* - threads.c - Copyright (C) 2007 Sébastien Granjoux - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "threads.h" - -#include "queue.h" - -#include -#include -#include -#include -#include -#include - -/*#define DEBUG*/ -#include -#include -#include -#include - -#include "utilities.h" -#include "info.h" - -#define ANJUTA_PIXMAP_POINTER PACKAGE_PIXMAPS_DIR"/pointer.png" - -struct _DmaThreads -{ - DebugManagerPlugin *plugin; - DmaDebuggerQueue *debugger; - - /* GUI */ - GtkWidget *scrolledwindow; - GtkTreeView *list; - GtkMenu *menu; - GtkActionGroup *action_group; - - gint current_thread; -}; - -struct _DmaThreadPacket { - GtkTreeModel *model; - GtkTreeRowReference* reference; - DmaThreads* self; -}; - -enum { - THREAD_ACTIVE_COLUMN, - THREAD_ID_COLUMN, - THREAD_FILE_COLUMN, - THREAD_LINE_COLUMN, - THREAD_FUNC_COLUMN, - THREAD_ADDR_COLUMN, - THREAD_URI_COLUMN, - THREAD_N_COLUMNS -}; - - -/* Helpers functions - *---------------------------------------------------------------------------*/ - -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 thread or -1 on error - */ -static gint -get_current_index (DmaThreads *self) -{ - GtkTreeIter iter; - - if (get_current_iter (self->list, &iter)) - { - GtkTreeModel *model; - gint thread_no; - - model = gtk_tree_view_get_model (self->list); - gtk_tree_model_get (model, &iter, THREAD_ID_COLUMN, &thread_no, -1); - - return thread_no; - } - else - { - return -1; - } -} - -/* Private functions - *---------------------------------------------------------------------------*/ - -static void -dma_threads_clear (DmaThreads *self) -{ - GtkTreeModel* model; - - model = gtk_tree_view_get_model (self->list); - gtk_list_store_clear (GTK_LIST_STORE (model)); -} - -/* Callback functions - *---------------------------------------------------------------------------*/ - -static void -on_threads_set_activate (GtkAction *action, gpointer user_data) -{ - DmaThreads *self = (DmaThreads *)user_data; - gint selected_thread; - - selected_thread = get_current_index (self); - - /* No thread selected */ - if (selected_thread == -1) - return; - - /* current thread is already active */ - if (selected_thread == self->current_thread) - return; - - /* issue a command to switch active frame to new location */ - dma_queue_set_thread (self->debugger, selected_thread); -} - -static void -on_threads_source_activate (GtkAction *action, gpointer user_data) -{ - GtkTreeModel *model; - GtkTreeSelection *selection; - GtkTreeIter iter; - GtkTreeView *view; - gchar *uri; - guint line; - gchar *adr; - gulong address; - DmaThreads* self = (DmaThreads*) user_data; - - view = self->list; - selection = gtk_tree_view_get_selection (view); - if (!gtk_tree_selection_get_selected (selection, &model, &iter)) - return; - - /* get the frame info */ - gtk_tree_model_get (model, &iter, - THREAD_URI_COLUMN, &uri, - THREAD_LINE_COLUMN, &line, - THREAD_ADDR_COLUMN, &adr, - -1); - - address = adr != NULL ? strtoul (adr, NULL, 0) : 0; - g_signal_emit_by_name (self->plugin, "location-changed", address, uri, line); - g_free (uri); - g_free (adr); -} - -static void -on_threads_row_activated (GtkTreeView *treeview, - GtkTreePath *arg1, - GtkTreeViewColumn *arg2, - DmaThreads* self) -{ - on_threads_set_activate (NULL, self); -} - -static gboolean -on_threads_button_press (GtkWidget *widget, GdkEventButton *bevent, gpointer user_data) -{ - DmaThreads *self = (DmaThreads*) user_data; - - if ((bevent->type == GDK_BUTTON_PRESS) && (bevent->button == 3)) - { - /* Right mouse click */ - g_return_val_if_fail (self->menu != NULL, FALSE); - gtk_menu_popup (GTK_MENU (self->menu), NULL, NULL, NULL, NULL, - bevent->button, bevent->time); - } - else if ((bevent->type == GDK_2BUTTON_PRESS) && (bevent->button == 1)) - { - /* Double left mouse click */ - on_threads_source_activate (NULL, user_data); - } - - return FALSE; -} - -static void -on_info_thread (const IAnjutaDebuggerFrame* frame, gpointer user_data) -{ - GtkTreeRowReference* reference = (GtkTreeRowReference*)user_data; - gchar* adr; - gchar* uri; - gchar* file; - - if (frame == NULL) return; - - adr = 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; - g_object_unref (gio_file); - } - else - { - uri = NULL; - file = frame->file; - } - } - else - { - uri = NULL; - file = frame->library; - } - - if (gtk_tree_row_reference_valid (reference)) - { - GtkTreeIter iter; - GtkTreeModel *model; - GtkTreePath *path; - gboolean ok; - - model = gtk_tree_row_reference_get_model(reference); - path = gtk_tree_row_reference_get_path (reference); - ok = gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_path_free (path); - - if (ok) - { - gtk_list_store_set(GTK_LIST_STORE (model), &iter, - THREAD_FILE_COLUMN, file, - THREAD_LINE_COLUMN, frame->line, - THREAD_FUNC_COLUMN, frame->function, - THREAD_ADDR_COLUMN, adr, - THREAD_URI_COLUMN, uri, - -1); - } - gtk_tree_row_reference_free(reference); - } - - g_free (uri); - g_free (adr); -} - -static void -on_list_thread (const GList *threads, gpointer user_data) -{ - DmaThreads *self = (DmaThreads *)user_data; - const GList *node; - GtkListStore *model; - - dma_threads_clear (self); - - model = GTK_LIST_STORE (gtk_tree_view_get_model (self->list)); - - for (node = threads; node != NULL; node = node->next) - { - GdkPixbuf *pic; - GtkTreeIter iter; - IAnjutaDebuggerFrame *frame; - gchar *adr; - gchar *uri; - gchar *file; - - frame = (IAnjutaDebuggerFrame *)node->data; - - gtk_list_store_append (model, &iter); - - /* if we are on the current frame set iterator and pixmap correctly */ - if (frame->thread == self->current_thread) - pic = gdk_pixbuf_new_from_file (ANJUTA_PIXMAP_POINTER, NULL); - else - pic = NULL; - - if ((dma_debugger_queue_is_supported (self->debugger, HAS_MEMORY) && (frame->address == 0)) - || (frame->function == NULL)) - { - /* Missing frame address, request more information */ - GtkTreeRowReference* reference; - GtkTreePath *path; - - path = gtk_tree_model_get_path(GTK_TREE_MODEL (model), &iter); - reference = gtk_tree_row_reference_new (GTK_TREE_MODEL (model), path); - gtk_tree_path_free (path); - - dma_queue_info_thread ( - self->debugger, frame->thread, - (IAnjutaDebuggerCallback)on_info_thread, - reference); - - gtk_list_store_set(model, &iter, - THREAD_ACTIVE_COLUMN, pic, - THREAD_ID_COLUMN, frame->thread, - -1); - } - else - { - adr = 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; - g_object_unref (gio_file); - } - else - { - uri = NULL; - file = frame->file; - } - } - else - { - uri = NULL; - file = frame->library; - } - - gtk_list_store_set(model, &iter, - THREAD_ACTIVE_COLUMN, pic, - THREAD_ID_COLUMN, frame->thread, - THREAD_FILE_COLUMN, file, - THREAD_LINE_COLUMN, frame->line, - THREAD_FUNC_COLUMN, frame->function, - THREAD_ADDR_COLUMN, adr, - THREAD_URI_COLUMN, uri, - -1); - - g_free (uri); - g_free (adr); - } - - if (pic) - g_object_unref (pic); - } -} - -static void -dma_threads_update (DmaThreads *self) -{ - dma_queue_list_thread ( - self->debugger, - (IAnjutaDebuggerCallback)on_list_thread, - self); -} - -/* Actions table - *---------------------------------------------------------------------------*/ - -static GtkActionEntry actions_threads[] = { - { - "ActionDmaSetCurrentThread", /* Action name */ - NULL, /* Stock icon, if any */ - N_("Set current thread"), /* Display label */ - NULL, /* short-cut */ - NULL, /* Tooltip */ - G_CALLBACK (on_threads_set_activate) /* action callback */ - }, - { - "ActionDmaJumpToThread", - NULL, - N_("View Source"), - NULL, - NULL, - G_CALLBACK (on_threads_source_activate) - } -}; - -static void -dma_threads_create_gui(DmaThreads *self) -{ - GtkTreeModel* model; - GtkTreeSelection *selection; - GtkTreeViewColumn *column; - GtkCellRenderer *renderer; - AnjutaUI *ui; - - g_return_if_fail (self->scrolledwindow == NULL); - - /* Create tree view */ - model = GTK_TREE_MODEL(gtk_list_store_new (THREAD_N_COLUMNS, - GDK_TYPE_PIXBUF, - G_TYPE_UINT, - G_TYPE_STRING, - G_TYPE_UINT, - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING)); - self->list = GTK_TREE_VIEW (gtk_tree_view_new_with_model (model)); - g_object_unref (G_OBJECT (model)); - - selection = gtk_tree_view_get_selection (self->list); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); - - /* Columns */ - 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, _("Active")); - renderer = gtk_cell_renderer_pixbuf_new (); - gtk_tree_view_column_pack_start (column, renderer, TRUE); - gtk_tree_view_column_add_attribute (column, renderer, "pixbuf", - THREAD_ACTIVE_COLUMN); - gtk_tree_view_append_column (self->list, column); - gtk_tree_view_set_expander_column (self->list, 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, _("ID")); - renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_column_pack_start (column, renderer, TRUE); - gtk_tree_view_column_add_attribute (column, renderer, "text", - THREAD_ID_COLUMN); - gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); - gtk_tree_view_append_column (self->list, column); - gtk_tree_view_set_expander_column (self->list, column); - - column = gtk_tree_view_column_new (); - renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_column_pack_start (column, renderer, TRUE); - gtk_tree_view_column_add_attribute (column, renderer, "text", - THREAD_FILE_COLUMN); - gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); - gtk_tree_view_column_set_title (column, _("File")); - gtk_tree_view_append_column (self->list, column); - - column = gtk_tree_view_column_new (); - renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_column_pack_start (column, renderer, TRUE); - gtk_tree_view_column_add_attribute (column, renderer, "text", - THREAD_LINE_COLUMN); - 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 (self->list, column); - - column = gtk_tree_view_column_new (); - renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_column_pack_start (column, renderer, TRUE); - gtk_tree_view_column_add_attribute (column, renderer, "text", - THREAD_FUNC_COLUMN); - 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 (self->list, column); - - if (dma_debugger_queue_is_supported (self->debugger, HAS_MEMORY)) - { - /* Display address only if debugger has such concept */ - column = gtk_tree_view_column_new (); - renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_column_pack_start (column, renderer, TRUE); - gtk_tree_view_column_add_attribute (column, renderer, "text", - THREAD_ADDR_COLUMN); - gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); - gtk_tree_view_column_set_title (column, _("Address")); - gtk_tree_view_append_column (self->list, column); - } - - /* Create popup menu */ - ui = anjuta_shell_get_ui (ANJUTA_PLUGIN(self->plugin)->shell, NULL); - self->menu = GTK_MENU (gtk_ui_manager_get_widget (GTK_UI_MANAGER (ui), "/PopupThread")); - - /* Connect signal */ - g_signal_connect (self->list, "button-press-event", G_CALLBACK (on_threads_button_press), self); - g_signal_connect (self->list, "row-activated", G_CALLBACK (on_threads_row_activated), self); - - /* Add stack window */ - self->scrolledwindow = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (self->scrolledwindow), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (self->scrolledwindow), - GTK_SHADOW_IN); - gtk_container_add (GTK_CONTAINER (self->scrolledwindow), - GTK_WIDGET (self->list)); - gtk_widget_show_all (self->scrolledwindow); - - anjuta_shell_add_widget (ANJUTA_PLUGIN(self->plugin)->shell, - self->scrolledwindow, - "AnjutaDebuggerThread", _("Thread"), - "gdb-stack-icon", ANJUTA_SHELL_PLACEMENT_BOTTOM, - NULL); - -} - -static void -dma_destroy_threads_gui (DmaThreads *self) -{ - if (self->scrolledwindow != NULL) - { - gtk_widget_destroy (self->scrolledwindow); - self->scrolledwindow = NULL; - } -} - -static void -on_program_moved (DmaThreads *self, guint pid, gint thread) -{ - self->current_thread = thread; - dma_threads_update (self); -} - -static gboolean -on_mark_selected_thread (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data) -{ - DmaThreads* self = (DmaThreads *)user_data; - GdkPixbuf *pic; - gint thread; - - gtk_tree_model_get (model, iter, THREAD_ACTIVE_COLUMN, &pic, THREAD_ID_COLUMN, &thread, -1); - - if (pic != NULL) - { - /* Remove previously selected thread marker */ - g_object_unref (pic); - pic = NULL; - } - - if (self->current_thread == thread) - { - /* Create marker if needed */ - pic = gdk_pixbuf_new_from_file (ANJUTA_PIXMAP_POINTER, NULL); - } - - gtk_list_store_set (GTK_LIST_STORE (model), iter, - THREAD_ACTIVE_COLUMN, pic, -1); - - if (pic != NULL) - { - g_object_unref (pic); - } - - return FALSE; -} - -static void -on_frame_changed (DmaThreads *self, guint frame, gint thread) -{ - if (thread != self->current_thread) - { - GtkTreeModel *model; - - self->current_thread = thread; - model = gtk_tree_view_get_model (self->list); - - gtk_tree_model_foreach (model, on_mark_selected_thread, self); - } -} - -static void -on_program_exited (DmaThreads *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_threads_clear (self); - dma_destroy_threads_gui (self); -} - -static void -on_program_started (DmaThreads *self) -{ - dma_threads_create_gui (self); - - 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); -} - -/* Constructor & Destructor - *---------------------------------------------------------------------------*/ - -DmaThreads* -dma_threads_new (DebugManagerPlugin *plugin) -{ - DmaThreads* self; - AnjutaUI *ui; - - self = g_new0 (DmaThreads, 1); - g_return_val_if_fail (self != NULL, NULL); - - self->plugin = plugin; - self->debugger = dma_debug_manager_get_queue (plugin); - - /* Register actions */ - ui = anjuta_shell_get_ui (ANJUTA_PLUGIN(self->plugin)->shell, NULL); - self->action_group = - anjuta_ui_add_action_group_entries (ui, "ActionGroupThread", - _("Thread operations"), - actions_threads, - G_N_ELEMENTS (actions_threads), - GETTEXT_PACKAGE, TRUE, self); - - g_signal_connect_swapped (self->plugin, "program-started", G_CALLBACK (on_program_started), self); - - return self; -} - -void -dma_threads_free (DmaThreads *self) -{ - AnjutaUI *ui; - - g_return_if_fail (self != NULL); - - /* Disconnect from debugger */ - g_signal_handlers_disconnect_matched (self->plugin, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self); - - /* Remove menu actions */ - ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (self->plugin)->shell, NULL); - anjuta_ui_remove_action_group (ui, self->action_group); - - /* Destroy menu */ - dma_destroy_threads_gui (self); - - g_free (self); -} diff --git a/plugins/debug-manager/threads.h b/plugins/debug-manager/threads.h deleted file mode 100644 index 025af9570..000000000 --- a/plugins/debug-manager/threads.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */ -/* - threads.h - Copyright (C) 2007 Sébastien Granjoux - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#ifndef _THREADS_H_ -#define _THREADS_H_ - -#include "plugin.h" - -#include -#include - -#include - -#include - -typedef struct _DmaThreads DmaThreads; - -DmaThreads *dma_threads_new (DebugManagerPlugin *plugin); -void dma_threads_free (DmaThreads *self); - -#endif diff --git a/po/POTFILES.in b/po/POTFILES.in index f6eac012f..c0b5e3f2c 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 -- 2.11.4.GIT