* plugins/debug-manager/disassemble.c,
[anjuta-git-plugin.git] / plugins / debug-manager / plugin.c
blob0556a95795f413c2896d6b0048b0c6e6f69ad95d
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 "watch.h"
29 #include "locals.h"
30 #include "stack_trace.h"
31 #include "threads.h"
32 #include "info.h"
33 #include "memory.h"
34 #include "disassemble.h"
35 #include "signals.h"
36 #include "sharedlib.h"
37 #include "registers.h"
38 #include "utilities.h"
39 #include "start.h"
40 #include "queue.h"
42 #include <libanjuta/anjuta-shell.h>
43 #include <libanjuta/anjuta-debug.h>
44 #include <libanjuta/anjuta-status.h>
45 #include <libanjuta/interfaces/ianjuta-file.h>
46 #include <libanjuta/interfaces/ianjuta-editor.h>
47 #include <libanjuta/interfaces/ianjuta-indicable.h>
48 #include <libanjuta/interfaces/ianjuta-markable.h>
49 #include <libanjuta/interfaces/ianjuta-debug-manager.h>
50 #include <libanjuta/interfaces/ianjuta-project-manager.h>
51 #include <libanjuta/interfaces/ianjuta-document-manager.h>
52 #include <libanjuta/interfaces/ianjuta-message-manager.h>
54 #include <libgnomevfs/gnome-vfs.h>
56 /* Contants defintion
57 *---------------------------------------------------------------------------*/
59 #define ICON_FILE "anjuta-debug-manager-plugin-48.png"
60 #define UI_FILE PACKAGE_DATA_DIR"/ui/anjuta-debug-manager.ui"
61 #define GLADE_FILE PACKAGE_DATA_DIR"/glade/anjuta-debug-manager.glade"
63 /* Plugin type
64 *---------------------------------------------------------------------------*/
66 struct _DebugManagerPlugin
68 AnjutaPlugin parent;
70 /* Debugger queue */
71 DmaDebuggerQueue *queue;
73 /* Menu item */
74 gint uiid;
75 GtkActionGroup *start_group;
76 GtkActionGroup *loaded_group;
77 GtkActionGroup *stopped_group;
78 GtkActionGroup *running_group;
80 /* Project */
81 gchar *project_root_uri;
82 guint project_watch_id;
84 /* Editor */
85 IAnjutaEditor *current_editor;
86 guint editor_watch_id;
87 IAnjutaEditor *pc_editor;
88 guint pc_line;
89 guint pc_address;
90 gboolean busy;
92 /* Debugger components */
93 Locals *locals;
94 ExprWatch *watch;
95 BreakpointsDBase *breakpoints;
96 DmaStart *start;
97 StackTrace *stack;
98 CpuRegisters *registers;
99 Sharedlibs *sharedlibs;
100 Signals *signals;
101 DmaMemory *memory;
102 DmaDisassemble *disassemble;
103 DmaThreads *thread;
106 /* Logging view */
107 IAnjutaMessageView* view;
110 struct _DebugManagerPluginClass
112 AnjutaPluginClass parent_class;
115 /* Private functions
116 *---------------------------------------------------------------------------*/
118 static void
119 register_stock_icons (AnjutaPlugin *plugin)
121 static gboolean registered = FALSE;
123 if (registered)
124 return;
125 registered = TRUE;
127 /* Register stock icons */
128 BEGIN_REGISTER_ICON (plugin)
129 REGISTER_ICON (ICON_FILE, "debugger-icon");
130 REGISTER_ICON ("stack.png", "gdb-stack-icon");
131 REGISTER_ICON ("locals.png", "gdb-locals-icon");
132 REGISTER_ICON_FULL ("anjuta-watch", "gdb-watch-icon");
133 REGISTER_ICON_FULL ("anjuta-breakpoint-toggle", ANJUTA_STOCK_BREAKPOINT_TOGGLE);
134 REGISTER_ICON_FULL ("anjuta-breakpoint-clear", ANJUTA_STOCK_BREAKPOINT_CLEAR);
135 /* We have no -24 version for the next two */
136 REGISTER_ICON ("anjuta-breakpoint-disabled-16.png", ANJUTA_STOCK_BREAKPOINT_DISABLED);
137 REGISTER_ICON ("anjuta-breakpoint-enabled-16.png", ANJUTA_STOCK_BREAKPOINT_ENABLED);
138 REGISTER_ICON_FULL ("anjuta-attach", "debugger-attach");
139 REGISTER_ICON_FULL ("anjuta-step-into", "debugger-step-into");
140 REGISTER_ICON_FULL ("anjuta-step-out", "debugger-step-out");
141 REGISTER_ICON_FULL ("anjuta-step-over", "debugger-step-over");
142 REGISTER_ICON_FULL ("anjuta-run-to-cursor", "debugger-run-to-cursor");
143 END_REGISTER_ICON
146 /* Program counter functions
147 *---------------------------------------------------------------------------*/
149 static void
150 show_program_counter_in_editor(DebugManagerPlugin *self)
152 IAnjutaEditor *editor = self->current_editor;
154 if ((editor != NULL) && (self->pc_editor == editor))
156 if (IANJUTA_IS_MARKABLE (editor))
158 ianjuta_markable_mark(IANJUTA_MARKABLE (editor), self->pc_line, IANJUTA_MARKABLE_PROGRAM_COUNTER, NULL);
160 if (IANJUTA_IS_INDICABLE(editor))
162 gint begin = ianjuta_editor_get_line_begin_position(editor, self->pc_line, NULL);
163 gint end = ianjuta_editor_get_line_end_position(editor, self->pc_line, NULL);
165 ianjuta_indicable_set(IANJUTA_INDICABLE(editor), begin, end, IANJUTA_INDICABLE_IMPORTANT,
166 NULL);
171 static void
172 hide_program_counter_in_editor(DebugManagerPlugin *self)
174 IAnjutaEditor *editor = self->current_editor;
176 if ((editor != NULL) && (self->pc_editor == editor))
178 if (IANJUTA_IS_MARKABLE (editor))
180 ianjuta_markable_delete_all_markers (IANJUTA_MARKABLE (editor), IANJUTA_MARKABLE_PROGRAM_COUNTER, NULL);
182 if (IANJUTA_IS_INDICABLE(editor))
184 ianjuta_indicable_clear(IANJUTA_INDICABLE(editor), NULL);
189 static void
190 set_program_counter(DebugManagerPlugin *self, const gchar* file, guint line, guint address)
192 IAnjutaDocumentManager *docman = NULL;
193 gchar *file_uri;
195 /* Remove previous marker */
196 hide_program_counter_in_editor (self);
197 if (self->pc_editor != NULL)
199 g_object_remove_weak_pointer (G_OBJECT (self->pc_editor), (gpointer *)(gpointer)&self->pc_editor);
200 self->pc_editor = NULL;
202 self->pc_address = address;
204 if (file != NULL)
206 docman = anjuta_shell_get_interface (ANJUTA_PLUGIN (self)->shell, IAnjutaDocumentManager, NULL);
207 file_uri = g_strconcat ("file://", file, NULL);
208 if (docman)
210 IAnjutaEditor* editor;
212 editor = ianjuta_document_manager_goto_file_line(docman, file_uri, line, NULL);
214 if (editor != NULL)
216 self->pc_editor = editor;
217 g_object_add_weak_pointer (G_OBJECT (editor), (gpointer)(gpointer)&self->pc_editor);
218 self->pc_line = line;
219 show_program_counter_in_editor (self);
222 g_free (file_uri);
226 static void
227 value_added_project_root_uri (AnjutaPlugin *plugin, const gchar *name,
228 const GValue *value, gpointer user_data)
230 DebugManagerPlugin *dm_plugin;
231 const gchar *root_uri;
233 dm_plugin = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
235 if (dm_plugin->project_root_uri)
236 g_free (dm_plugin->project_root_uri);
237 dm_plugin->project_root_uri = NULL;
239 root_uri = g_value_get_string (value);
240 if (root_uri)
242 dm_plugin->project_root_uri = g_strdup (root_uri);
246 static void
247 value_removed_project_root_uri (AnjutaPlugin *plugin, const gchar *name,
248 gpointer user_data)
250 DebugManagerPlugin *dm_plugin;
252 dm_plugin = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
254 if (dm_plugin->project_root_uri)
255 g_free (dm_plugin->project_root_uri);
256 dm_plugin->project_root_uri = NULL;
259 static void
260 value_added_current_editor (AnjutaPlugin *plugin, const char *name,
261 const GValue *value, gpointer data)
263 GObject *editor;
264 DebugManagerPlugin *self;
266 self = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
268 editor = g_value_get_object (value);
269 DEBUG_PRINT("add value current editor %p", editor);
271 if (!IANJUTA_IS_EDITOR(editor))
273 self->current_editor = NULL;
274 return;
277 self->current_editor = IANJUTA_EDITOR (editor);
278 g_object_add_weak_pointer (G_OBJECT (self->current_editor), (gpointer *)(gpointer)&self->current_editor);
280 /* Restore program counter marker */
281 show_program_counter_in_editor (self);
284 static void
285 value_removed_current_editor (AnjutaPlugin *plugin,
286 const char *name, gpointer data)
288 DebugManagerPlugin *self = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
290 DEBUG_PRINT("remove value current editor %p", self->current_editor);
291 if (self->current_editor)
293 hide_program_counter_in_editor (self);
295 g_object_remove_weak_pointer (G_OBJECT (self->current_editor), (gpointer *)(gpointer)&self->current_editor);
297 self->current_editor = NULL;
300 static void
301 enable_log_view (DebugManagerPlugin *this, gboolean enable)
303 if (enable)
305 if (this->view == NULL)
307 IAnjutaMessageManager* man;
309 man = anjuta_shell_get_interface (ANJUTA_PLUGIN (this)->shell, IAnjutaMessageManager, NULL);
310 this->view = ianjuta_message_manager_add_view (man, _("Debugger Log"), ICON_FILE, NULL);
311 if (this->view != NULL)
313 /*g_signal_connect (G_OBJECT (this->view), "buffer_flushed", G_CALLBACK (on_message_buffer_flushed), this);*/
314 g_object_add_weak_pointer (G_OBJECT (this->view), (gpointer *)(gpointer)&this->view);
315 dma_queue_enable_log (this->queue, this->view);
318 else
320 ianjuta_message_view_clear (this->view, NULL);
323 else
325 if (this->view != NULL)
327 IAnjutaMessageManager* man;
329 man = anjuta_shell_get_interface (ANJUTA_PLUGIN (this)->shell, IAnjutaMessageManager, NULL);
330 ianjuta_message_manager_remove_view (man, this->view, NULL);
331 this->view = NULL;
333 if (this->queue != NULL)
335 dma_queue_disable_log (this->queue);
340 static void
341 on_session_save (AnjutaShell *shell, AnjutaSessionPhase phase,
342 AnjutaSession *session, DebugManagerPlugin *plugin)
344 if (phase == ANJUTA_SESSION_PHASE_FIRST)
345 enable_log_view (plugin, FALSE);
346 if (phase != ANJUTA_SESSION_PHASE_NORMAL)
347 return;
349 /* Close debugger when session changed */
350 if (plugin->queue)
352 dma_queue_abort (plugin->queue);
357 /* State functions
358 *---------------------------------------------------------------------------*/
360 /* Called when the debugger is started but no program is loaded */
362 static void
363 dma_plugin_debugger_started (DebugManagerPlugin *this)
365 AnjutaUI *ui;
366 GtkAction *action;
367 AnjutaStatus* status;
369 DEBUG_PRINT ("DMA: dma_plugin_debugger_started");
371 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
373 /* Update ui */
374 action = gtk_action_group_get_action (this->start_group, "ActionDebuggerStop");
375 gtk_action_set_sensitive (action, TRUE);
376 gtk_action_group_set_visible (this->loaded_group, TRUE);
377 gtk_action_group_set_sensitive (this->loaded_group, FALSE);
378 gtk_action_group_set_visible (this->stopped_group, TRUE);
379 gtk_action_group_set_sensitive (this->stopped_group, FALSE);
380 gtk_action_group_set_visible (this->running_group, TRUE);
381 gtk_action_group_set_sensitive (this->running_group, FALSE);
383 status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
384 anjuta_status_set_default (status, _("Debugger"), _("Started"));
387 /* Called when a program is loaded */
389 static void
390 dma_plugin_program_loaded (DebugManagerPlugin *this)
392 AnjutaUI *ui;
393 AnjutaStatus* status;
395 DEBUG_PRINT ("DMA: dma_plugin_program_loaded");
397 if (this->sharedlibs == NULL)
399 this->sharedlibs = sharedlibs_new (this);
401 if (this->signals == NULL)
403 this->signals = signals_new (this);
406 /* Update ui */
407 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
408 gtk_action_group_set_sensitive (this->loaded_group, TRUE);
409 gtk_action_group_set_sensitive (this->stopped_group, FALSE);
410 gtk_action_group_set_sensitive (this->running_group, FALSE);
412 status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
413 anjuta_status_set_default (status, _("Debugger"), _("Loaded"));
416 /* Called when the program is running */
418 static void
419 dma_plugin_program_running (DebugManagerPlugin *this)
421 AnjutaUI *ui;
422 AnjutaStatus* status;
424 DEBUG_PRINT ("DMA: dma_plugin_program_running");
426 /* Update ui */
427 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
428 gtk_action_group_set_sensitive (this->loaded_group, TRUE);
429 gtk_action_group_set_sensitive (this->stopped_group, FALSE);
430 gtk_action_group_set_sensitive (this->running_group, TRUE);
432 status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
433 anjuta_status_set_default (status, _("Debugger"), _("Running..."));
435 set_program_counter(this, NULL, 0, 0);
438 /* Called when the program is stopped */
440 static void
441 dma_plugin_program_stopped (DebugManagerPlugin *this)
443 AnjutaUI *ui;
444 AnjutaStatus* status;
446 DEBUG_PRINT ("DMA: dma_plugin_program_broken");
448 /* Update ui */
449 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
450 gtk_action_group_set_sensitive (this->loaded_group, TRUE);
451 gtk_action_group_set_sensitive (this->stopped_group, TRUE);
452 gtk_action_group_set_sensitive (this->running_group, FALSE);
454 status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
455 anjuta_status_set_default (status, _("Debugger"), _("Stopped"));
458 /* Called when the program postion change */
460 static void
461 dma_plugin_program_moved (DebugManagerPlugin *this, guint pid, guint tid, guint address, const gchar* file, guint line)
463 DEBUG_PRINT ("DMA: dma_plugin_program_moved %s %d %x", file, line, address);
465 set_program_counter (this, file, line, address);
468 /* Called when a program is unloaded */
469 static void
470 dma_plugin_program_unload (DebugManagerPlugin *this)
472 AnjutaUI *ui;
473 AnjutaStatus* status;
475 DEBUG_PRINT ("DMA: dma_plugin_program_unload");
477 if (this->sharedlibs != NULL)
479 sharedlibs_free (this->sharedlibs);
480 this->sharedlibs = NULL;
482 if (this->signals == NULL)
484 signals_free (this->signals);
485 this->signals = NULL;
488 /* Update ui */
489 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
490 gtk_action_group_set_visible (this->start_group, TRUE);
491 gtk_action_group_set_sensitive (this->start_group, TRUE);
492 gtk_action_group_set_visible (this->loaded_group, TRUE);
493 gtk_action_group_set_sensitive (this->loaded_group, FALSE);
494 gtk_action_group_set_visible (this->stopped_group, TRUE);
495 gtk_action_group_set_sensitive (this->stopped_group, FALSE);
496 gtk_action_group_set_visible (this->running_group, TRUE);
497 gtk_action_group_set_sensitive (this->running_group, FALSE);
499 status = anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell, NULL);
500 anjuta_status_set_default (status, _("Debugger"), _("Unloaded"));
503 /* Called when the debugger is stopped */
505 static void
506 dma_plugin_debugger_stopped (DebugManagerPlugin *self, GError *err)
508 AnjutaUI *ui;
509 GtkAction *action;
510 AnjutaStatus* state;
512 DEBUG_PRINT ("DMA: dma_plugin_debugger_stopped");
514 dma_plugin_program_unload (self);
516 /* Update ui */
517 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (self)->shell, NULL);
518 gtk_action_group_set_visible (self->start_group, TRUE);
519 gtk_action_group_set_sensitive (self->start_group, TRUE);
520 action = gtk_action_group_get_action (self->start_group, "ActionDebuggerStop");
521 gtk_action_set_sensitive (action, FALSE);
522 gtk_action_group_set_visible (self->loaded_group, TRUE);
523 gtk_action_group_set_sensitive (self->loaded_group, FALSE);
524 gtk_action_group_set_visible (self->stopped_group, TRUE);
525 gtk_action_group_set_sensitive (self->stopped_group, FALSE);
526 gtk_action_group_set_visible (self->running_group, TRUE);
527 gtk_action_group_set_sensitive (self->running_group, FALSE);
529 /* clear indicator */
530 set_program_counter (self, NULL, 0, 0);
532 enable_log_view (self, FALSE);
534 state = anjuta_shell_get_status(ANJUTA_PLUGIN (self)->shell, NULL);
535 anjuta_status_set_default (state, _("Debugger"), NULL);
537 /* Display a warning if debugger stop unexpectedly */
538 if (err != NULL)
540 GtkWindow *parent = GTK_WINDOW (ANJUTA_PLUGIN(self)->shell);
541 anjuta_util_dialog_error (parent, _("Debugger terminated with error %d: %s\n"), err->code, err->message);
546 static void
547 dma_plugin_signal_received (DebugManagerPlugin *self, const gchar *name, const gchar *description)
549 GtkWindow *parent = GTK_WINDOW (ANJUTA_PLUGIN (self)->shell);
551 /* Skip SIGINT signal */
552 if (strcmp(name, "SIGINT") != 0)
554 anjuta_util_dialog_warning (parent, _("Program has received signal: %s\n"), description);
558 /* Called when the user want to go to another location */
560 static void
561 dma_plugin_location_changed (DebugManagerPlugin *self, guint address, const gchar* uri, guint line)
563 /* Go to location in editor */
564 if (uri != NULL)
566 IAnjutaDocumentManager *docman;
568 docman = anjuta_shell_get_interface (ANJUTA_PLUGIN(self)->shell, IAnjutaDocumentManager, NULL);
569 if (docman)
571 ianjuta_document_manager_goto_file_line (docman, uri, line, NULL);
576 /* Start/Stop menu functions
577 *---------------------------------------------------------------------------*/
579 static void
580 on_start_debug_activate (GtkAction* action, DebugManagerPlugin* this)
582 enable_log_view (this, TRUE);
583 if (dma_run_target (this->start))
585 GtkAction *action;
586 action = gtk_action_group_get_action (this->start_group, "ActionDebuggerRestartTarget");
587 gtk_action_set_sensitive (action, TRUE);
592 static void
593 on_restart_debug_activate (GtkAction* action, DebugManagerPlugin* this)
595 enable_log_view (this, TRUE);
596 dma_rerun_target (this->start);
599 static void
600 on_attach_to_project_action_activate (GtkAction* action, DebugManagerPlugin* this)
602 enable_log_view (this, TRUE);
603 dma_attach_to_process (this->start);
606 static void
607 on_debugger_stop_activate (GtkAction* action, DebugManagerPlugin* plugin)
609 if (plugin->start)
611 dma_quit_debugger (plugin->start);
615 /* Execute call back
616 *---------------------------------------------------------------------------*/
618 static void
619 on_run_continue_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
621 if (plugin->queue)
622 dma_queue_run (plugin->queue);
625 static void
626 on_step_in_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
628 if (plugin->queue)
630 if ((plugin->disassemble != NULL) && (dma_disassemble_is_focus (plugin->disassemble)))
632 dma_queue_stepi_in (plugin->queue);
634 else
636 dma_queue_step_in (plugin->queue);
641 static void
642 on_step_over_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
644 if (plugin->queue)
646 if ((plugin->disassemble != NULL) && (dma_disassemble_is_focus (plugin->disassemble)))
648 dma_queue_stepi_over (plugin->queue);
650 else
652 dma_queue_step_over (plugin->queue);
657 static void
658 on_step_out_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
660 if (plugin->queue)
661 dma_queue_step_out (plugin->queue);
664 static void
665 on_run_to_cursor_action_activate (GtkAction* action, DebugManagerPlugin* plugin)
667 if (plugin->queue)
669 if ((plugin->disassemble != NULL) && (dma_disassemble_is_focus (plugin->disassemble)))
671 guint address;
673 address = dma_disassemble_get_current_address (plugin->disassemble);
674 dma_queue_run_to_address (plugin->queue, address);
676 else
678 IAnjutaDocumentManager *docman;
679 IAnjutaEditor *editor;
680 IAnjutaDocument *document;
681 gchar *uri;
682 gchar *file;
683 gint line;
685 docman = IANJUTA_DOCUMENT_MANAGER (anjuta_shell_get_object (ANJUTA_PLUGIN (plugin)->shell, "IAnjutaDocumentManager", NULL));
686 if (docman == NULL)
687 return;
689 document = ianjuta_document_manager_get_current_document (docman, NULL);
690 if (IANJUTA_IS_DOCUMENT(document))
692 editor = IANJUTA_EDITOR(document);
694 else
695 return;
696 uri = ianjuta_file_get_uri (IANJUTA_FILE (editor), NULL);
697 if (uri == NULL)
698 return;
700 file = gnome_vfs_get_local_path_from_uri (uri);
702 line = ianjuta_editor_get_lineno (editor, NULL);
703 dma_queue_run_to (plugin->queue, file, line);
704 g_free (uri);
705 g_free (file);
710 static void
711 on_debugger_interrupt_activate (GtkAction* action, DebugManagerPlugin* plugin)
713 if (plugin->queue)
714 dma_queue_interrupt (plugin->queue);
717 /* Custom command
718 *---------------------------------------------------------------------------*/
720 static void
721 on_debugger_command_entry_activate (GtkEntry *entry, DebugManagerPlugin *plugin)
723 const gchar *command;
725 command = gtk_entry_get_text (GTK_ENTRY (entry));
726 if (command && strlen (command))
727 dma_queue_send_command (plugin->queue, command);
728 gtk_entry_set_text (entry, "");
731 static void
732 on_debugger_custom_command_activate (GtkAction * action, DebugManagerPlugin *plugin)
734 GladeXML *gxml;
735 GtkWidget *win, *entry;
737 gxml = glade_xml_new (GLADE_FILE, "debugger_command_dialog", NULL);
738 win = glade_xml_get_widget (gxml, "debugger_command_dialog");
739 entry = glade_xml_get_widget (gxml, "debugger_command_entry");
741 gtk_window_set_transient_for (GTK_WINDOW (win),
742 GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell));
743 g_signal_connect_swapped (win, "response",
744 G_CALLBACK (gtk_widget_destroy),
745 win);
746 g_signal_connect (entry, "activate",
747 G_CALLBACK (on_debugger_command_entry_activate),
748 plugin);
749 g_object_unref (gxml);
752 /* Info callbacks
753 *---------------------------------------------------------------------------*/
755 static void
756 on_debugger_dialog_message (const gpointer data, gpointer user_data, GError* error)
758 const GList *cli_result = data;
759 GtkWindow *parent = GTK_WINDOW (user_data);
760 if (g_list_length ((GList*)cli_result) < 1)
761 return;
762 gdb_info_show_list (parent, (GList*)cli_result, 0, 0);
765 static void
766 on_info_targets_activate (GtkAction *action, DebugManagerPlugin *plugin)
768 dma_queue_info_target (plugin->queue, on_debugger_dialog_message, plugin);
771 static void
772 on_info_program_activate (GtkAction *action, DebugManagerPlugin *plugin)
774 dma_queue_info_program (plugin->queue, on_debugger_dialog_message, plugin);
777 static void
778 on_info_udot_activate (GtkAction *action, DebugManagerPlugin *plugin)
780 dma_queue_info_udot (plugin->queue, on_debugger_dialog_message, plugin);
783 static void
784 on_info_variables_activate (GtkAction *action, DebugManagerPlugin *plugin)
786 dma_queue_info_variables (plugin->queue, on_debugger_dialog_message, plugin);
789 static void
790 on_info_frame_activate (GtkAction *action, DebugManagerPlugin *plugin)
792 dma_queue_info_frame (plugin->queue, 0, on_debugger_dialog_message, plugin);
795 static void
796 on_info_args_activate (GtkAction *action, DebugManagerPlugin *plugin)
798 dma_queue_info_args (plugin->queue, on_debugger_dialog_message, plugin);
801 /* Other informations
802 *---------------------------------------------------------------------------*/
804 /*static void
805 on_info_memory_activate (GtkAction * action, DebugManagerPlugin *plugin)
807 GtkWidget *win_memory;
809 win_memory = memory_info_new (plugin->debugger,
810 GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell),
811 NULL);
812 gtk_widget_show(win_memory);
815 static void
816 on_debugger_sharedlibs_activate (GtkAction * action, DebugManagerPlugin *plugin)
818 sharedlibs_show (plugin->sharedlibs);
821 static void
822 on_debugger_signals_activate (GtkAction * action, DebugManagerPlugin *plugin)
824 signals_show (plugin->signals);
827 /* Actions table
828 *---------------------------------------------------------------------------*/
830 static GtkActionEntry actions_start[] =
833 "ActionMenuDebug", /* Action name */
834 NULL, /* Stock icon, if any */
835 N_("_Debug"), /* Display label */
836 NULL, /* short-cut */
837 NULL, /* Tooltip */
838 NULL /* action callback */
841 "ActionMenuStart",
842 "debugger-icon",
843 N_("_Start Debugger"),
844 NULL,
845 NULL,
846 NULL
849 "ActionDebuggerRunTarget",
850 NULL,
851 N_("Run Target..."),
852 "<shift>F12",
853 N_("load and start the target for debugging"),
854 G_CALLBACK (on_start_debug_activate)
857 "ActionDebuggerRestartTarget",
858 NULL,
859 N_("Restart Target"),
860 NULL,
861 N_("restart the same target for debugging"),
862 G_CALLBACK (on_restart_debug_activate)
865 "ActionDebuggerAttachProcess",
866 "debugger-attach",
867 N_("_Attach to Process..."),
868 NULL,
869 N_("Attach to a running program"),
870 G_CALLBACK (on_attach_to_project_action_activate)
873 "ActionDebuggerStop",
874 GTK_STOCK_STOP,
875 N_("Stop Debugger"),
876 NULL,
877 N_("Say goodbye to the debugger"),
878 G_CALLBACK (on_debugger_stop_activate)
882 static GtkActionEntry actions_loaded[] =
885 "ActionGdbCommand", /* Action name */
886 NULL, /* Stock icon, if any */
887 N_("Debugger Command..."), /* Display label */
888 NULL, /* short-cut */
889 N_("Custom debugger command"), /* Tooltip */
890 G_CALLBACK (on_debugger_custom_command_activate) /* action callback */
893 "ActionMenuGdbInformation",
894 NULL,
895 N_("_Info"),
896 NULL,
897 NULL,
898 NULL
901 "ActionGdbInfoTargetFiles",
902 NULL,
903 N_("Info _Target Files"),
904 NULL,
905 N_("Display information on the files the debugger is active with"),
906 G_CALLBACK (on_info_targets_activate)
909 "ActionGdbInfoProgram",
910 NULL,
911 N_("Info _Program"),
912 NULL,
913 N_("Display information on the execution status of the program"),
914 G_CALLBACK (on_info_program_activate)
917 "ActionGdbInfoKernelUserStruct",
918 NULL,
919 N_("Info _Kernel User Struct"),
920 NULL,
921 N_("Display the contents of kernel 'struct user' for current child"),
922 G_CALLBACK (on_info_udot_activate)
924 /* {
925 "ActionGdbExamineMemory",
926 NULL,
927 N_("Examine _Memory"),
928 NULL,
929 N_("Display accessible memory"),
930 G_CALLBACK (on_info_memory_activate)
931 },*/
933 "ActionGdbViewSharedlibs",
934 NULL,
935 N_("Shared Libraries"),
936 NULL,
937 N_("Show shared libraries mappings"),
938 G_CALLBACK (on_debugger_sharedlibs_activate)
941 "ActionGdbViewSignals",
942 NULL,
943 N_("Kernel Signals"),
944 NULL,
945 N_("Show kernel signals"),
946 G_CALLBACK (on_debugger_signals_activate)
950 static GtkActionEntry actions_stopped[] =
953 "ActionDebuggerRunContinue", /* Action name */
954 GTK_STOCK_EXECUTE, /* Stock icon, if any */
955 N_("Run/_Continue"), /* Display label */
956 "F4", /* short-cut */
957 N_("Continue the execution of the program"), /* Tooltip */
958 G_CALLBACK (on_run_continue_action_activate) /* action callback */
961 "ActionDebuggerStepIn",
962 "debugger-step-into",
963 N_("Step _In"),
964 "F5",
965 N_("Single step into function"),
966 G_CALLBACK (on_step_in_action_activate)
969 "ActionDebuggerStepOver",
970 "debugger-step-over",
971 N_("Step O_ver"),
972 "F6",
973 N_("Single step over function"),
974 G_CALLBACK (on_step_over_action_activate)
977 "ActionDebuggerStepOut",
978 "debugger-step-out",
979 N_("Step _Out"),
980 "F7",
981 N_("Single step out of the function"),
982 G_CALLBACK (on_step_out_action_activate)
985 "ActionDebuggerRunToPosition",
986 "debugger-run-to-cursor",
987 N_("_Run to Cursor"),
988 "F8",
989 N_("Run to the cursor"),
990 G_CALLBACK (on_run_to_cursor_action_activate)
993 "ActionGdbCommand",
994 NULL,
995 N_("Debugger Command..."),
996 NULL,
997 N_("Custom debugger command"),
998 G_CALLBACK (on_debugger_custom_command_activate)
1001 "ActionMenuGdbInformation",
1002 NULL,
1003 N_("_Info"),
1004 NULL,
1005 NULL,
1006 NULL
1009 "ActionGdbInfoGlobalVariables",
1010 NULL,
1011 N_("Info _Global Variables"),
1012 NULL,
1013 N_("Display all global and static variables of the program"),
1014 G_CALLBACK (on_info_variables_activate)
1017 "ActionGdbInfoCurrentFrame",
1018 NULL,
1019 N_("Info _Current Frame"),
1020 NULL,
1021 N_("Display information about the current frame of execution"),
1022 G_CALLBACK (on_info_frame_activate)
1025 "ActionGdbInfoFunctionArgs",
1026 NULL,
1027 N_("Info Function _Arguments"),
1028 NULL,
1029 N_("Display function arguments of the current frame"),
1030 G_CALLBACK (on_info_args_activate)
1033 "ActionGdbViewSharedlibs",
1034 NULL,
1035 N_("Shared Libraries"),
1036 NULL,
1037 N_("Show shared libraries mappings"),
1038 G_CALLBACK (on_debugger_sharedlibs_activate)
1041 "ActionGdbViewSignals",
1042 NULL,
1043 N_("Kernel Signals"),
1044 NULL,
1045 N_("Show kernel signals"),
1046 G_CALLBACK (on_debugger_signals_activate)
1050 static GtkActionEntry actions_running[] =
1053 "ActionGdbPauseProgram", /* Action name */
1054 GTK_STOCK_MEDIA_PAUSE, /* Stock icon, if any */
1055 N_("Pa_use Program"), /* Display label */
1056 NULL, /* short-cut */
1057 N_("Pauses the execution of the program"), /* Tooltip */
1058 G_CALLBACK (on_debugger_interrupt_activate) /* action callback */
1062 /* AnjutaPlugin functions
1063 *---------------------------------------------------------------------------*/
1065 static gboolean
1066 dma_plugin_activate (AnjutaPlugin* plugin)
1068 DebugManagerPlugin *this;
1069 static gboolean initialized = FALSE;
1070 AnjutaUI *ui;
1071 GtkAction *action;
1073 DEBUG_PRINT ("DebugManagerPlugin: Activating Debug Manager plugin...");
1074 this = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
1076 if (!initialized)
1078 initialized = TRUE;
1079 register_stock_icons (ANJUTA_PLUGIN (plugin));
1082 /* Load debugger */
1083 this->queue = dma_debugger_queue_new (plugin);
1084 g_signal_connect (this, "debugger-started", G_CALLBACK (dma_plugin_debugger_started), this);
1085 g_signal_connect (this, "debugger-stopped", G_CALLBACK (dma_plugin_debugger_stopped), this);
1086 g_signal_connect (this, "program-loaded", G_CALLBACK (dma_plugin_program_loaded), this);
1087 g_signal_connect (this, "program-running", G_CALLBACK (dma_plugin_program_running), this);
1088 g_signal_connect (this, "program-stopped", G_CALLBACK (dma_plugin_program_stopped), this);
1089 g_signal_connect (this, "program-exited", G_CALLBACK (dma_plugin_program_loaded), this);
1090 g_signal_connect (this, "program-moved", G_CALLBACK (dma_plugin_program_moved), this);
1091 g_signal_connect (this, "signal-received", G_CALLBACK (dma_plugin_signal_received), this);
1092 g_signal_connect (this, "location_changed", G_CALLBACK (dma_plugin_location_changed), this);
1094 /* Add all our debug manager actions */
1095 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin)->shell, NULL);
1096 this->start_group =
1097 anjuta_ui_add_action_group_entries (ui, "ActionGroupDebug",
1098 _("Debugger operations"),
1099 actions_start,
1100 G_N_ELEMENTS (actions_start),
1101 GETTEXT_PACKAGE, TRUE, this);
1102 this->loaded_group =
1103 anjuta_ui_add_action_group_entries (ui, "ActionGroupDebug",
1104 _("Debugger operations"),
1105 actions_loaded,
1106 G_N_ELEMENTS (actions_loaded),
1107 GETTEXT_PACKAGE, TRUE, this);
1108 this->stopped_group =
1109 anjuta_ui_add_action_group_entries (ui, "ActionGroupDebug",
1110 _("Debugger operations"),
1111 actions_stopped,
1112 G_N_ELEMENTS (actions_stopped),
1113 GETTEXT_PACKAGE, TRUE, this);
1114 this->running_group =
1115 anjuta_ui_add_action_group_entries (ui, "ActionGroupDebug",
1116 _("Debugger operations"),
1117 actions_running,
1118 G_N_ELEMENTS (actions_running),
1119 GETTEXT_PACKAGE, TRUE, this);
1120 this->uiid = anjuta_ui_merge (ui, UI_FILE);
1123 /* Watch expression */
1124 this->watch = expr_watch_new (ANJUTA_PLUGIN (this));
1126 /* Local window */
1127 this->locals = locals_new (this);
1129 /* Stack trace */
1130 this->stack = stack_trace_new (this);
1132 /* Thread list */
1133 this->thread = dma_threads_new (this);
1135 /* Create breakpoints list */
1136 this->breakpoints = breakpoints_dbase_new (this);
1138 /* Register list */
1139 this->registers = cpu_registers_new (this);
1141 /* Memory window */
1142 this->memory = dma_memory_new (this);
1144 /* Disassembly window */
1145 this->disassemble = dma_disassemble_new (this);
1147 /* Start debugger part */
1148 this->start = dma_start_new (this);
1151 dma_plugin_debugger_stopped (this, 0);
1152 action = gtk_action_group_get_action (this->start_group, "ActionDebuggerRestartTarget");
1153 gtk_action_set_sensitive (action, FALSE);
1155 /* Add watches */
1156 this->project_watch_id =
1157 anjuta_plugin_add_watch (plugin, "project_root_uri",
1158 value_added_project_root_uri,
1159 value_removed_project_root_uri, NULL);
1160 this->editor_watch_id =
1161 anjuta_plugin_add_watch (plugin, "document_manager_current_editor",
1162 value_added_current_editor,
1163 value_removed_current_editor, NULL);
1165 /* Connect to save session */
1166 g_signal_connect (G_OBJECT (plugin->shell), "save_session",
1167 G_CALLBACK (on_session_save), plugin);
1169 return TRUE;
1172 static gboolean
1173 dma_plugin_deactivate (AnjutaPlugin* plugin)
1175 DebugManagerPlugin *this;
1176 AnjutaUI *ui;
1178 DEBUG_PRINT ("DebugManagerPlugin: Deactivating Debug Manager plugin...");
1180 this = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin);
1182 /* Stop debugger */
1183 dma_plugin_debugger_stopped (this, 0);
1185 g_signal_handlers_disconnect_matched (plugin->shell, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, plugin);
1186 g_signal_handlers_disconnect_matched (plugin, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, plugin);
1188 anjuta_plugin_remove_watch (plugin, this->project_watch_id, FALSE);
1189 anjuta_plugin_remove_watch (plugin, this->editor_watch_id, FALSE);
1191 dma_debugger_queue_free (this->queue);
1192 this->queue = NULL;
1194 ui = anjuta_shell_get_ui (plugin->shell, NULL);
1195 anjuta_ui_unmerge (ui, this->uiid);
1197 expr_watch_destroy (this->watch);
1198 this->watch = NULL;
1200 breakpoints_dbase_destroy (this->breakpoints);
1201 this->breakpoints = NULL;
1203 locals_free (this->locals);
1204 this->locals = NULL;
1206 stack_trace_free (this->stack);
1207 this->stack = NULL;
1209 cpu_registers_free (this->registers);
1210 this->registers = NULL;
1212 dma_memory_free (this->memory);
1213 this->memory = NULL;
1215 dma_disassemble_free (this->disassemble);
1216 this->disassemble = NULL;
1218 dma_threads_free (this->thread);
1219 this->thread = NULL;
1221 dma_start_free (this->start);
1222 this->start = NULL;
1224 ui = anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell, NULL);
1225 anjuta_ui_remove_action_group (ui, this->start_group);
1226 anjuta_ui_remove_action_group (ui, this->loaded_group);
1227 anjuta_ui_remove_action_group (ui, this->stopped_group);
1228 anjuta_ui_remove_action_group (ui, this->running_group);
1230 if (this->view != NULL)
1232 g_object_remove_weak_pointer (G_OBJECT (this->view), (gpointer*)(gpointer)&this->view);
1233 this->view = NULL;
1236 return TRUE;
1239 /* Public functions
1240 *---------------------------------------------------------------------------*/
1242 DmaDebuggerQueue*
1243 dma_debug_manager_get_queue (DebugManagerPlugin *self)
1245 return self->queue;
1248 /* GObject functions
1249 *---------------------------------------------------------------------------*/
1251 /* Used in dispose and finalize */
1252 static gpointer parent_class;
1254 /* instance_init is the constructor. All functions should work after this
1255 * call. */
1257 static void
1258 dma_plugin_instance_init (GObject* obj)
1260 DebugManagerPlugin *plugin = ANJUTA_PLUGIN_DEBUG_MANAGER (obj);
1262 plugin->uiid = 0;
1264 plugin->project_root_uri = NULL;
1265 plugin->queue = NULL;
1266 plugin->current_editor = NULL;
1267 plugin->pc_editor = NULL;
1268 plugin->editor_watch_id = 0;
1269 plugin->project_watch_id = 0;
1270 plugin->breakpoints = NULL;
1271 plugin->watch = NULL;
1272 plugin->locals = NULL;
1273 plugin->registers = NULL;
1274 plugin->signals = NULL;
1275 plugin->sharedlibs = NULL;
1276 plugin->view = NULL;
1278 /* plugin->uri = NULL; */
1281 /* dispose is the first destruction step. It is used to unref object created
1282 * with instance_init in order to break reference counting cycles. This
1283 * function could be called several times. All function should still work
1284 * after this call. It has to called its parents.*/
1286 static void
1287 dma_plugin_dispose (GObject* obj)
1289 GNOME_CALL_PARENT (G_OBJECT_CLASS, dispose, (G_OBJECT (obj)));
1292 /* finalize is the last destruction step. It must free all memory allocated
1293 * with instance_init. It is called only one time just before releasing all
1294 * memory */
1296 static void
1297 dma_plugin_finalize (GObject* obj)
1299 DebugManagerPlugin *self = ANJUTA_PLUGIN_DEBUG_MANAGER (obj);
1301 if (self->pc_editor != NULL)
1303 g_object_remove_weak_pointer (G_OBJECT (self->pc_editor), (gpointer *)(gpointer)&self->pc_editor);
1305 if (self->current_editor != NULL)
1307 g_object_remove_weak_pointer (G_OBJECT (self->current_editor), (gpointer *)(gpointer)&self->current_editor);
1310 GNOME_CALL_PARENT (G_OBJECT_CLASS, finalize, (G_OBJECT (obj)));
1313 /* class_init intialize the class itself not the instance */
1315 static void
1316 dma_plugin_class_init (GObjectClass* klass)
1318 AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass);
1320 parent_class = g_type_class_peek_parent (klass);
1322 plugin_class->activate = dma_plugin_activate;
1323 plugin_class->deactivate = dma_plugin_deactivate;
1324 klass->dispose = dma_plugin_dispose;
1325 klass->finalize = dma_plugin_finalize;
1328 /* Implementation of IAnjutaDebugManager interface
1329 *---------------------------------------------------------------------------*/
1331 static void
1332 idebug_manager_iface_init (IAnjutaDebugManagerIface *iface)
1336 ANJUTA_PLUGIN_BEGIN (DebugManagerPlugin, dma_plugin);
1337 ANJUTA_PLUGIN_ADD_INTERFACE(idebug_manager, IANJUTA_TYPE_DEBUG_MANAGER);
1338 ANJUTA_PLUGIN_END;
1340 ANJUTA_SIMPLE_PLUGIN (DebugManagerPlugin, dma_plugin);