1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
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
27 #include "breakpoints.h"
28 #include "stack_trace.h"
31 #include "disassemble.h"
33 #include "sharedlib.h"
34 #include "registers.h"
35 #include "utilities.h"
40 #include <glib/gi18n.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>
56 *---------------------------------------------------------------------------*/
58 #define ICON_FILE "anjuta-debug-manager-plugin-48.png"
59 #define UI_FILE PACKAGE_DATA_DIR "/ui/anjuta-debug-manager.xml"
62 *---------------------------------------------------------------------------*/
64 struct _DebugManagerPlugin
69 DmaDebuggerQueue
*queue
;
73 GtkActionGroup
*start_group
;
74 GtkActionGroup
*loaded_group
;
75 GtkActionGroup
*stopped_group
;
76 GtkActionGroup
*running_group
;
77 GtkAction
*run_stop_action
;
80 gchar
*project_root_uri
;
81 guint project_watch_id
;
84 IAnjutaEditor
*current_editor
;
85 guint editor_watch_id
;
86 IAnjutaEditor
*pc_editor
;
91 /* Debugger components */
92 BreakpointsDBase
*breakpoints
;
95 CpuRegisters
*registers
;
96 Sharedlibs
*sharedlibs
;
99 DmaDisassemble
*disassemble
;
100 DmaVariableDBase
*variable
;
103 GtkWidget
*user_command_dialog
;
106 IAnjutaMessageView
* view
;
109 struct _DebugManagerPluginClass
111 AnjutaPluginClass parent_class
;
115 *---------------------------------------------------------------------------*/
118 register_stock_icons (AnjutaPlugin
*plugin
)
120 static gboolean registered
= FALSE
;
126 /* Register stock icons */
127 BEGIN_REGISTER_ICON (plugin
)
128 REGISTER_ICON (ICON_FILE
, "debugger-icon");
129 REGISTER_ICON ("stack.png", "gdb-stack-icon");
130 REGISTER_ICON ("locals.png", "gdb-locals-icon");
131 REGISTER_ICON_FULL ("anjuta-watch", "gdb-watch-icon");
132 REGISTER_ICON_FULL ("anjuta-breakpoint-toggle", ANJUTA_STOCK_BREAKPOINT_TOGGLE
);
133 REGISTER_ICON_FULL ("anjuta-breakpoint-clear", ANJUTA_STOCK_BREAKPOINT_CLEAR
);
134 /* We have no -24 version for the next two */
135 REGISTER_ICON ("anjuta-breakpoint-disabled-16.png", ANJUTA_STOCK_BREAKPOINT_DISABLED
);
136 REGISTER_ICON ("anjuta-breakpoint-enabled-16.png", ANJUTA_STOCK_BREAKPOINT_ENABLED
);
137 REGISTER_ICON_FULL ("anjuta-attach", "debugger-attach");
138 REGISTER_ICON_FULL ("anjuta-step-into", "debugger-step-into");
139 REGISTER_ICON_FULL ("anjuta-step-out", "debugger-step-out");
140 REGISTER_ICON_FULL ("anjuta-step-over", "debugger-step-over");
141 REGISTER_ICON_FULL ("anjuta-run-to-cursor", "debugger-run-to-cursor");
142 REGISTER_ICON_FULL ("anjuta-memory", "debugger-memory");
143 REGISTER_ICON_FULL ("anjuta-disassembly", "debugger-disassembly");
147 /* Program counter functions
148 *---------------------------------------------------------------------------*/
151 show_program_counter_in_editor(DebugManagerPlugin
*self
)
153 IAnjutaEditor
*editor
= self
->current_editor
;
155 if ((editor
!= NULL
) && (self
->pc_editor
== editor
))
157 if (IANJUTA_IS_MARKABLE (editor
))
159 ianjuta_markable_mark(IANJUTA_MARKABLE (editor
), self
->pc_line
, IANJUTA_MARKABLE_PROGRAM_COUNTER
, NULL
, NULL
);
161 if (IANJUTA_IS_INDICABLE(editor
))
163 IAnjutaIterable
*begin
=
164 ianjuta_editor_get_line_begin_position(editor
, self
->pc_line
, NULL
);
165 IAnjutaIterable
*end
=
166 ianjuta_editor_get_line_end_position(editor
, self
->pc_line
, NULL
);
168 ianjuta_indicable_set(IANJUTA_INDICABLE(editor
), begin
, end
,
169 IANJUTA_INDICABLE_IMPORTANT
, NULL
);
170 g_object_unref (begin
);
171 g_object_unref (end
);
177 hide_program_counter_in_editor(DebugManagerPlugin
*self
)
179 IAnjutaEditor
*editor
= self
->current_editor
;
181 if ((editor
!= NULL
) && (self
->pc_editor
== editor
))
183 if (IANJUTA_IS_MARKABLE (editor
))
185 ianjuta_markable_delete_all_markers (IANJUTA_MARKABLE (editor
), IANJUTA_MARKABLE_PROGRAM_COUNTER
, NULL
);
187 if (IANJUTA_IS_INDICABLE(editor
))
189 ianjuta_indicable_clear(IANJUTA_INDICABLE(editor
), NULL
);
195 set_program_counter(DebugManagerPlugin
*self
, const gchar
* filename
, guint line
, gulong address
)
197 IAnjutaDocumentManager
*docman
= NULL
;
200 /* Remove previous marker */
201 hide_program_counter_in_editor (self
);
202 if (self
->pc_editor
!= NULL
)
204 g_object_remove_weak_pointer (G_OBJECT (self
->pc_editor
), (gpointer
*)(gpointer
)&self
->pc_editor
);
205 self
->pc_editor
= NULL
;
207 self
->pc_address
= address
;
209 if (filename
!= NULL
)
211 file
= g_file_new_for_path (filename
);
212 docman
= anjuta_shell_get_interface (ANJUTA_PLUGIN (self
)->shell
, IAnjutaDocumentManager
, NULL
);
215 IAnjutaEditor
* editor
;
217 editor
= ianjuta_document_manager_goto_file_line(docman
, file
, line
, NULL
);
221 self
->pc_editor
= editor
;
222 g_object_add_weak_pointer (G_OBJECT (editor
), (gpointer
)(gpointer
)&self
->pc_editor
);
223 self
->pc_line
= line
;
224 show_program_counter_in_editor (self
);
227 g_object_unref (file
);
232 value_added_project_root_uri (AnjutaPlugin
*plugin
, const gchar
*name
,
233 const GValue
*value
, gpointer user_data
)
235 DebugManagerPlugin
*dm_plugin
;
236 const gchar
*root_uri
;
238 dm_plugin
= ANJUTA_PLUGIN_DEBUG_MANAGER (plugin
);
240 if (dm_plugin
->project_root_uri
)
241 g_free (dm_plugin
->project_root_uri
);
242 dm_plugin
->project_root_uri
= NULL
;
244 root_uri
= g_value_get_string (value
);
247 dm_plugin
->project_root_uri
= g_strdup (root_uri
);
252 value_removed_project_root_uri (AnjutaPlugin
*plugin
, const gchar
*name
,
255 DebugManagerPlugin
*dm_plugin
;
257 dm_plugin
= ANJUTA_PLUGIN_DEBUG_MANAGER (plugin
);
259 if (dm_plugin
->project_root_uri
)
260 g_free (dm_plugin
->project_root_uri
);
261 dm_plugin
->project_root_uri
= NULL
;
265 value_added_current_editor (AnjutaPlugin
*plugin
, const char *name
,
266 const GValue
*value
, gpointer data
)
269 DebugManagerPlugin
*self
;
271 self
= ANJUTA_PLUGIN_DEBUG_MANAGER (plugin
);
273 editor
= g_value_get_object (value
);
274 DEBUG_PRINT("add value current editor %p", editor
);
276 if (self
->current_editor
)
277 g_object_remove_weak_pointer (G_OBJECT (self
->current_editor
), (gpointer
*)(gpointer
)&self
->current_editor
);
279 if (!IANJUTA_IS_EDITOR(editor
))
281 self
->current_editor
= NULL
;
285 self
->current_editor
= IANJUTA_EDITOR (editor
);
286 g_object_add_weak_pointer (G_OBJECT (self
->current_editor
), (gpointer
*)(gpointer
)&self
->current_editor
);
288 /* Restore program counter marker */
289 show_program_counter_in_editor (self
);
291 /* connect signal to enable/disable breakpoints on double clicking the line marks gutter */
292 /* firstly, find the handler of previously connected signal */
293 /* secondly, connect signal if a handler wasn't found for the signal */
294 guint signal_id
= g_signal_lookup( "line-marks-gutter-clicked", IANJUTA_TYPE_EDITOR
);
295 glong handler_id
= g_signal_handler_find( (gpointer
)self
->current_editor
,
298 0, NULL
, NULL
, NULL
);
301 DEBUG_PRINT("current editor %p, breapoints db %p", self
->current_editor
, self
->breakpoints
);
305 self
->current_editor
,
306 "line-marks-gutter-clicked",
307 G_CALLBACK (breakpoint_toggle_handler
),
315 value_removed_current_editor (AnjutaPlugin
*plugin
,
316 const char *name
, gpointer data
)
318 DebugManagerPlugin
*self
= ANJUTA_PLUGIN_DEBUG_MANAGER (plugin
);
320 DEBUG_PRINT("remove value current editor %p", self
->current_editor
);
321 if (self
->current_editor
)
323 hide_program_counter_in_editor (self
);
325 g_object_remove_weak_pointer (G_OBJECT (self
->current_editor
), (gpointer
*)(gpointer
)&self
->current_editor
);
327 self
->current_editor
= NULL
;
331 enable_log_view (DebugManagerPlugin
*this, gboolean enable
)
335 if (this->view
== NULL
)
337 IAnjutaMessageManager
* man
;
339 man
= anjuta_shell_get_interface (ANJUTA_PLUGIN (this)->shell
, IAnjutaMessageManager
, NULL
);
340 this->view
= ianjuta_message_manager_add_view (man
, _("Debugger Log"), ICON_FILE
, NULL
);
341 if (this->view
!= NULL
)
343 /*g_signal_connect (G_OBJECT (this->view), "buffer_flushed", G_CALLBACK (on_message_buffer_flushed), this);*/
344 g_object_add_weak_pointer (G_OBJECT (this->view
), (gpointer
*)(gpointer
)&this->view
);
345 dma_queue_enable_log (this->queue
, this->view
);
350 ianjuta_message_view_clear (this->view
, NULL
);
355 if (this->view
!= NULL
)
357 IAnjutaMessageManager
* man
;
359 man
= anjuta_shell_get_interface (ANJUTA_PLUGIN (this)->shell
, IAnjutaMessageManager
, NULL
);
360 ianjuta_message_manager_remove_view (man
, this->view
, NULL
);
363 if (this->queue
!= NULL
)
365 dma_queue_disable_log (this->queue
);
371 on_session_save (AnjutaShell
*shell
, AnjutaSessionPhase phase
,
372 AnjutaSession
*session
, DebugManagerPlugin
*plugin
)
374 if (phase
== ANJUTA_SESSION_PHASE_FIRST
)
375 enable_log_view (plugin
, FALSE
);
376 if (phase
!= ANJUTA_SESSION_PHASE_NORMAL
)
379 /* Close debugger when session changed */
382 dma_queue_abort (plugin
->queue
);
387 *---------------------------------------------------------------------------*/
389 /* Called when the debugger is started but no program is loaded */
392 dma_plugin_debugger_started (DebugManagerPlugin
*this)
395 AnjutaStatus
* status
;
397 DEBUG_PRINT ("%s", "DMA: dma_plugin_debugger_started");
400 action
= gtk_action_group_get_action (this->start_group
, "ActionDebuggerStop");
401 gtk_action_set_sensitive (action
, TRUE
);
402 gtk_action_group_set_visible (this->loaded_group
, TRUE
);
403 gtk_action_group_set_sensitive (this->loaded_group
, FALSE
);
404 gtk_action_group_set_visible (this->stopped_group
, TRUE
);
405 gtk_action_group_set_sensitive (this->stopped_group
, FALSE
);
406 gtk_action_group_set_visible (this->running_group
, TRUE
);
407 gtk_action_group_set_sensitive (this->running_group
, FALSE
);
409 status
= anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell
, NULL
);
410 anjuta_status_set_default (status
, _("Debugger"), _("Started"));
413 /* Called when a program is loaded */
416 dma_plugin_program_loaded (DebugManagerPlugin
*this)
418 AnjutaStatus
* status
;
420 DEBUG_PRINT ("%s", "DMA: dma_plugin_program_loaded");
423 gtk_action_group_set_sensitive (this->loaded_group
, TRUE
);
424 gtk_action_group_set_sensitive (this->stopped_group
, FALSE
);
425 gtk_action_group_set_sensitive (this->running_group
, FALSE
);
427 gtk_action_set_sensitive (this->run_stop_action
, FALSE
);
429 status
= anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell
, NULL
);
430 anjuta_status_set_default (status
, _("Debugger"), _("Loaded"));
433 /* Called when the program is running */
436 dma_plugin_program_running (DebugManagerPlugin
*this)
438 AnjutaStatus
* status
;
440 DEBUG_PRINT ("%s", "DMA: dma_plugin_program_running");
443 gtk_action_group_set_sensitive (this->loaded_group
, TRUE
);
444 gtk_action_group_set_sensitive (this->stopped_group
, FALSE
);
445 gtk_action_group_set_sensitive (this->running_group
, TRUE
);
447 gtk_action_set_sensitive (this->run_stop_action
, TRUE
);
448 gtk_action_set_stock_id (this->run_stop_action
, GTK_STOCK_MEDIA_PAUSE
);
449 gtk_action_set_label (this->run_stop_action
, _("Pa_use Program"));
450 gtk_action_set_tooltip (this->run_stop_action
, _("Pauses the execution of the program"));
452 status
= anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell
, NULL
);
453 anjuta_status_set_default (status
, _("Debugger"), _("Running…"));
455 set_program_counter(this, NULL
, 0, 0);
458 /* Called when the program is stopped */
461 dma_plugin_program_stopped (DebugManagerPlugin
*this)
463 AnjutaStatus
* status
;
465 DEBUG_PRINT ("%s", "DMA: dma_plugin_program_broken");
468 gtk_action_group_set_sensitive (this->loaded_group
, TRUE
);
469 gtk_action_group_set_sensitive (this->stopped_group
, TRUE
);
470 gtk_action_group_set_sensitive (this->running_group
, FALSE
);
472 gtk_action_set_sensitive (this->run_stop_action
, TRUE
);
473 gtk_action_set_stock_id (this->run_stop_action
, GTK_STOCK_MEDIA_PLAY
);
474 gtk_action_set_label (this->run_stop_action
, _("Run/_Continue"));
475 gtk_action_set_tooltip (this->run_stop_action
, _("Continue the execution of the program"));
477 status
= anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell
, NULL
);
478 anjuta_status_set_default (status
, _("Debugger"), _("Stopped"));
481 /* Called when the program postion change */
484 dma_plugin_program_moved (DebugManagerPlugin
*this, guint pid
, guint tid
, gulong address
, const gchar
* file
, guint line
)
486 DEBUG_PRINT ("DMA: dma_plugin_program_moved %s %d %lx", file
, line
, address
);
488 set_program_counter (this, file
, line
, address
);
491 /* Called when a program is unloaded */
493 dma_plugin_program_unload (DebugManagerPlugin
*this)
495 AnjutaStatus
* status
;
497 DEBUG_PRINT ("%s", "DMA: dma_plugin_program_unload");
500 gtk_action_group_set_visible (this->start_group
, TRUE
);
501 gtk_action_group_set_sensitive (this->start_group
, TRUE
);
502 gtk_action_group_set_visible (this->loaded_group
, TRUE
);
503 gtk_action_group_set_sensitive (this->loaded_group
, FALSE
);
504 gtk_action_group_set_visible (this->stopped_group
, TRUE
);
505 gtk_action_group_set_sensitive (this->stopped_group
, FALSE
);
506 gtk_action_group_set_visible (this->running_group
, TRUE
);
507 gtk_action_group_set_sensitive (this->running_group
, FALSE
);
509 status
= anjuta_shell_get_status(ANJUTA_PLUGIN (this)->shell
, NULL
);
510 anjuta_status_set_default (status
, _("Debugger"), _("Unloaded"));
513 /* Called when the debugger is stopped */
516 dma_plugin_debugger_stopped (DebugManagerPlugin
*self
, GError
*err
)
521 DEBUG_PRINT ("%s", "DMA: dma_plugin_debugger_stopped");
523 dma_plugin_program_unload (self
);
526 gtk_action_group_set_visible (self
->start_group
, TRUE
);
527 gtk_action_group_set_sensitive (self
->start_group
, TRUE
);
528 action
= gtk_action_group_get_action (self
->start_group
, "ActionDebuggerStop");
529 gtk_action_set_sensitive (action
, FALSE
);
530 gtk_action_group_set_visible (self
->loaded_group
, TRUE
);
531 gtk_action_group_set_sensitive (self
->loaded_group
, FALSE
);
532 gtk_action_group_set_visible (self
->stopped_group
, TRUE
);
533 gtk_action_group_set_sensitive (self
->stopped_group
, FALSE
);
534 gtk_action_group_set_visible (self
->running_group
, TRUE
);
535 gtk_action_group_set_sensitive (self
->running_group
, FALSE
);
537 /* clear indicator */
538 set_program_counter (self
, NULL
, 0, 0);
540 state
= anjuta_shell_get_status(ANJUTA_PLUGIN (self
)->shell
, NULL
);
541 anjuta_status_set_default (state
, _("Debugger"), NULL
);
543 /* Remove user command dialog if existing */
544 if (self
->user_command_dialog
) gtk_widget_destroy (GTK_WIDGET (self
->user_command_dialog
));
546 /* Display a warning if debugger stop unexpectedly */
549 GtkWindow
*parent
= GTK_WINDOW (ANJUTA_PLUGIN(self
)->shell
);
550 anjuta_util_dialog_error (parent
, _("Debugger terminated with error %d: %s\n"), err
->code
, err
->message
);
556 dma_plugin_signal_received (DebugManagerPlugin
*self
, const gchar
*name
, const gchar
*description
)
558 GtkWindow
*parent
= GTK_WINDOW (ANJUTA_PLUGIN (self
)->shell
);
560 /* Skip SIGINT signal */
561 if (strcmp(name
, "SIGINT") != 0)
563 anjuta_util_dialog_warning (parent
, _("Program has received signal: %s\n"), description
);
567 /* Called when the user want to go to another location */
570 dma_plugin_location_changed (DebugManagerPlugin
*self
, gulong address
, const gchar
*uri
, guint line
)
572 /* Go to location in editor */
575 IAnjutaDocumentManager
*docman
;
576 docman
= anjuta_shell_get_interface (ANJUTA_PLUGIN(self
)->shell
, IAnjutaDocumentManager
, NULL
);
579 GFile
*file
= g_file_new_for_uri (uri
);
580 ianjuta_document_manager_goto_file_line (docman
, file
, line
, NULL
);
581 g_object_unref (file
);
586 /* Start/Stop menu functions
587 *---------------------------------------------------------------------------*/
590 on_start_debug_activate (GtkAction
* action
, DebugManagerPlugin
* this)
592 enable_log_view (this, TRUE
);
593 dma_run_target (this->start
, NULL
);
597 on_attach_to_project_action_activate (GtkAction
* action
, DebugManagerPlugin
* this)
599 enable_log_view (this, TRUE
);
600 dma_attach_to_process (this->start
);
604 on_start_remote_debug_action_activate (GtkAction
* action
, DebugManagerPlugin
* this)
606 /* Returns true if user clicked "Connect" */
607 enable_log_view (this, TRUE
);
608 dma_run_remote_target (this->start
, NULL
, NULL
);
612 on_debugger_stop_activate (GtkAction
* action
, DebugManagerPlugin
* plugin
)
616 dma_quit_debugger (plugin
->start
);
621 on_add_source_activate (GtkAction
* action
, DebugManagerPlugin
* this)
623 dma_add_source_path (this->start
);
627 *---------------------------------------------------------------------------*/
630 on_run_continue_action_activate (GtkAction
* action
, DebugManagerPlugin
* plugin
)
633 dma_queue_run (plugin
->queue
);
637 on_continue_suspend_action_activate (GtkAction
* action
, DebugManagerPlugin
* plugin
)
641 if (gtk_action_group_get_sensitive (plugin
->running_group
))
643 dma_queue_interrupt (plugin
->queue
);
647 dma_queue_run (plugin
->queue
);
653 on_step_in_action_activate (GtkAction
* action
, DebugManagerPlugin
* plugin
)
657 if ((plugin
->disassemble
!= NULL
) && (dma_disassemble_is_focus (plugin
->disassemble
)))
659 dma_queue_stepi_in (plugin
->queue
);
663 dma_queue_step_in (plugin
->queue
);
669 on_step_over_action_activate (GtkAction
* action
, DebugManagerPlugin
* plugin
)
673 if ((plugin
->disassemble
!= NULL
) && (dma_disassemble_is_focus (plugin
->disassemble
)))
675 dma_queue_stepi_over (plugin
->queue
);
679 dma_queue_step_over (plugin
->queue
);
685 on_step_out_action_activate (GtkAction
* action
, DebugManagerPlugin
* plugin
)
688 dma_queue_step_out (plugin
->queue
);
692 on_run_to_cursor_action_activate (GtkAction
* action
, DebugManagerPlugin
* plugin
)
696 if ((plugin
->disassemble
!= NULL
) && (dma_disassemble_is_focus (plugin
->disassemble
)))
700 address
= dma_disassemble_get_current_address (plugin
->disassemble
);
701 dma_queue_run_to_address (plugin
->queue
, address
);
705 IAnjutaEditor
*editor
;
710 editor
= dma_get_current_editor (ANJUTA_PLUGIN (plugin
));
713 file
= ianjuta_file_get_file (IANJUTA_FILE (editor
), NULL
);
717 filename
= g_file_get_path (file
);
719 line
= ianjuta_editor_get_lineno (editor
, NULL
);
720 dma_queue_run_to (plugin
->queue
, filename
, line
);
722 g_object_unref (file
);
728 on_run_from_cursor_action_activate (GtkAction
* action
, DebugManagerPlugin
* plugin
)
732 if ((plugin
->disassemble
!= NULL
) && (dma_disassemble_is_focus (plugin
->disassemble
)))
736 address
= dma_disassemble_get_current_address (plugin
->disassemble
);
737 dma_queue_run_from_address (plugin
->queue
, address
);
741 IAnjutaEditor
*editor
;
746 editor
= dma_get_current_editor (ANJUTA_PLUGIN (plugin
));
749 file
= ianjuta_file_get_file (IANJUTA_FILE (editor
), NULL
);
753 filename
= g_file_get_path (file
);
755 line
= ianjuta_editor_get_lineno (editor
, NULL
);
756 dma_queue_run_from (plugin
->queue
, filename
, line
);
758 g_object_unref (file
);
764 on_debugger_interrupt_activate (GtkAction
* action
, DebugManagerPlugin
* plugin
)
767 dma_queue_interrupt (plugin
->queue
);
771 *---------------------------------------------------------------------------*/
774 on_debugger_command_entry_activate (GtkEntry
*entry
, DebugManagerPlugin
*plugin
)
776 const gchar
*command
;
778 command
= gtk_entry_get_text (GTK_ENTRY (entry
));
779 if (command
&& strlen (command
))
780 dma_queue_send_command (plugin
->queue
, command
);
781 gtk_entry_set_text (entry
, "");
785 on_debugger_custom_command_activate (GtkAction
* action
, DebugManagerPlugin
*plugin
)
787 if (plugin
->user_command_dialog
== NULL
)
792 bxml
= anjuta_util_builder_new (GLADE_FILE
, NULL
);
794 anjuta_util_builder_get_objects (bxml
,
795 "debugger_command_dialog", &plugin
->user_command_dialog
,
796 "debugger_command_entry", &entry
,
798 g_object_unref (bxml
);
800 gtk_window_set_transient_for (GTK_WINDOW (plugin
->user_command_dialog
), GTK_WINDOW (ANJUTA_PLUGIN (plugin
)->shell
));
802 g_object_add_weak_pointer (G_OBJECT (plugin
->user_command_dialog
), (gpointer
*)&plugin
->user_command_dialog
);
804 g_signal_connect_swapped (plugin
->user_command_dialog
, "response",
805 G_CALLBACK (gtk_widget_destroy
),
806 plugin
->user_command_dialog
);
807 g_signal_connect (entry
, "activate",
808 G_CALLBACK (on_debugger_command_entry_activate
),
811 gtk_widget_show_all (GTK_WIDGET (plugin
->user_command_dialog
));
815 gtk_window_present (GTK_WINDOW (plugin
->user_command_dialog
));
819 /* Other informations
820 *---------------------------------------------------------------------------*/
823 on_info_memory_activate (GtkAction * action, DebugManagerPlugin *plugin)
825 GtkWidget *win_memory;
827 win_memory = memory_info_new (plugin->debugger,
828 GTK_WINDOW (ANJUTA_PLUGIN (plugin)->shell),
830 gtk_widget_show(win_memory);
834 on_debugger_sharedlibs_activate (GtkAction
* action
, DebugManagerPlugin
*plugin
)
836 sharedlibs_show (plugin
->sharedlibs
);
840 on_debugger_signals_activate (GtkAction
* action
, DebugManagerPlugin
*plugin
)
842 signals_show (plugin
->signals
);
846 *---------------------------------------------------------------------------*/
848 static GtkActionEntry actions_start
[] =
851 "ActionMenuDebug", /* Action name */
852 NULL
, /* Stock icon, if any */
853 N_("_Debug"), /* Display label */
854 NULL
, /* short-cut */
856 NULL
/* action callback */
861 N_("_Start Debugger"),
867 "ActionDebuggerRunTarget",
869 N_("_Debug Program"),
871 N_("Start debugger and load the program"),
872 G_CALLBACK (on_start_debug_activate
)
875 "ActionDebuggerAttachProcess",
877 N_("_Debug Process…"),
879 N_("Start debugger and attach to a running program"),
880 G_CALLBACK (on_attach_to_project_action_activate
)
883 "ActionDebuggerDebugRemote",
884 "debugger-remote-target",
885 N_("Debug _Remote Target…"),
887 N_("Connect to a remote debugging target"),
888 G_CALLBACK (on_start_remote_debug_action_activate
),
891 "ActionDebuggerStop",
895 N_("Say goodbye to the debugger"),
896 G_CALLBACK (on_debugger_stop_activate
)
899 "ActionDebuggerAddSource",
901 N_("Add source paths…"),
903 N_("Add additional source paths"),
904 G_CALLBACK (on_add_source_activate
)
908 static GtkActionEntry actions_loaded
[] =
911 "ActionGdbCommand", /* Action name */
912 NULL
, /* Stock icon, if any */
913 N_("Debugger Command…"), /* Display label */
914 NULL
, /* short-cut */
915 N_("Custom debugger command"), /* Tooltip */
916 G_CALLBACK (on_debugger_custom_command_activate
) /* action callback */
919 "ActionMenuGdbInformation",
927 "ActionGdbViewSharedlibs",
929 N_("Shared Libraries"),
931 N_("Show shared library mappings"),
932 G_CALLBACK (on_debugger_sharedlibs_activate
)
935 "ActionGdbViewSignals",
937 N_("Kernel Signals"),
939 N_("Show kernel signals"),
940 G_CALLBACK (on_debugger_signals_activate
)
943 "ActionDebuggerContinueSuspend",
944 GTK_STOCK_MEDIA_PLAY
,
945 N_("_Continue/Suspend"),
947 N_("Continue or suspend the execution of the program"),
948 G_CALLBACK (on_continue_suspend_action_activate
)
952 static GtkActionEntry actions_stopped
[] =
955 "ActionDebuggerRunContinue", /* Action name */
956 GTK_STOCK_MEDIA_PLAY
, /* 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",
967 N_("Single step into function"),
968 G_CALLBACK (on_step_in_action_activate
)
971 "ActionDebuggerStepOver",
972 "debugger-step-over",
975 N_("Single step over function"),
976 G_CALLBACK (on_step_over_action_activate
)
979 "ActionDebuggerStepOut",
983 N_("Single step out of function"),
984 G_CALLBACK (on_step_out_action_activate
)
987 "ActionDebuggerRunToPosition",
988 "debugger-run-to-cursor",
989 N_("_Run to Cursor"),
991 N_("Run to the cursor"),
992 G_CALLBACK (on_run_to_cursor_action_activate
)
995 "ActionDebuggerRunFromPosition",
996 "debugger-run-from-cursor",
997 N_("_Run from Cursor"),
999 N_("Run from the cursor"),
1000 G_CALLBACK (on_run_from_cursor_action_activate
)
1005 N_("Debugger Command…"),
1007 N_("Custom debugger command"),
1008 G_CALLBACK (on_debugger_custom_command_activate
)
1011 "ActionMenuGdbInformation",
1019 "ActionGdbViewSharedlibs",
1021 N_("Shared Libraries"),
1023 N_("Show shared library mappings"),
1024 G_CALLBACK (on_debugger_sharedlibs_activate
)
1027 "ActionGdbViewSignals",
1029 N_("Kernel Signals"),
1031 N_("Show kernel signals"),
1032 G_CALLBACK (on_debugger_signals_activate
)
1036 static GtkActionEntry actions_running
[] =
1039 "ActionGdbPauseProgram", /* Action name */
1040 GTK_STOCK_MEDIA_PAUSE
, /* Stock icon, if any */
1041 N_("Pa_use Program"), /* Display label */
1042 NULL
, /* short-cut */
1043 N_("Pauses the execution of the program"), /* Tooltip */
1044 G_CALLBACK (on_debugger_interrupt_activate
) /* action callback */
1048 /* AnjutaPlugin functions
1049 *---------------------------------------------------------------------------*/
1052 dma_plugin_activate (AnjutaPlugin
* plugin
)
1054 DebugManagerPlugin
*this;
1055 static gboolean initialized
= FALSE
;
1058 DEBUG_PRINT ("%s", "DebugManagerPlugin: Activating Debug Manager plugin…");
1059 this = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin
);
1064 register_stock_icons (ANJUTA_PLUGIN (plugin
));
1068 this->queue
= dma_debugger_queue_new (plugin
);
1069 g_signal_connect (this, "debugger-started", G_CALLBACK (dma_plugin_debugger_started
), this);
1070 g_signal_connect (this, "debugger-stopped", G_CALLBACK (dma_plugin_debugger_stopped
), this);
1071 g_signal_connect (this, "program-loaded", G_CALLBACK (dma_plugin_program_loaded
), this);
1072 g_signal_connect (this, "program-running", G_CALLBACK (dma_plugin_program_running
), this);
1073 g_signal_connect (this, "program-stopped", G_CALLBACK (dma_plugin_program_stopped
), this);
1074 g_signal_connect (this, "program-exited", G_CALLBACK (dma_plugin_program_loaded
), this);
1075 g_signal_connect (this, "program-moved", G_CALLBACK (dma_plugin_program_moved
), this);
1076 g_signal_connect (this, "signal-received", G_CALLBACK (dma_plugin_signal_received
), this);
1077 g_signal_connect (this, "location-changed", G_CALLBACK (dma_plugin_location_changed
), this);
1079 /* Add all our debug manager actions */
1080 ui
= anjuta_shell_get_ui (ANJUTA_PLUGIN (plugin
)->shell
, NULL
);
1082 anjuta_ui_add_action_group_entries (ui
, "ActionGroupDebugStart",
1083 _("Debugger operations"),
1085 G_N_ELEMENTS (actions_start
),
1086 GETTEXT_PACKAGE
, TRUE
, this);
1087 this->loaded_group
=
1088 anjuta_ui_add_action_group_entries (ui
, "ActionGroupDebugLoaded",
1089 _("Debugger operations"),
1091 G_N_ELEMENTS (actions_loaded
),
1092 GETTEXT_PACKAGE
, TRUE
, this);
1093 this->stopped_group
=
1094 anjuta_ui_add_action_group_entries (ui
, "ActionGroupDebugStopped",
1095 _("Debugger operations"),
1097 G_N_ELEMENTS (actions_stopped
),
1098 GETTEXT_PACKAGE
, TRUE
, this);
1099 this->running_group
=
1100 anjuta_ui_add_action_group_entries (ui
, "ActionGroupDebugRunning",
1101 _("Debugger operations"),
1103 G_N_ELEMENTS (actions_running
),
1104 GETTEXT_PACKAGE
, TRUE
, this);
1105 this->uiid
= anjuta_ui_merge (ui
, UI_FILE
);
1107 /* Get run_stop_action */
1108 this->run_stop_action
= anjuta_ui_get_action (ui
, "ActionGroupDebugLoaded", "ActionDebuggerContinueSuspend");
1111 this->variable
= dma_variable_dbase_new (this);
1114 this->stack
= stack_trace_new (this);
1116 /* Create breakpoints list */
1117 this->breakpoints
= breakpoints_dbase_new (this);
1120 this->registers
= cpu_registers_new (this);
1123 this->memory
= dma_memory_new (this);
1125 /* Disassembly window */
1126 this->disassemble
= dma_disassemble_new (this);
1128 /* Start debugger part */
1129 this->start
= dma_start_new (this);
1131 /* Shared libraries part */
1132 this->sharedlibs
= sharedlibs_new (this);
1135 this->signals
= signals_new (this);
1137 dma_plugin_debugger_stopped (this, 0);
1140 this->project_watch_id
=
1141 anjuta_plugin_add_watch (plugin
, IANJUTA_PROJECT_MANAGER_PROJECT_ROOT_URI
,
1142 value_added_project_root_uri
,
1143 value_removed_project_root_uri
, NULL
);
1144 this->editor_watch_id
=
1145 anjuta_plugin_add_watch (plugin
, IANJUTA_DOCUMENT_MANAGER_CURRENT_DOCUMENT
,
1146 value_added_current_editor
,
1147 value_removed_current_editor
, NULL
);
1149 /* Connect to save session */
1150 g_signal_connect (G_OBJECT (plugin
->shell
), "save_session",
1151 G_CALLBACK (on_session_save
), plugin
);
1157 dma_plugin_deactivate (AnjutaPlugin
* plugin
)
1159 DebugManagerPlugin
*this;
1162 DEBUG_PRINT ("%s", "DebugManagerPlugin: Deactivating Debug Manager plugin…");
1164 this = ANJUTA_PLUGIN_DEBUG_MANAGER (plugin
);
1167 dma_plugin_debugger_stopped (this, 0);
1169 g_signal_handlers_disconnect_by_func (plugin
->shell
, G_CALLBACK (on_session_save
), plugin
);
1170 g_signal_handlers_disconnect_matched (plugin
, G_SIGNAL_MATCH_DATA
, 0, 0, NULL
, NULL
, plugin
);
1172 anjuta_plugin_remove_watch (plugin
, this->project_watch_id
, FALSE
);
1173 anjuta_plugin_remove_watch (plugin
, this->editor_watch_id
, FALSE
);
1175 dma_debugger_queue_free (this->queue
);
1178 ui
= anjuta_shell_get_ui (plugin
->shell
, NULL
);
1179 anjuta_ui_unmerge (ui
, this->uiid
);
1181 dma_variable_dbase_free (this->variable
);
1182 this->variable
= NULL
;
1184 breakpoints_dbase_destroy (this->breakpoints
);
1185 this->breakpoints
= NULL
;
1187 stack_trace_free (this->stack
);
1190 cpu_registers_free (this->registers
);
1191 this->registers
= NULL
;
1193 dma_memory_free (this->memory
);
1194 this->memory
= NULL
;
1196 dma_disassemble_free (this->disassemble
);
1197 this->disassemble
= NULL
;
1199 dma_start_free (this->start
);
1202 sharedlibs_free (this->sharedlibs
);
1203 this->sharedlibs
= NULL
;
1205 signals_free (this->signals
);
1206 this->signals
= NULL
;
1208 ui
= anjuta_shell_get_ui (ANJUTA_PLUGIN (this)->shell
, NULL
);
1209 anjuta_ui_remove_action_group (ui
, this->start_group
);
1210 anjuta_ui_remove_action_group (ui
, this->loaded_group
);
1211 anjuta_ui_remove_action_group (ui
, this->stopped_group
);
1212 anjuta_ui_remove_action_group (ui
, this->running_group
);
1214 if (this->view
!= NULL
)
1216 g_object_remove_weak_pointer (G_OBJECT (this->view
), (gpointer
*)(gpointer
)&this->view
);
1224 *---------------------------------------------------------------------------*/
1227 dma_debug_manager_get_queue (DebugManagerPlugin
*self
)
1232 /* GObject functions
1233 *---------------------------------------------------------------------------*/
1235 /* Used in dispose and finalize */
1236 static gpointer parent_class
;
1238 /* instance_init is the constructor. All functions should work after this
1242 dma_plugin_instance_init (GObject
* obj
)
1244 DebugManagerPlugin
*plugin
= ANJUTA_PLUGIN_DEBUG_MANAGER (obj
);
1248 plugin
->project_root_uri
= NULL
;
1249 plugin
->queue
= NULL
;
1250 plugin
->current_editor
= NULL
;
1251 plugin
->pc_editor
= NULL
;
1252 plugin
->editor_watch_id
= 0;
1253 plugin
->project_watch_id
= 0;
1254 plugin
->breakpoints
= NULL
;
1255 plugin
->registers
= NULL
;
1256 plugin
->signals
= NULL
;
1257 plugin
->sharedlibs
= NULL
;
1258 plugin
->view
= NULL
;
1260 plugin
->user_command_dialog
= NULL
;
1262 /* plugin->uri = NULL; */
1265 /* dispose is the first destruction step. It is used to unref object created
1266 * with instance_init in order to break reference counting cycles. This
1267 * function could be called several times. All function should still work
1268 * after this call. It has to called its parents.*/
1271 dma_plugin_dispose (GObject
* obj
)
1273 DebugManagerPlugin
*plugin
= ANJUTA_PLUGIN_DEBUG_MANAGER (obj
);
1275 if (plugin
->user_command_dialog
!= NULL
) gtk_widget_destroy (GTK_WIDGET (plugin
->user_command_dialog
));
1277 G_OBJECT_CLASS (parent_class
)->dispose (obj
);
1280 /* finalize is the last destruction step. It must free all memory allocated
1281 * with instance_init. It is called only one time just before releasing all
1285 dma_plugin_finalize (GObject
* obj
)
1287 DebugManagerPlugin
*self
= ANJUTA_PLUGIN_DEBUG_MANAGER (obj
);
1289 if (self
->pc_editor
!= NULL
)
1291 g_object_remove_weak_pointer (G_OBJECT (self
->pc_editor
), (gpointer
*)(gpointer
)&self
->pc_editor
);
1293 if (self
->current_editor
!= NULL
)
1295 g_object_remove_weak_pointer (G_OBJECT (self
->current_editor
), (gpointer
*)(gpointer
)&self
->current_editor
);
1298 G_OBJECT_CLASS (parent_class
)->finalize (obj
);
1301 /* class_init intialize the class itself not the instance */
1304 dma_plugin_class_init (GObjectClass
* klass
)
1306 AnjutaPluginClass
*plugin_class
= ANJUTA_PLUGIN_CLASS (klass
);
1308 parent_class
= g_type_class_peek_parent (klass
);
1310 plugin_class
->activate
= dma_plugin_activate
;
1311 plugin_class
->deactivate
= dma_plugin_deactivate
;
1312 klass
->dispose
= dma_plugin_dispose
;
1313 klass
->finalize
= dma_plugin_finalize
;
1316 /* Implementation of IAnjutaDebugManager interface
1317 *---------------------------------------------------------------------------*/
1320 idebug_manager_start (IAnjutaDebugManager
*plugin
, const gchar
*uri
, GError
**err
)
1322 DebugManagerPlugin
*self
= ANJUTA_PLUGIN_DEBUG_MANAGER (plugin
);
1324 return dma_run_target (self
->start
, uri
);
1328 idebug_manager_start_remote (IAnjutaDebugManager
*plugin
, const gchar
*server
, const gchar
*uri
, GError
**err
)
1330 DebugManagerPlugin
*self
= ANJUTA_PLUGIN_DEBUG_MANAGER (plugin
);
1332 return dma_run_remote_target (self
->start
, server
, uri
);
1336 idebug_manager_quit (IAnjutaDebugManager
*plugin
, GError
**err
)
1338 DebugManagerPlugin
*self
= ANJUTA_PLUGIN_DEBUG_MANAGER (plugin
);
1340 return dma_quit_debugger (self
->start
);
1344 idebug_manager_iface_init (IAnjutaDebugManagerIface
*iface
)
1346 iface
->start
= idebug_manager_start
;
1347 iface
->start_remote
= idebug_manager_start_remote
;
1348 iface
->quit
= idebug_manager_quit
;
1351 ANJUTA_PLUGIN_BEGIN (DebugManagerPlugin
, dma_plugin
);
1352 ANJUTA_PLUGIN_ADD_INTERFACE(idebug_manager
, IANJUTA_TYPE_DEBUG_MANAGER
);
1355 ANJUTA_SIMPLE_PLUGIN (DebugManagerPlugin
, dma_plugin
);