* plugins/debug-manager/disassemble.c,
[anjuta-git-plugin.git] / plugins / debug-manager / plugin.c
blobbb3401e1172dc1b10ed6b1f9a4557c917b30cc9c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 plugin.c
4 Copyright (C) 2004 Naba Kumar
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <config.h>
23 /*#define DEBUG*/
25 #include "plugin.h"
27 #include "breakpoints.h"
28 #include "stack_trace.h"
29 #include "threads.h"
30 #include "info.h"
31 #include "memory.h"
32 #include "disassemble.h"
33 #include "signals.h"
34 #include "sharedlib.h"
35 #include "registers.h"
36 #include "utilities.h"
37 #include "start.h"
38 #include "queue.h"
39 #include "variable.h"
41 #include <libanjuta/anjuta-shell.h>
42 #include <libanjuta/anjuta-debug.h>
43 #include <libanjuta/anjuta-status.h>
44 #include <libanjuta/interfaces/ianjuta-file.h>
45 #include <libanjuta/interfaces/ianjuta-editor.h>
46 #include <libanjuta/interfaces/ianjuta-indicable.h>
47 #include <libanjuta/interfaces/ianjuta-markable.h>
48 #include <libanjuta/interfaces/ianjuta-debug-manager.h>
49 #include <libanjuta/interfaces/ianjuta-project-manager.h>
50 #include <libanjuta/interfaces/ianjuta-document-manager.h>
51 #include <libanjuta/interfaces/ianjuta-message-manager.h>
53 #include <libgnomevfs/gnome-vfs.h>
55 /* Contants defintion
56 *---------------------------------------------------------------------------*/
58 #define ICON_FILE "anjuta-debug-manager-plugin-48.png"
59 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-debug-manager.ui"
60 #define GLADE_FILE PACKAGE_DATA_DIR"/glade/anjuta-debug-manager.glade"
62 /* Plugin type
63 *---------------------------------------------------------------------------*/
65 struct _DebugManagerPlugin
67 AnjutaPlugin parent;
69 /* Debugger queue */
70 DmaDebuggerQueue *queue;
72 /* Menu item */
73 gint uiid;
74 GtkActionGroup *start_group;
75 GtkActionGroup *loaded_group;
76 GtkActionGroup *stopped_group;
77 GtkActionGroup *running_group;
79 /* Project */
80 gchar *project_root_uri;
81 guint project_watch_id;
83 /* Editor */
84 IAnjutaEditor *current_editor;
85 guint editor_watch_id;
86 IAnjutaEditor *pc_editor;
87 guint pc_line;
88 gulong pc_address;
89 gboolean busy;
91 /* Debugger components */
92 BreakpointsDBase *breakpoints;
93 DmaStart *start;
94 StackTrace *stack;
95 CpuRegisters *registers;
96 Sharedlibs *sharedlibs;
97 Signals *signals;
98 DmaMemory *memory;
99 DmaDisassemble *disassemble;
100 DmaThreads *thread;
101 DmaVariableDBase *variable;
104 /* Logging view */
105 IAnjutaMessageView* view;
108 struct _DebugManagerPluginClass
110 AnjutaPluginClass parent_class;
113 /* Private functions
114 *---------------------------------------------------------------------------*/
116 static void
117 register_stock_icons (AnjutaPlugin *plugin)
119 static gboolean registered = FALSE;
121 if (registered)
122 return;
123 registered = TRUE;
125 /* Register stock icons */
126 BEGIN_REGISTER_ICON (plugin)
127 REGISTER_ICON (ICON_FILE, "debugger-icon");
128 REGISTER_ICON ("stack.png", "gdb-stack-icon");
129 REGISTER_ICON ("locals.png", "gdb-locals-icon");
130 REGISTER_ICON_FULL ("anjuta-watch", "gdb-watch-icon");
131 REGISTER_ICON_FULL ("anjuta-breakpoint-toggle", ANJUTA_STOCK_BREAKPOINT_TOGGLE);
132 REGISTER_ICON_FULL ("anjuta-breakpoint-clear", ANJUTA_STOCK_BREAKPOINT_CLEAR);
133 /* We have no -24 version for the next two */
134 REGISTER_ICON ("anjuta-breakpoint-disabled-16.png", ANJUTA_STOCK_BREAKPOINT_DISABLED);
135 REGISTER_ICON ("anjuta-breakpoint-enabled-16.png", ANJUTA_STOCK_BREAKPOINT_ENABLED);
136 REGISTER_ICON_FULL ("anjuta-attach", "debugger-attach");
137 REGISTER_ICON_FULL ("anjuta-step-into", "debugger-step-into");
138 REGISTER_ICON_FULL ("anjuta-step-out", "debugger-step-out");
139 REGISTER_ICON_FULL ("anjuta-step-over", "debugger-step-over");
140 REGISTER_ICON_FULL ("anjuta-run-to-cursor", "debugger-run-to-cursor");
141 END_REGISTER_ICON
144 /* Program counter functions
145 *---------------------------------------------------------------------------*/
147 static void
148 show_program_counter_in_editor(DebugManagerPlugin *self)
150 IAnjutaEditor *editor = self->current_editor;
152 if ((editor != NULL) && (self->pc_editor == editor))
154 if (IANJUTA_IS_MARKABLE (editor))
156 ianjuta_markable_mark(IANJUTA_MARKABLE (editor), self->pc_line, IANJUTA_MARKABLE_PROGRAM_COUNTER, NULL);
158 if (IANJUTA_IS_INDICABLE(editor))
160 gint begin = ianjuta_editor_get_line_begin_position(editor, self->pc_line, NULL);
161 gint end = ianjuta_editor_get_line_end_position(editor, self->pc_line, NULL);
163 ianjuta_indicable_set(IANJUTA_INDICABLE(editor), begin, end, IANJUTA_INDICABLE_IMPORTANT,
164 NULL);
169 static void
170 hide_program_counter_in_editor(DebugManagerPlugin *self)
172 IAnjutaEditor *editor = self->current_editor;
174 if ((editor != NULL) && (self->pc_editor == editor))
176 if (IANJUTA_IS_MARKABLE (editor))
178 ianjuta_markable_delete_all_markers (IANJUTA_MARKABLE (editor), IANJUTA_MARKABLE_PROGRAM_COUNTER, NULL);
180 if (IANJUTA_IS_INDICABLE(editor))
182 ianjuta_indicable_clear(IANJUTA_INDICABLE(editor), NULL);
187 static void
188 set_program_counter(DebugManagerPlugin *self, const gchar* file, guint line, gulong address)
190 IAnjutaDocumentManager *docman = NULL;
191 gchar *file_uri;
193 /* Remove previous marker */
194 hide_program_counter_in_editor (self);
195 if (self->pc_editor != NULL)
197 g_object_remove_weak_pointer (G_OBJECT (self->pc_editor), (gpointer *)(gpointer)&self->pc_editor);
198 self->pc_editor = NULL;
200 self->pc_address = address;
202 if (file != NULL)
204 docman = anjuta_shell_get_interface (ANJUTA_PLUGIN (self)->shell, IAnjutaDocumentManager, NULL);
205 file_uri = gnome_vfs_get_uri_from_local_path(file);
206 if (docman)
208 IAnjutaEditor* editor;
210 editor = ianjuta_document_manager_goto_file_line(docman, file_uri, line, NULL);
212 if (editor != NULL)
214 self->pc_editor = editor;
215 g_object_add_weak_pointer (G_OBJECT (editor), (gpointer)(gpointer)&self->pc_editor);
216 self->pc_line = line;
217 show_program_counter_in_editor (self);
220 g_free (file_uri);
224 static void
225 value_added_project_root_uri (AnjutaPlugin *plugin, const gchar *name,
226 const GValue *value, gpointer user_data)
228 DebugManagerPlugin *dm_plugin;
229 const gchar *root_uri;
231 dm_plugin = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
233 if (dm_plugin->project_root_uri)
234 g_free (dm_plugin->project_root_uri);
235 dm_plugin->project_root_uri = NULL;
237 root_uri = g_value_get_string (value);
238 if (root_uri)
240 dm_plugin->project_root_uri = g_strdup (root_uri);
244 static void
245 value_removed_project_root_uri (AnjutaPlugin *plugin, const gchar *name,
246 gpointer user_data)
248 DebugManagerPlugin *dm_plugin;
250 dm_plugin = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
252 if (dm_plugin->project_root_uri)
253 g_free (dm_plugin->project_root_uri);
254 dm_plugin->project_root_uri = NULL;
257 static void
258 value_added_current_editor (AnjutaPlugin *plugin, const char *name,
259 const GValue *value, gpointer data)
261 GObject *editor;
262 DebugManagerPlugin *self;
264 self = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
266 editor = g_value_get_object (value);
267 DEBUG_PRINT("add value current editor %p", editor);
269 if (!IANJUTA_IS_EDITOR(editor))
271 self->current_editor = NULL;
272 return;
275 self->current_editor = IANJUTA_EDITOR (editor);
276 g_object_add_weak_pointer (G_OBJECT (self->current_editor), (gpointer *)(gpointer)&self->current_editor);
278 /* Restore program counter marker */
279 show_program_counter_in_editor (self);
282 static void
283 value_removed_current_editor (AnjutaPlugin *plugin,
284 const char *name, gpointer data)
286 DebugManagerPlugin *self = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
288 DEBUG_PRINT("remove value current editor %p", self->current_editor);
289 if (self->current_editor)
291 hide_program_counter_in_editor (self);
293 g_object_remove_weak_pointer (G_OBJECT (self->current_editor), (gpointer *)(gpointer)&self->current_editor);
295 self->current_editor = NULL;
298 static void
299 enable_log_view (DebugManagerPlugin *this, gboolean enable)
301 if (enable)
303 if (this->view == NULL)
305 IAnjutaMessageManager* man;
307 man = anjuta_shell_get_interface (ANJUTA_PLUGIN (this)->shell, IAnjutaMessageManager, NULL);
308 this->view = ianjuta_message_manager_add_view (man, _("Debugger Log"), ICON_FILE, NULL);
309 if (this->view != NULL)
311 /*g_signal_connect (G_OBJECT (this->view), "buffer_flushed", G_CALLBACK (on_message_buffer_flushed), this);*/
312 g_object_add_weak_pointer (G_OBJECT (this->view), (gpointer *)(gpointer)&this->view);
313 dma_queue_enable_log (this->queue, this->view);
316 else
318 ianjuta_message_view_clear (this->view, NULL);
321 else
323 if (this->view != NULL)
325 IAnjutaMessageManager* man;
327 man = anjuta_shell_get_interface (ANJUTA_PLUGIN (this)->shell, IAnjutaMessageManager, NULL);
328 ianjuta_message_manager_remove_view (man, this->view, NULL);
329 this->view = NULL;
331 if (this->queue != NULL)
333 dma_queue_disable_log (this->queue);
338 static void
339 on_session_save (AnjutaShell *shell, AnjutaSessionPhase phase,
340 AnjutaSession *session, DebugManagerPlugin *plugin)
342 if (phase == ANJUTA_SESSION_PHASE_FIRST)
343 enable_log_view (plugin, FALSE);
344 if (phase != ANJUTA_SESSION_PHASE_NORMAL)
345 return;
347 /* Close debugger when session changed */
348 if (plugin->queue)
350 dma_queue_abort (plugin->queue);
355 /* State functions
356 *---------------------------------------------------------------------------*/
358 /* Called when the debugger is started but no program is loaded */
360 static void
361 dma_plugin_debugger_started (DebugManagerPlugin *this)
363 AnjutaUI *ui;
364 GtkAction *action;
365 AnjutaStatus* status;
367 DEBUG_PRINT ("DMA: dma_plugin_debugger_started");
369 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
371 /* Update ui */
372 action = gtk_action_group_get_action (this->start_group, "ActionDebuggerStop");
373 gtk_action_set_sensitive (action, TRUE);
374 gtk_action_group_set_visible (this->loaded_group, TRUE);
375 gtk_action_group_set_sensitive (this->loaded_group, FALSE);
376 gtk_action_group_set_visible (this->stopped_group, TRUE);
377 gtk_action_group_set_sensitive (this->stopped_group, FALSE);
378 gtk_action_group_set_visible (this->running_group, TRUE);
379 gtk_action_group_set_sensitive (this->running_group, FALSE);
381 status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
382 anjuta_status_set_default (status, _("Debugger"), _("Started"));
385 /* Called when a program is loaded */
387 static void
388 dma_plugin_program_loaded (DebugManagerPlugin *this)
390 AnjutaUI *ui;
391 AnjutaStatus* status;
393 DEBUG_PRINT ("DMA: dma_plugin_program_loaded");
395 if (this->sharedlibs == NULL)
397 this->sharedlibs = sharedlibs_new (this);
399 if (this->signals == NULL)
401 this->signals = signals_new (this);
404 /* Update ui */
405 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
406 gtk_action_group_set_sensitive (this->loaded_group, TRUE);
407 gtk_action_group_set_sensitive (this->stopped_group, FALSE);
408 gtk_action_group_set_sensitive (this->running_group, FALSE);
410 status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
411 anjuta_status_set_default (status, _("Debugger"), _("Loaded"));
414 /* Called when the program is running */
416 static void
417 dma_plugin_program_running (DebugManagerPlugin *this)
419 AnjutaUI *ui;
420 AnjutaStatus* status;
422 DEBUG_PRINT ("DMA: dma_plugin_program_running");
424 /* Update ui */
425 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
426 gtk_action_group_set_sensitive (this->loaded_group, TRUE);
427 gtk_action_group_set_sensitive (this->stopped_group, FALSE);
428 gtk_action_group_set_sensitive (this->running_group, TRUE);
430 status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
431 anjuta_status_set_default (status, _("Debugger"), _("Running..."));
433 set_program_counter(this, NULL, 0, 0);
436 /* Called when the program is stopped */
438 static void
439 dma_plugin_program_stopped (DebugManagerPlugin *this)
441 AnjutaUI *ui;
442 AnjutaStatus* status;
444 DEBUG_PRINT ("DMA: dma_plugin_program_broken");
446 /* Update ui */
447 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
448 gtk_action_group_set_sensitive (this->loaded_group, TRUE);
449 gtk_action_group_set_sensitive (this->stopped_group, TRUE);
450 gtk_action_group_set_sensitive (this->running_group, FALSE);
452 status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
453 anjuta_status_set_default (status, _("Debugger"), _("Stopped"));
456 /* Called when the program postion change */
458 static void
459 dma_plugin_program_moved (DebugManagerPlugin *this, guint pid, guint tid, gulong address, const gchar* file, guint line)
461 DEBUG_PRINT ("DMA: dma_plugin_program_moved %s %d %lx", file, line, address);
463 set_program_counter (this, file, line, address);
466 /* Called when a program is unloaded */
467 static void
468 dma_plugin_program_unload (DebugManagerPlugin *this)
470 AnjutaUI *ui;
471 AnjutaStatus* status;
473 DEBUG_PRINT ("DMA: dma_plugin_program_unload");
475 if (this->sharedlibs != NULL)
477 sharedlibs_free (this->sharedlibs);
478 this->sharedlibs = NULL;
480 if (this->signals == NULL)
482 signals_free (this->signals);
483 this->signals = NULL;
486 /* Update ui */
487 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
488 gtk_action_group_set_visible (this->start_group, TRUE);
489 gtk_action_group_set_sensitive (this->start_group, TRUE);
490 gtk_action_group_set_visible (this->loaded_group, TRUE);
491 gtk_action_group_set_sensitive (this->loaded_group, FALSE);
492 gtk_action_group_set_visible (this->stopped_group, TRUE);
493 gtk_action_group_set_sensitive (this->stopped_group, FALSE);
494 gtk_action_group_set_visible (this->running_group, TRUE);
495 gtk_action_group_set_sensitive (this->running_group, FALSE);
497 status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
498 anjuta_status_set_default (status, _("Debugger"), _("Unloaded"));
501 /* Called when the debugger is stopped */
503 static void
504 dma_plugin_debugger_stopped (DebugManagerPlugin *self, GError *err)
506 AnjutaUI *ui;
507 GtkAction *action;
508 AnjutaStatus* state;
510 DEBUG_PRINT ("DMA: dma_plugin_debugger_stopped");
512 dma_plugin_program_unload (self);
514 /* Update ui */
515 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (self)->shell, NULL);
516 gtk_action_group_set_visible (self->start_group, TRUE);
517 gtk_action_group_set_sensitive (self->start_group, TRUE);
518 action = gtk_action_group_get_action (self->start_group, "ActionDebuggerStop");
519 gtk_action_set_sensitive (action, FALSE);
520 gtk_action_group_set_visible (self->loaded_group, TRUE);
521 gtk_action_group_set_sensitive (self->loaded_group, FALSE);
522 gtk_action_group_set_visible (self->stopped_group, TRUE);
523 gtk_action_group_set_sensitive (self->stopped_group, FALSE);
524 gtk_action_group_set_visible (self->running_group, TRUE);
525 gtk_action_group_set_sensitive (self->running_group, FALSE);
527 /* clear indicator */
528 set_program_counter (self, NULL, 0, 0);
530 enable_log_view (self, FALSE);
532 state = anjuta_shell_get_status(ANJUTA_PLUGIN (self)->shell, NULL);
533 anjuta_status_set_default (state, _("Debugger"), NULL);
535 /* Display a warning if debugger stop unexpectedly */
536 if (err != NULL)
538 GtkWindow *parent = GTK_WINDOW (ANJUTA_PLUGIN(self)->shell);
539 anjuta_util_dialog_error (parent, _("Debugger terminated with error %d: %s\n"), err->code, err->message);
544 static void
545 dma_plugin_signal_received (DebugManagerPlugin *self, const gchar *name, const gchar *description)
547 GtkWindow *parent = GTK_WINDOW (ANJUTA_PLUGIN (self)->shell);
549 /* Skip SIGINT signal */
550 if (strcmp(name, "SIGINT") != 0)
552 anjuta_util_dialog_warning (parent, _("Program has received signal: %s\n"), description);
556 /* Called when the user want to go to another location */
558 static void
559 dma_plugin_location_changed (DebugManagerPlugin *self, gulong address, const gchar* uri, guint line)
561 /* Go to location in editor */
562 if (uri != NULL)
564 IAnjutaDocumentManager *docman;
566 docman = anjuta_shell_get_interface (ANJUTA_PLUGIN(self)->shell, IAnjutaDocumentManager, NULL);
567 if (docman)
569 ianjuta_document_manager_goto_file_line (docman, uri, line, NULL);
574 /* Start/Stop menu functions
575 *---------------------------------------------------------------------------*/
577 static void
578 on_start_debug_activate (GtkAction* action, DebugManagerPlugin* this)
580 enable_log_view (this, TRUE);
581 if (dma_run_target (this->start))
583 GtkAction *action;
584 action = gtk_action_group_get_action (this->start_group, "ActionDebuggerRestartTarget");
585 gtk_action_set_sensitive (action, TRUE);
590 static void
591 on_restart_debug_activate (GtkAction* action, DebugManagerPlugin* this)
593 enable_log_view (this, TRUE);
594 dma_rerun_target (this->start);
597 static void
598 on_attach_to_project_action_activate (GtkAction* action, DebugManagerPlugin* this)
600 enable_log_view (this, TRUE);
601 dma_attach_to_process (this->start);
604 static void
605 on_debugger_stop_activate (GtkAction* action, DebugManagerPlugin* plugin)
607 if (plugin->start)
609 dma_quit_debugger (plugin->start);
613 static void
614 on_add_source_activate (GtkAction* action, DebugManagerPlugin* this)
616 dma_add_source_path (this->start);
619 /* Execute call back
620 *---------------------------------------------------------------------------*/
622 static void
623 on_run_continue_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
625 if (plugin->queue)
626 dma_queue_run (plugin->queue);
629 static void
630 on_step_in_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
632 if (plugin->queue)
634 if ((plugin->disassemble != NULL) && (dma_disassemble_is_focus (plugin->disassemble)))
636 dma_queue_stepi_in (plugin->queue);
638 else
640 dma_queue_step_in (plugin->queue);
645 static void
646 on_step_over_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
648 if (plugin->queue)
650 if ((plugin->disassemble != NULL) && (dma_disassemble_is_focus (plugin->disassemble)))
652 dma_queue_stepi_over (plugin->queue);
654 else
656 dma_queue_step_over (plugin->queue);
661 static void
662 on_step_out_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
664 if (plugin->queue)
665 dma_queue_step_out (plugin->queue);
668 static void
669 on_run_to_cursor_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
671 if (plugin->queue)
673 if ((plugin->disassemble != NULL) && (dma_disassemble_is_focus (plugin->disassemble)))
675 gulong address;
677 address = dma_disassemble_get_current_address (plugin->disassemble);
678 dma_queue_run_to_address (plugin->queue, address);
680 else
682 IAnjutaEditor *editor;
683 gchar *uri;
684 gchar *file;
685 gint line;
687 editor = dma_get_current_editor (ANJUTA_PLUGIN (plugin));
688 if (editor == NULL)
689 return;
690 uri = ianjuta_file_get_uri (IANJUTA_FILE (editor), NULL);
691 if (uri == NULL)
692 return;
694 file = gnome_vfs_get_local_path_from_uri (uri);
696 line = ianjuta_editor_get_lineno (editor, NULL);
697 dma_queue_run_to (plugin->queue, file, line);
698 g_free (uri);
699 g_free (file);
704 static void
705 on_debugger_interrupt_activate (GtkAction* action, DebugManagerPlugin* plugin)
707 if (plugin->queue)
708 dma_queue_interrupt (plugin->queue);
711 /* Custom command
712 *---------------------------------------------------------------------------*/
714 static void
715 on_debugger_command_entry_activate (GtkEntry *entry, DebugManagerPlugin *plugin)
717 const gchar *command;
719 command = gtk_entry_get_text (GTK_ENTRY (entry));
720 if (command && strlen (command))
721 dma_queue_send_command (plugin->queue, command);
722 gtk_entry_set_text (entry, "");
725 static void
726 on_debugger_custom_command_activate (GtkAction * action, DebugManagerPlugin *plugin)
728 GladeXML *gxml;
729 GtkWidget *win, *entry;
731 gxml = glade_xml_new (GLADE_FILE, "debugger_command_dialog", NULL);
732 win = glade_xml_get_widget (gxml, "debugger_command_dialog");
733 entry = glade_xml_get_widget (gxml, "debugger_command_entry");
735 gtk_window_set_transient_for (GTK_WINDOW (win),
736 GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell));
737 g_signal_connect_swapped (win, "response",
738 G_CALLBACK (gtk_widget_destroy),
739 win);
740 g_signal_connect (entry, "activate",
741 G_CALLBACK (on_debugger_command_entry_activate),
742 plugin);
743 g_object_unref (gxml);
746 /* Info callbacks
747 *---------------------------------------------------------------------------*/
749 static void
750 on_debugger_dialog_message (const gpointer data, gpointer user_data, GError* error)
752 const GList *cli_result = data;
753 GtkWindow *parent = GTK_WINDOW (user_data);
754 if (g_list_length ((GList*)cli_result) < 1)
755 return;
756 gdb_info_show_list (parent, (GList*)cli_result, 0, 0);
759 static void
760 on_info_targets_activate (GtkAction *action, DebugManagerPlugin *plugin)
762 dma_queue_info_target (plugin->queue, on_debugger_dialog_message, plugin);
765 static void
766 on_info_program_activate (GtkAction *action, DebugManagerPlugin *plugin)
768 dma_queue_info_program (plugin->queue, on_debugger_dialog_message, plugin);
771 static void
772 on_info_udot_activate (GtkAction *action, DebugManagerPlugin *plugin)
774 dma_queue_info_udot (plugin->queue, on_debugger_dialog_message, plugin);
777 static void
778 on_info_variables_activate (GtkAction *action, DebugManagerPlugin *plugin)
780 dma_queue_info_variables (plugin->queue, on_debugger_dialog_message, plugin);
783 static void
784 on_info_frame_activate (GtkAction *action, DebugManagerPlugin *plugin)
786 dma_queue_info_frame (plugin->queue, 0, on_debugger_dialog_message, plugin);
789 static void
790 on_info_args_activate (GtkAction *action, DebugManagerPlugin *plugin)
792 dma_queue_info_args (plugin->queue, on_debugger_dialog_message, plugin);
795 /* Other informations
796 *---------------------------------------------------------------------------*/
798 /*static void
799 on_info_memory_activate (GtkAction * action, DebugManagerPlugin *plugin)
801 GtkWidget *win_memory;
803 win_memory = memory_info_new (plugin->debugger,
804 GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell),
805 NULL);
806 gtk_widget_show(win_memory);
809 static void
810 on_debugger_sharedlibs_activate (GtkAction * action, DebugManagerPlugin *plugin)
812 sharedlibs_show (plugin->sharedlibs);
815 static void
816 on_debugger_signals_activate (GtkAction * action, DebugManagerPlugin *plugin)
818 signals_show (plugin->signals);
821 /* Actions table
822 *---------------------------------------------------------------------------*/
824 static GtkActionEntry actions_start[] =
827 "ActionMenuDebug", /* Action name */
828 NULL, /* Stock icon, if any */
829 N_("_Debug"), /* Display label */
830 NULL, /* short-cut */
831 NULL, /* Tooltip */
832 NULL /* action callback */
835 "ActionMenuStart",
836 "debugger-icon",
837 N_("_Start Debugger"),
838 NULL,
839 NULL,
840 NULL
843 "ActionDebuggerRunTarget",
844 NULL,
845 N_("Run Target..."),
846 "<shift>F12",
847 N_("load and start the target for debugging"),
848 G_CALLBACK (on_start_debug_activate)
851 "ActionDebuggerRestartTarget",
852 NULL,
853 N_("Restart Target"),
854 NULL,
855 N_("restart the same target for debugging"),
856 G_CALLBACK (on_restart_debug_activate)
859 "ActionDebuggerAttachProcess",
860 "debugger-attach",
861 N_("_Attach to Process..."),
862 NULL,
863 N_("Attach to a running program"),
864 G_CALLBACK (on_attach_to_project_action_activate)
867 "ActionDebuggerStop",
868 GTK_STOCK_STOP,
869 N_("Stop Debugger"),
870 NULL,
871 N_("Say goodbye to the debugger"),
872 G_CALLBACK (on_debugger_stop_activate)
875 "ActionDebuggerAddSource",
876 NULL,
877 N_("Add source paths..."),
878 NULL,
879 N_("Add additional source paths"),
880 G_CALLBACK (on_add_source_activate)
884 static GtkActionEntry actions_loaded[] =
887 "ActionGdbCommand", /* Action name */
888 NULL, /* Stock icon, if any */
889 N_("Debugger Command..."), /* Display label */
890 NULL, /* short-cut */
891 N_("Custom debugger command"), /* Tooltip */
892 G_CALLBACK (on_debugger_custom_command_activate) /* action callback */
895 "ActionMenuGdbInformation",
896 NULL,
897 N_("_Info"),
898 NULL,
899 NULL,
900 NULL
903 "ActionGdbInfoTargetFiles",
904 NULL,
905 N_("Info _Target Files"),
906 NULL,
907 N_("Display information on the files the debugger is active with"),
908 G_CALLBACK (on_info_targets_activate)
911 "ActionGdbInfoProgram",
912 NULL,
913 N_("Info _Program"),
914 NULL,
915 N_("Display information on the execution status of the program"),
916 G_CALLBACK (on_info_program_activate)
919 "ActionGdbInfoKernelUserStruct",
920 NULL,
921 N_("Info _Kernel User Struct"),
922 NULL,
923 N_("Display the contents of kernel 'struct user' for current child"),
924 G_CALLBACK (on_info_udot_activate)
926 /* {
927 "ActionGdbExamineMemory",
928 NULL,
929 N_("Examine _Memory"),
930 NULL,
931 N_("Display accessible memory"),
932 G_CALLBACK (on_info_memory_activate)
933 },*/
935 "ActionGdbViewSharedlibs",
936 NULL,
937 N_("Shared Libraries"),
938 NULL,
939 N_("Show shared libraries mappings"),
940 G_CALLBACK (on_debugger_sharedlibs_activate)
943 "ActionGdbViewSignals",
944 NULL,
945 N_("Kernel Signals"),
946 NULL,
947 N_("Show kernel signals"),
948 G_CALLBACK (on_debugger_signals_activate)
952 static GtkActionEntry actions_stopped[] =
955 "ActionDebuggerRunContinue", /* Action name */
956 GTK_STOCK_EXECUTE, /* Stock icon, if any */
957 N_("Run/_Continue"), /* Display label */
958 "F4", /* short-cut */
959 N_("Continue the execution of the program"), /* Tooltip */
960 G_CALLBACK (on_run_continue_action_activate) /* action callback */
963 "ActionDebuggerStepIn",
964 "debugger-step-into",
965 N_("Step _In"),
966 "F5",
967 N_("Single step into function"),
968 G_CALLBACK (on_step_in_action_activate)
971 "ActionDebuggerStepOver",
972 "debugger-step-over",
973 N_("Step O_ver"),
974 "F6",
975 N_("Single step over function"),
976 G_CALLBACK (on_step_over_action_activate)
979 "ActionDebuggerStepOut",
980 "debugger-step-out",
981 N_("Step _Out"),
982 "F7",
983 N_("Single step out of the function"),
984 G_CALLBACK (on_step_out_action_activate)
987 "ActionDebuggerRunToPosition",
988 "debugger-run-to-cursor",
989 N_("_Run to Cursor"),
990 "F8",
991 N_("Run to the cursor"),
992 G_CALLBACK (on_run_to_cursor_action_activate)
995 "ActionGdbCommand",
996 NULL,
997 N_("Debugger Command..."),
998 NULL,
999 N_("Custom debugger command"),
1000 G_CALLBACK (on_debugger_custom_command_activate)
1003 "ActionMenuGdbInformation",
1004 NULL,
1005 N_("_Info"),
1006 NULL,
1007 NULL,
1008 NULL
1011 "ActionGdbInfoGlobalVariables",
1012 NULL,
1013 N_("Info _Global Variables"),
1014 NULL,
1015 N_("Display all global and static variables of the program"),
1016 G_CALLBACK (on_info_variables_activate)
1019 "ActionGdbInfoCurrentFrame",
1020 NULL,
1021 N_("Info _Current Frame"),
1022 NULL,
1023 N_("Display information about the current frame of execution"),
1024 G_CALLBACK (on_info_frame_activate)
1027 "ActionGdbInfoFunctionArgs",
1028 NULL,
1029 N_("Info Function _Arguments"),
1030 NULL,
1031 N_("Display function arguments of the current frame"),
1032 G_CALLBACK (on_info_args_activate)
1035 "ActionGdbViewSharedlibs",
1036 NULL,
1037 N_("Shared Libraries"),
1038 NULL,
1039 N_("Show shared libraries mappings"),
1040 G_CALLBACK (on_debugger_sharedlibs_activate)
1043 "ActionGdbViewSignals",
1044 NULL,
1045 N_("Kernel Signals"),
1046 NULL,
1047 N_("Show kernel signals"),
1048 G_CALLBACK (on_debugger_signals_activate)
1052 static GtkActionEntry actions_running[] =
1055 "ActionGdbPauseProgram", /* Action name */
1056 GTK_STOCK_MEDIA_PAUSE, /* Stock icon, if any */
1057 N_("Pa_use Program"), /* Display label */
1058 NULL, /* short-cut */
1059 N_("Pauses the execution of the program"), /* Tooltip */
1060 G_CALLBACK (on_debugger_interrupt_activate) /* action callback */
1064 /* AnjutaPlugin functions
1065 *---------------------------------------------------------------------------*/
1067 static gboolean
1068 dma_plugin_activate (AnjutaPlugin* plugin)
1070 DebugManagerPlugin *this;
1071 static gboolean initialized = FALSE;
1072 AnjutaUI *ui;
1073 GtkAction *action;
1075 DEBUG_PRINT ("DebugManagerPlugin: Activating Debug Manager plugin...");
1076 this = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
1078 if (!initialized)
1080 initialized = TRUE;
1081 register_stock_icons (ANJUTA_PLUGIN (plugin));
1084 /* Load debugger */
1085 this->queue = dma_debugger_queue_new (plugin);
1086 g_signal_connect (this, "debugger-started", G_CALLBACK (dma_plugin_debugger_started), this);
1087 g_signal_connect (this, "debugger-stopped", G_CALLBACK (dma_plugin_debugger_stopped), this);
1088 g_signal_connect (this, "program-loaded", G_CALLBACK (dma_plugin_program_loaded), this);
1089 g_signal_connect (this, "program-running", G_CALLBACK (dma_plugin_program_running), this);
1090 g_signal_connect (this, "program-stopped", G_CALLBACK (dma_plugin_program_stopped), this);
1091 g_signal_connect (this, "program-exited", G_CALLBACK (dma_plugin_program_loaded), this);
1092 g_signal_connect (this, "program-moved", G_CALLBACK (dma_plugin_program_moved), this);
1093 g_signal_connect (this, "signal-received", G_CALLBACK (dma_plugin_signal_received), this);
1094 g_signal_connect (this, "location_changed", G_CALLBACK (dma_plugin_location_changed), this);
1096 /* Add all our debug manager actions */
1097 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin)->shell, NULL);
1098 this->start_group =
1099 anjuta_ui_add_action_group_entries (ui, "ActionGroupDebug",
1100 _("Debugger operations"),
1101 actions_start,
1102 G_N_ELEMENTS (actions_start),
1103 GETTEXT_PACKAGE, TRUE, this);
1104 this->loaded_group =
1105 anjuta_ui_add_action_group_entries (ui, "ActionGroupDebug",
1106 _("Debugger operations"),
1107 actions_loaded,
1108 G_N_ELEMENTS (actions_loaded),
1109 GETTEXT_PACKAGE, TRUE, this);
1110 this->stopped_group =
1111 anjuta_ui_add_action_group_entries (ui, "ActionGroupDebug",
1112 _("Debugger operations"),
1113 actions_stopped,
1114 G_N_ELEMENTS (actions_stopped),
1115 GETTEXT_PACKAGE, TRUE, this);
1116 this->running_group =
1117 anjuta_ui_add_action_group_entries (ui, "ActionGroupDebug",
1118 _("Debugger operations"),
1119 actions_running,
1120 G_N_ELEMENTS (actions_running),
1121 GETTEXT_PACKAGE, TRUE, this);
1122 this->uiid = anjuta_ui_merge (ui, UI_FILE);
1124 /* Variable */
1125 this->variable = dma_variable_dbase_new (this);
1127 /* Stack trace */
1128 this->stack = stack_trace_new (this);
1130 /* Thread list */
1131 this->thread = dma_threads_new (this);
1133 /* Create breakpoints list */
1134 this->breakpoints = breakpoints_dbase_new (this);
1136 /* Register list */
1137 this->registers = cpu_registers_new (this);
1139 /* Memory window */
1140 this->memory = dma_memory_new (this);
1142 /* Disassembly window */
1143 this->disassemble = dma_disassemble_new (this);
1145 /* Start debugger part */
1146 this->start = dma_start_new (this);
1149 dma_plugin_debugger_stopped (this, 0);
1150 action = gtk_action_group_get_action (this->start_group, "ActionDebuggerRestartTarget");
1151 gtk_action_set_sensitive (action, FALSE);
1153 /* Add watches */
1154 this->project_watch_id =
1155 anjuta_plugin_add_watch (plugin, "project_root_uri",
1156 value_added_project_root_uri,
1157 value_removed_project_root_uri, NULL);
1158 this->editor_watch_id =
1159 anjuta_plugin_add_watch (plugin, "document_manager_current_editor",
1160 value_added_current_editor,
1161 value_removed_current_editor, NULL);
1163 /* Connect to save session */
1164 g_signal_connect (G_OBJECT (plugin->shell), "save_session",
1165 G_CALLBACK (on_session_save), plugin);
1167 return TRUE;
1170 static gboolean
1171 dma_plugin_deactivate (AnjutaPlugin* plugin)
1173 DebugManagerPlugin *this;
1174 AnjutaUI *ui;
1176 DEBUG_PRINT ("DebugManagerPlugin: Deactivating Debug Manager plugin...");
1178 this = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
1180 /* Stop debugger */
1181 dma_plugin_debugger_stopped (this, 0);
1183 g_signal_handlers_disconnect_matched (plugin->shell, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, plugin);
1184 g_signal_handlers_disconnect_matched (plugin, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, plugin);
1186 anjuta_plugin_remove_watch (plugin, this->project_watch_id, FALSE);
1187 anjuta_plugin_remove_watch (plugin, this->editor_watch_id, FALSE);
1189 dma_debugger_queue_free (this->queue);
1190 this->queue = NULL;
1192 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1193 anjuta_ui_unmerge (ui, this->uiid);
1195 dma_variable_dbase_free (this->variable);
1196 this->variable = NULL;
1198 breakpoints_dbase_destroy (this->breakpoints);
1199 this->breakpoints = NULL;
1201 stack_trace_free (this->stack);
1202 this->stack = NULL;
1204 cpu_registers_free (this->registers);
1205 this->registers = NULL;
1207 dma_memory_free (this->memory);
1208 this->memory = NULL;
1210 dma_disassemble_free (this->disassemble);
1211 this->disassemble = NULL;
1213 dma_threads_free (this->thread);
1214 this->thread = NULL;
1216 dma_start_free (this->start);
1217 this->start = NULL;
1219 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
1220 anjuta_ui_remove_action_group (ui, this->start_group);
1221 anjuta_ui_remove_action_group (ui, this->loaded_group);
1222 anjuta_ui_remove_action_group (ui, this->stopped_group);
1223 anjuta_ui_remove_action_group (ui, this->running_group);
1225 if (this->view != NULL)
1227 g_object_remove_weak_pointer (G_OBJECT (this->view), (gpointer*)(gpointer)&this->view);
1228 this->view = NULL;
1231 return TRUE;
1234 /* Public functions
1235 *---------------------------------------------------------------------------*/
1237 DmaDebuggerQueue*
1238 dma_debug_manager_get_queue (DebugManagerPlugin *self)
1240 return self->queue;
1243 /* GObject functions
1244 *---------------------------------------------------------------------------*/
1246 /* Used in dispose and finalize */
1247 static gpointer parent_class;
1249 /* instance_init is the constructor. All functions should work after this
1250 * call. */
1252 static void
1253 dma_plugin_instance_init (GObject* obj)
1255 DebugManagerPlugin *plugin = ANJUTA_PLUGIN_DEBUG_MANAGER (obj);
1257 plugin->uiid = 0;
1259 plugin->project_root_uri = NULL;
1260 plugin->queue = NULL;
1261 plugin->current_editor = NULL;
1262 plugin->pc_editor = NULL;
1263 plugin->editor_watch_id = 0;
1264 plugin->project_watch_id = 0;
1265 plugin->breakpoints = NULL;
1266 plugin->registers = NULL;
1267 plugin->signals = NULL;
1268 plugin->sharedlibs = NULL;
1269 plugin->view = NULL;
1271 /* plugin->uri = NULL; */
1274 /* dispose is the first destruction step. It is used to unref object created
1275 * with instance_init in order to break reference counting cycles. This
1276 * function could be called several times. All function should still work
1277 * after this call. It has to called its parents.*/
1279 static void
1280 dma_plugin_dispose (GObject* obj)
1282 GNOME_CALL_PARENT (G_OBJECT_CLASS, dispose, (G_OBJECT (obj)));
1285 /* finalize is the last destruction step. It must free all memory allocated
1286 * with instance_init. It is called only one time just before releasing all
1287 * memory */
1289 static void
1290 dma_plugin_finalize (GObject* obj)
1292 DebugManagerPlugin *self = ANJUTA_PLUGIN_DEBUG_MANAGER (obj);
1294 if (self->pc_editor != NULL)
1296 g_object_remove_weak_pointer (G_OBJECT (self->pc_editor), (gpointer *)(gpointer)&self->pc_editor);
1298 if (self->current_editor != NULL)
1300 g_object_remove_weak_pointer (G_OBJECT (self->current_editor), (gpointer *)(gpointer)&self->current_editor);
1303 GNOME_CALL_PARENT (G_OBJECT_CLASS, finalize, (G_OBJECT (obj)));
1306 /* class_init intialize the class itself not the instance */
1308 static void
1309 dma_plugin_class_init (GObjectClass* klass)
1311 AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
1313 parent_class = g_type_class_peek_parent (klass);
1315 plugin_class->activate = dma_plugin_activate;
1316 plugin_class->deactivate = dma_plugin_deactivate;
1317 klass->dispose = dma_plugin_dispose;
1318 klass->finalize = dma_plugin_finalize;
1321 /* Implementation of IAnjutaDebugManager interface
1322 *---------------------------------------------------------------------------*/
1324 static void
1325 idebug_manager_iface_init (IAnjutaDebugManagerIface *iface)
1329 ANJUTA_PLUGIN_BEGIN (DebugManagerPlugin, dma_plugin);
1330 ANJUTA_PLUGIN_ADD_INTERFACE(idebug_manager, IANJUTA_TYPE_DEBUG_MANAGER);
1331 ANJUTA_PLUGIN_END;
1333 ANJUTA_SIMPLE_PLUGIN (DebugManagerPlugin, dma_plugin);