[nemiver/follow-fork-mode: 9/35] ASM <-> Source code switching preliminary support
- From: Dodji Seketeli <dodji src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nemiver/follow-fork-mode: 9/35] ASM <-> Source code switching preliminary support
- Date: Thu, 6 May 2010 10:16:51 +0000 (UTC)
commit e1a2f33d92669d54c95a062427a0ae29616cc39c
Author: Dodji Seketeli <dodji redhat com>
Date: Sun Mar 7 21:02:08 2010 +0100
ASM <-> Source code switching preliminary support
Preliminary support to switch from source code view to assembly
view and backward. Neiher decorating nor stepping is supported
in the assembly view yet.
* src/uicommon/nmv-source-editor.h (clear_decorations): New
interface.
(SourceEditor::*): Renamed all methods that had "composite" in
their names into method that have "assembly" in their name
instead.
* src/uicommon/nmv-source-editor.cc (*):
Same similar renaming as above.
Go further by renaming members that have "comp" in their names
by members that have "asm" in their names instead.
(SourceEditor::clear_decorations): New definition.
* src/persp/dbgperspective/nmv-dbg-perspective.cc
(DBGPerspective::on_disassemble_action,
DBGPerspective::on_switch_to_disassembly_action,
DBGPerspective::on_debugger_disassembled_signal,
DBGPerspective::switch_to_disassembly,
DBGPerspective::switch_to_source_code,
DBGPerspective::disassemble,
DBGPerspective::find_absolute_path_or_ask_user,
DBGPerspective::remove_visual_decorations_from_text): New fns
declarations and definitions.
(DBGPerspective::find_absolute_path,
DBGPerspective::ask_user_to_select_file): Extract these
functions from DBGPerspective::append_visual_breakpoint.
(DBGPerspective::append_visual_breakpoint): Use the new
DBGPerspective::find_absolute_path and
DBGPerspective::ask_user_to_select_file.
(DBGPerspective::init_actions): Add menu actions DisAsmMenuItemAction,
SwitchToAsmMenuItemAction, SwitchToSourceMenuItemAction. Used
the new DBGPerspective::on_disassemble_action, and
DBGPerspective::switch_to_source_code as the callbacks for this
menu actions.
(DBGPerspective::open_disassembly): If the disassembly tab
exists already, re-use it.
(DBGPerspective::open_file): Don't yell if the file path is empty.
* src/persp/dbgperspective/menus/menus.xml: Add new "Show assembly",
"Switch to assembly" and "Switch to source" menu items to the
"debug" menu.
src/persp/dbgperspective/menus/menus.xml | 6 +
src/persp/dbgperspective/nmv-dbg-perspective.cc | 435 +++++++++++++++++------
src/uicommon/nmv-source-editor.cc | 180 ++++++----
src/uicommon/nmv-source-editor.h | 29 +-
4 files changed, 451 insertions(+), 199 deletions(-)
---
diff --git a/src/persp/dbgperspective/menus/menus.xml b/src/persp/dbgperspective/menus/menus.xml
index 75967c5..ccdb2f1 100644
--- a/src/persp/dbgperspective/menus/menus.xml
+++ b/src/persp/dbgperspective/menus/menus.xml
@@ -85,6 +85,12 @@
name="ActivateGlobalVariablesDialogMenuItem"/>
<menuitem action="RefreshLocalVariablesMenuItemAction"
name="RefreshLocalVariablesMenuItemAction"/>
+ <menuitem action="DisAsmMenuItemAction"
+ name="DisAsmMenuItemAction"/>
+ <menuitem action="SwitchToAsmMenuItemAction"
+ name="SwitchToAsmMenuItemAction"/>
+ <menuitem action="SwitchToSourceMenuItemAction"
+ name="SwitchToSourceMenuItemAction"/>
</menu>
</placeholder>
</menubar>
diff --git a/src/persp/dbgperspective/nmv-dbg-perspective.cc b/src/persp/dbgperspective/nmv-dbg-perspective.cc
index f4441b3..3bb46b9 100644
--- a/src/persp/dbgperspective/nmv-dbg-perspective.cc
+++ b/src/persp/dbgperspective/nmv-dbg-perspective.cc
@@ -132,6 +132,8 @@ const char *LAST_RUN_TIME= "lastruntime";
const char *DBG_PERSPECTIVE_MOUSE_MOTION_DOMAIN =
"dbg-perspective-mouse-motion-domain";
+static const int NUM_INSTR_TO_DISASSEMBLE = 20;
+
const char* CONF_KEY_NEMIVER_SOURCE_DIRS =
"/apps/nemiver/dbgperspective/source-search-dirs";
const char* CONF_KEY_SHOW_DBG_ERROR_DIALOGS =
@@ -279,6 +281,8 @@ private:
void on_set_breakpoint_using_dialog_action ();
void on_set_watchpoint_using_dialog_action ();
void on_refresh_locals_action ();
+ void on_disassemble_action (bool a_show_asm_in_new_tab);
+ void on_switch_to_disassembly_action ();
void on_toggle_breakpoint_action ();
void on_toggle_breakpoint_enabled_action ();
void on_inspect_variable_action ();
@@ -321,6 +325,7 @@ private:
void on_insertion_changed_signal (const Gtk::TextBuffer::iterator& iter,
SourceEditor *a_editor);
+
void update_toggle_menu_text (const UString& a_current_file,
int a_current_line);
@@ -340,7 +345,7 @@ private:
void on_debugger_detached_from_target_signal ();
void on_debugger_got_target_info_signal (int a_pid,
- const UString &a_exe_path);
+ const UString &a_exe_path);
void on_debugger_console_message_signal (const UString &a_msg);
@@ -387,6 +392,10 @@ private:
(const UString &a_var_name,
const IDebugger::VariableSafePtr &a_var,
const UString &a_cooker);
+ void on_debugger_disassembled_signal
+ (const IDebugger::DisassembleInfo &a_info,
+ const std::list<IDebugger::AsmInstr> &a_instrs,
+ bool a_show_asm_in_new_tab = true);
void on_variable_created_for_tooltip_signal
(const IDebugger::VariableSafePtr);
@@ -523,6 +532,11 @@ public:
bool open_disassembly (const IDebugger::DisassembleInfo &a_info,
const std::list<IDebugger::AsmInstr> &a_asm);
+ void switch_to_disassembly (const IDebugger::DisassembleInfo &a_info,
+ const std::list<IDebugger::AsmInstr> &a_asm);
+
+ void switch_to_source_code ();
+
void close_opened_files ();
void update_file_maps ();
@@ -606,6 +620,7 @@ public:
void set_breakpoint_from_dialog (SetBreakpointDialog &a_dialog);
void set_watchpoint_using_dialog ();
void refresh_locals ();
+ void disassemble (bool a_show_asm_in_new_tab);
void inspect_variable ();
void inspect_variable (const UString &a_variable_name);
@@ -615,7 +630,15 @@ public:
void toggle_breakpoint_enabled (const UString &a_file_path,
int a_linenum);
void toggle_breakpoint_enabled ();
+
void update_src_dependant_bp_actions_sensitiveness ();
+
+ bool find_absolute_path (const UString& a_file_path,
+ UString& a_absolute_path);
+ bool find_absolute_path_or_ask_user (const UString& a_file_path,
+ UString& a_absolute_path);
+ bool ask_user_to_select_file (const UString &a_file_name,
+ UString& a_selected_file_path);
bool append_visual_breakpoint (const UString &a_file_name,
int a_linenum,
UString &a_actual_file_name,
@@ -628,6 +651,7 @@ public:
void choose_function_overload
(const vector<IDebugger::OverloadsChoiceEntry> &a_entries);
+ void remove_visual_decorations_from_text (const UString &a_file_path);
bool apply_decorations_to_text (const UString &a_file_path);
IDebuggerSafePtr& debugger ();
@@ -1494,6 +1518,23 @@ DBGPerspective::on_refresh_locals_action ()
}
void
+DBGPerspective::on_disassemble_action (bool a_show_asm_in_new_tab)
+{
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+ NEMIVER_TRY
+ disassemble (a_show_asm_in_new_tab);
+ NEMIVER_CATCH
+}
+
+void
+DBGPerspective::on_switch_to_disassembly_action ()
+{
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+ NEMIVER_TRY
+ NEMIVER_CATCH
+}
+
+void
DBGPerspective::on_toggle_breakpoint_enabled_action ()
{
LOG_FUNCTION_SCOPE_NORMAL_DD;
@@ -2570,6 +2611,20 @@ DBGPerspective::on_debugger_variable_value_signal
}
void
+DBGPerspective::on_debugger_disassembled_signal
+ (const IDebugger::DisassembleInfo &a_info,
+ const std::list<IDebugger::AsmInstr> &a_instrs,
+ bool a_show_asm_in_new_tab)
+{
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+ if (a_show_asm_in_new_tab)
+ open_disassembly (a_info, a_instrs);
+ else
+ switch_to_disassembly (a_info, a_instrs);
+}
+
+void
DBGPerspective::on_variable_created_for_tooltip_signal
(const IDebugger::VariableSafePtr a_var)
{
@@ -3195,7 +3250,43 @@ DBGPerspective::init_actions ()
ActionEntry::DEFAULT,
"",
false
- }
+ },
+ {
+ "DisAsmMenuItemAction",
+ nil_stock_id,
+ _("Show assembly"),
+ _("Show the assembly code of the source code being "
+ "currently debugged, in another tab"),
+ sigc::bind (sigc::mem_fun
+ (*this, &DBGPerspective::on_disassemble_action),
+ /*show_asm_in_new_tab=*/true),
+ ActionEntry::DEFAULT,
+ "",
+ false
+ },
+ {
+ "SwitchToAsmMenuItemAction",
+ nil_stock_id,
+ _("Switch to assembly"),
+ _("Show the assembly code of the source code being "
+ "currently debugged"),
+ sigc::bind (sigc::mem_fun
+ (*this, &DBGPerspective::on_disassemble_action),
+ /*show_asm_in_new_tab=*/false),
+ ActionEntry::DEFAULT,
+ "",
+ false
+ },
+ {
+ "SwitchToSourceMenuItemAction",
+ nil_stock_id,
+ _("Switch to source"),
+ _("Show the source code being currently debugged"),
+ sigc::mem_fun (*this, &DBGPerspective::switch_to_source_code),
+ ActionEntry::DEFAULT,
+ "",
+ false
+ },
};
static ui_utils::ActionEntry s_debugger_busy_action_entries [] = {
@@ -3777,6 +3868,39 @@ DBGPerspective::clear_session_data ()
m_priv->source_dirs.clear ();
}
+bool
+DBGPerspective::find_absolute_path (const UString& a_file_path,
+ UString &a_absolute_path)
+{
+ // First, assume it's a full path name already.
+ if (Glib::file_test (a_file_path, Glib::FILE_TEST_IS_REGULAR)) {
+ a_absolute_path = a_file_path;
+ return true;
+ }
+ // If that didn't work, look for a file of that name in the search
+ // directories.
+ if (find_file_in_source_dirs (a_file_path, a_absolute_path)) {
+ return true;
+ }
+ return false;
+}
+
+bool
+DBGPerspective::find_absolute_path_or_ask_user (const UString& a_file_path,
+ UString& a_absolute_path)
+{
+ if (!find_absolute_path (a_file_path, a_absolute_path)) {
+ if (ask_user_to_select_file (a_file_path, a_absolute_path)) {
+ UString parent_dir = Glib::filename_to_utf8
+ (Glib::path_get_dirname (a_absolute_path));
+ m_priv->search_paths.push_back (parent_dir);
+ } else {
+ return false;
+ }
+ }
+ return true;
+}
+
void
DBGPerspective::append_source_editor (SourceEditor &a_sv,
const UString &a_path)
@@ -4893,6 +5017,9 @@ DBGPerspective::get_file_mime_type (const UString &a_path,
NEMIVER_CATCH_AND_RETURN (false)
}
+// Make sure the source buffer a_buf is properly setup to have the mime
+// type a_mime_type. If a_buf is null, a new one is created.
+// Returns true upon successful completion, false otherwise.
bool
DBGPerspective::setup_buffer_mime_and_lang (Glib::RefPtr<SourceBuffer> &a_buf,
const std::string &a_mime_type)
@@ -5051,7 +5178,7 @@ DBGPerspective::create_source_editor (Glib::RefPtr<SourceBuffer> &a_source_buf,
a_source_buf,
true));
if (!a_current_address.empty ()) {
- source_editor->composite_buf_loc_to_line (a_current_address.raw (),
+ source_editor->assembly_buf_loc_to_line (a_current_address.raw (),
current_line);
}
} else {
@@ -5142,7 +5269,8 @@ DBGPerspective::open_file (const UString &a_path,
int a_current_line)
{
RETURN_VAL_IF_FAIL (m_priv, false);
- RETURN_VAL_IF_FAIL (!a_path.empty (), false);
+ if (a_path.empty ())
+ return false;
if (get_source_editor_from_path (a_path)) {return true;}
@@ -5280,6 +5408,11 @@ DBGPerspective::load_disassembly (const IDebugger::DisassembleInfo &/*a_info*/,
NEMIVER_CATCH_AND_RETURN (false)
}
+// If new disassembly dedicated tab was already present in the perspective,
+// create a new one, otherwise, reuse the one that was already present.
+// Then load the assembly insns a_asm described by a_info into the
+// source buffer of the disassembly tab.
+// Return true upon successful completion, false otherwise.
bool
DBGPerspective::open_disassembly (const IDebugger::DisassembleInfo &a_info,
const std::list<IDebugger::AsmInstr> &a_asm)
@@ -5289,25 +5422,108 @@ DBGPerspective::open_disassembly (const IDebugger::DisassembleInfo &a_info,
NEMIVER_TRY
Glib::RefPtr<SourceBuffer> source_buffer;
+
+ SourceEditor *source_editor =
+ get_source_editor_from_path (get_disassembly_title ());
+
+ if (source_editor) {
+ source_buffer = source_editor->source_view ().get_source_buffer ();
+ source_buffer->erase (source_buffer->begin (), source_buffer->end ());
+ }
if (!load_disassembly (a_info, a_asm, source_buffer)) {
return false;
}
-
- SourceEditor *source_editor =
- create_source_editor (source_buffer,
- /*a_disassembly_view=*/true,
- get_disassembly_title (),
- -1,
- /*a_current_address=*/"");
- THROW_IF_FAIL (source_editor);
- source_editor->show_all ();
- append_source_editor (*source_editor, get_disassembly_title ());
+ if (!source_editor) {
+ source_editor =
+ create_source_editor (source_buffer,
+ /*a_disassembly_view=*/true,
+ get_disassembly_title (),
+ -1,
+ /*a_current_address=*/"");
+ THROW_IF_FAIL (source_editor);
+ source_editor->show_all ();
+ append_source_editor (*source_editor, get_disassembly_title ());
+ }
NEMIVER_CATCH_AND_RETURN (false);
return true;
}
+// Get the source editor of the source file being currently debugged,
+// switch it into the disassembly mode and load the asm insns
+// represented by a_info and a_asm into its source buffer.
+// \param a_info descriptor of the assembly instructions
+// \param a_asm a list of asm instructions.
+void
+DBGPerspective::switch_to_disassembly
+ (const IDebugger::DisassembleInfo &a_info,
+ const std::list<IDebugger::AsmInstr> &a_asm)
+{
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+ SourceEditor *source_editor = get_current_source_editor ();
+ if (source_editor == 0)
+ return;
+
+ Glib::RefPtr<SourceBuffer> asm_buf;
+ if ((asm_buf = source_editor->get_assembly_source_buffer ()) == 0) {
+ setup_buffer_mime_and_lang (asm_buf, "test/x-asm");
+ source_editor->register_assembly_source_buffer (asm_buf);
+ asm_buf = source_editor->get_assembly_source_buffer ();
+ RETURN_IF_FAIL (asm_buf);
+ }
+ if (!load_disassembly (a_info, a_asm, asm_buf)) {
+ LOG_ERROR ("failed to load asm");
+ return;
+ }
+ if (!source_editor->switch_to_assembly_source_buffer ()) {
+ LOG_ERROR ("Could not switch the current view to asm");
+ }
+}
+
+// Get the source editor of the source file being currently debugged,
+// switch it into the source code mode. If necessary, (re) load the
+// source code.
+void
+DBGPerspective::switch_to_source_code ()
+{
+ SourceEditor *source_editor = get_current_source_editor ();
+ if (source_editor == 0)
+ return;
+ Glib::RefPtr<SourceBuffer> source_buf;
+ UString source_path;
+ if ((source_buf = source_editor->get_non_assembly_source_buffer ()) == 0) {
+ // Woops!
+ // We don't have any source code buffer. Let's try hard to get
+ // the source code corresponding to the current frame. For that,
+ // we'll hope to have proper debug info for the binary being
+ // debugged, and the source code available on disk.
+ if (m_priv->current_frame.address ().empty ()) {
+ LOG_DD ("No current instruction pointer");
+ return;
+ }
+ if (m_priv->current_frame.file_name ().empty ()) {
+ LOG_DD ("No file name information for current frame");
+ return;
+ }
+ UString absolute_path, mime_type;
+ if (!find_absolute_path_or_ask_user (m_priv->current_frame.file_name (),
+ absolute_path)) {
+ LOG_DD ("Could not find file: "
+ << m_priv->current_frame.file_name ());
+ return;
+ }
+ get_file_mime_type (absolute_path, mime_type);
+ setup_buffer_mime_and_lang (source_buf, mime_type);
+ load_file (absolute_path, source_buf);
+ source_editor->register_non_assembly_source_buffer (source_buf);
+ }
+ source_editor->switch_to_non_assembly_source_buffer ();
+ source_editor->get_path (source_path);
+ apply_decorations_to_text (source_path);
+}
+
Gtk::Widget*
DBGPerspective::load_menu (const UString &a_filename,
const UString &a_widget_name)
@@ -6156,10 +6372,42 @@ DBGPerspective::append_visual_breakpoint (const UString &a_file_name,
actual_file_path, enabled);
}
+// Popup a dialog asking the user to select the file a_file_name.
+// \param a_file_name the name of the file we want the user to select.
+// \param a_selected_file_path the path to the file the user actually
+// selected.
+// \return true if the user really selected the file we wanted, false
+// otherwise.
+bool
+DBGPerspective::ask_user_to_select_file (const UString &a_file_name,
+ UString &a_selected_file_path)
+{
+ LocateFileDialog dialog (plugin_path (), a_file_name);
+ // start looking in the working directory
+ dialog.file_location (m_priv->prog_cwd);
+ int result = dialog.run ();
+ if (result == Gtk::RESPONSE_OK) {
+ UString file_path = dialog.file_location ();
+ if (!Glib::file_test (file_path, Glib::FILE_TEST_IS_REGULAR)
+ || (Glib::path_get_basename (a_file_name)
+ != Glib::path_get_basename (file_path)))
+ return false;
+ UString parent_dir =
+ Glib::filename_to_utf8 (Glib::path_get_dirname
+ (dialog.file_location ()));
+ if (!Glib::file_test (parent_dir, Glib::FILE_TEST_IS_DIR))
+ return false;
+
+ a_selected_file_path = file_path;
+ return true;
+ }
+ return false;
+}
+
bool
DBGPerspective::append_visual_breakpoint (const UString &a_file_name,
int a_linenum,
- UString &a_actual_file_name,
+ UString &a_actual_file_path,
bool enabled)
{
if (a_file_name.empty()) {
@@ -6174,105 +6422,32 @@ DBGPerspective::append_visual_breakpoint (const UString &a_file_name,
if (a_linenum < 0) {a_linenum = 0;}
- UString actual_file_name;
+ UString actual_file_path;
SourceEditor *source_editor =
get_source_editor_from_path (a_file_name,
- actual_file_name);
- //first assume that it's a full pathname and just try to open it
- if (!source_editor) {
- if (Glib::file_test (a_file_name, Glib::FILE_TEST_IS_REGULAR)) {
- if (!open_file (a_file_name)) {
- UString msg;
- msg.printf (_("Failed to open file %s. "
- "Would you like to open another file which "
- "would have the same content ?"),
- a_file_name.c_str ());
- if (ui_utils::ask_yes_no_question (msg)
- == Gtk::RESPONSE_YES) {
- LocateFileDialog dialog (plugin_path (), a_file_name);
- dialog.file_location (m_priv->prog_cwd);
- int result = dialog.run ();
- if (result == Gtk::RESPONSE_OK) {
- UString file_path = dialog.file_location ();
- THROW_IF_FAIL (Glib::file_test (file_path,
- Glib::FILE_TEST_IS_REGULAR));
- std::string raw_dir = Glib::path_get_dirname
- (dialog.file_location ());
- UString parent_dir = Glib::filename_to_utf8 (raw_dir);
- THROW_IF_FAIL (Glib::file_test (raw_dir,
- Glib::FILE_TEST_IS_DIR));
- m_priv->search_paths.push_back (parent_dir);
- if (!open_file (file_path)) {
- return false;
- }
- source_editor =
- get_source_editor_from_path (file_path,
- actual_file_name);
- } else {
- return false;
- }
- } else {
- return false;
- }
+ actual_file_path);
+ if (source_editor == 0) {
+ if (!find_absolute_path (a_file_name, actual_file_path)) {
+ if (ask_user_to_select_file (a_file_name, actual_file_path)) {
+ UString parent_dir =
+ Glib::filename_to_utf8
+ (Glib::path_get_dirname (actual_file_path));
+ m_priv->search_paths.push_back (parent_dir);
}
- source_editor = get_source_editor_from_path (a_file_name,
- actual_file_name);
}
- }
- //if that didn't work, look for an opened source editor
- //that matches the base name
- if (!source_editor) {
+ open_file (actual_file_path);
source_editor = get_source_editor_from_path (a_file_name,
- actual_file_name,
- true);
+ actual_file_path);
}
- //if that still didn't work, look for a file of that name in the search
- //directories and then as a last resort ask the user to locate it
- //manually
- if (!source_editor) {
- UString file_path;
- if (!find_file_in_source_dirs (a_file_name, file_path)) {
- LOG_DD ("didn't find file either in opened files "
- " or in source dirs:");
- //Pop up a dialog asking user to select the specified file
- LocateFileDialog dialog (plugin_path (), a_file_name);
- //start looking in the working directory
- dialog.file_location (m_priv->prog_cwd);
- int result = dialog.run ();
- if (result == Gtk::RESPONSE_OK) {
- file_path = dialog.file_location ();
- THROW_IF_FAIL (Glib::file_test (file_path,
- Glib::FILE_TEST_IS_REGULAR));
- THROW_IF_FAIL (Glib::path_get_basename(a_file_name) ==
- Glib::path_get_basename(file_path));
- UString parent_dir = Glib::filename_to_utf8
- (Glib::path_get_dirname (dialog.file_location ()));
- THROW_IF_FAIL (Glib::file_test
- (parent_dir, Glib::FILE_TEST_IS_DIR));
-
- //Also add the parent directory to the list
- //of paths to search for this session so
- //you don't have to keep selecting files if
- //they're all in the same directory.
- //We can assume that the parent
- //directory is not already in the
- //list of source dirs
- //(or else it would have been found and the
- //user wouldn't have had to locate it manually)
- //so just stack it
- //on the end of the list
- m_priv->search_paths.push_back (parent_dir);
- }
- }
-
- if (!file_path.empty ()) {
- open_file (file_path);
- source_editor = get_source_editor_from_path (file_path,
- actual_file_name);
- }
+ // if that didn't work, look for an opened source editor
+ // that matches the base name
+ if (source_editor == 0) {
+ source_editor = get_source_editor_from_path (a_file_name,
+ actual_file_path,
+ /*basename_only=*/true);
}
- //finally, if none of these things worked, display an error
+ // finally, if none of these things worked, display an error
if (!source_editor) {
LOG_ERROR ("Could not find source editor for file: '"
<< a_file_name
@@ -6283,7 +6458,7 @@ DBGPerspective::append_visual_breakpoint (const UString &a_file_name,
source_editor->set_visual_breakpoint_at_line (a_linenum, enabled);
}
- a_actual_file_name = actual_file_name;
+ a_actual_file_path = actual_file_path;
return true;
}
@@ -6350,6 +6525,16 @@ DBGPerspective::choose_function_overload
debugger ()->choose_function_overloads (nums);
}
+void
+DBGPerspective::remove_visual_decorations_from_text
+ (const UString &a_file_path)
+{
+ SourceEditor *editor = get_source_editor_from_path (a_file_path);
+ if (editor == 0)
+ return;
+ editor->clear_decorations ();
+}
+
bool
DBGPerspective::apply_decorations_to_text (const UString &a_file_path)
{
@@ -6617,6 +6802,42 @@ DBGPerspective::refresh_locals ()
}
void
+DBGPerspective::disassemble (bool a_show_asm_in_new_tab)
+{
+ THROW_IF_FAIL (m_priv);
+
+ // If we don't have the current instruction pointer (IP), there is
+ // nothing we can do.
+ if (!debugger ()->is_attached_to_target ()
+ || m_priv->current_frame.address ().empty ()) {
+ LOG_DD ("No current instruction pointer");
+ return;
+ }
+
+ sigc::slot<void,
+ const IDebugger::DisassembleInfo,
+ const std::list<IDebugger::AsmInstr>& > s;
+ if (a_show_asm_in_new_tab)
+ s = sigc::bind (sigc::mem_fun (this,
+ &DBGPerspective::on_debugger_disassembled_signal),
+ true);
+
+ else
+ s = sigc::bind
+ (sigc::mem_fun
+ (this,
+ &DBGPerspective::on_debugger_disassembled_signal),
+ false);
+
+ debugger ()->disassemble
+ (0 /* Start @ to disassemble */,
+ true /* Start @ is relative to current IP */,
+ NUM_INSTR_TO_DISASSEMBLE * sizeof (void *),
+ true /* End @ is relative to current IP */,
+ s);
+}
+
+void
DBGPerspective::toggle_breakpoint_enabled ()
{
LOG_FUNCTION_SCOPE_NORMAL_DD;
diff --git a/src/uicommon/nmv-source-editor.cc b/src/uicommon/nmv-source-editor.cc
index 624cde8..624129c 100644
--- a/src/uicommon/nmv-source-editor.cc
+++ b/src/uicommon/nmv-source-editor.cc
@@ -173,7 +173,7 @@ struct SourceEditor::Priv {
Gtk::Label *line_col_label;
Gtk::HBox *status_box;
- struct NonCompositeBufContext {
+ struct NonAssemblyBufContext {
Glib::RefPtr<SourceBuffer> buffer;
int current_column;
int current_line;
@@ -181,7 +181,7 @@ struct SourceEditor::Priv {
sigc::signal<void, int, bool> marker_region_got_clicked_signal;
UString path;
- NonCompositeBufContext (Glib::RefPtr<SourceBuffer> a_buf,
+ NonAssemblyBufContext (Glib::RefPtr<SourceBuffer> a_buf,
int a_cur_col, int a_cur_line) :
buffer (a_buf),
current_column (a_cur_col),
@@ -189,72 +189,72 @@ struct SourceEditor::Priv {
{
}
- NonCompositeBufContext (int a_cur_col, int a_cur_line) :
+ NonAssemblyBufContext (int a_cur_col, int a_cur_line) :
current_column (a_cur_col),
current_line (a_cur_line)
{
}
- NonCompositeBufContext () :
+ NonAssemblyBufContext () :
current_column (-1),
current_line (-1)
{
}
- } non_comp_ctxt;
+ } non_asm_ctxt;
- struct CompositeBufContext {
+ struct AssemblyBufContext {
Glib::RefPtr<SourceBuffer> buffer;
Line2AddrFunc line_to_locus_func;
Addr2LineFunc locus_to_line_func;
- CompositeBufContext ()
+ AssemblyBufContext ()
{
}
- CompositeBufContext
+ AssemblyBufContext
(Glib::RefPtr<SourceBuffer> a_buf) :
buffer (a_buf)
{
}
- } comp_ctxt;
+ } asm_ctxt;
sigc::signal<void, const Gtk::TextBuffer::iterator&>
insertion_changed_signal;
- void register_composite_source_buffer
+ void register_assembly_source_buffer
(Glib::RefPtr<SourceBuffer> &a_buf)
{
- comp_ctxt.buffer = a_buf;
+ asm_ctxt.buffer = a_buf;
}
- void register_non_composite_source_buffer
+ void register_non_assembly_source_buffer
(Glib::RefPtr<SourceBuffer> &a_buf)
{
- non_comp_ctxt.buffer = a_buf;
+ non_asm_ctxt.buffer = a_buf;
}
- bool switch_to_composite_source_buffer ()
+ bool switch_to_assembly_source_buffer ()
{
RETURN_VAL_IF_FAIL (source_view, false);
- if (comp_ctxt.buffer
+ if (asm_ctxt.buffer
&& (source_view->get_source_buffer ()
- != comp_ctxt.buffer)) {
- source_view->set_source_buffer (comp_ctxt.buffer);
+ != asm_ctxt.buffer)) {
+ source_view->set_source_buffer (asm_ctxt.buffer);
return true;
}
return false;
}
- bool switch_to_non_composite_source_buffer ()
+ bool switch_to_non_assembly_source_buffer ()
{
RETURN_VAL_IF_FAIL (source_view, false);
- if (comp_ctxt.buffer
+ if (asm_ctxt.buffer
&& (source_view->get_source_buffer ()
- != non_comp_ctxt.buffer)) {
- source_view->set_source_buffer (non_comp_ctxt.buffer);
+ != non_asm_ctxt.buffer)) {
+ source_view->set_source_buffer (non_asm_ctxt.buffer);
return true;
}
return false;
@@ -265,7 +265,7 @@ struct SourceEditor::Priv {
//**************
void on_marker_region_got_clicked (int a_line, bool a_dialog_requested)
{
- non_comp_ctxt.marker_region_got_clicked_signal.emit
+ non_asm_ctxt.marker_region_got_clicked_signal.emit
(a_line, a_dialog_requested);
}
@@ -288,8 +288,8 @@ struct SourceEditor::Priv {
void on_signal_insertion_moved (gint a_line, gint a_col)
{
if (a_line || a_col) {}
- non_comp_ctxt.current_line = a_line;
- non_comp_ctxt.current_column = a_col;
+ non_asm_ctxt.current_line = a_line;
+ non_asm_ctxt.current_column = a_col;
update_line_col_label ();
}
@@ -321,7 +321,7 @@ struct SourceEditor::Priv {
(sigc::mem_fun (*this, &SourceEditor::Priv::on_mark_set_signal));
source_view->get_buffer ()->signal_insert ().connect
(sigc::mem_fun (*this, &SourceEditor::Priv::on_signal_insert));
- non_comp_ctxt.signal_insertion_moved.connect
+ non_asm_ctxt.signal_insertion_moved.connect
(sigc::mem_fun (*this,
&SourceEditor::Priv::on_signal_insertion_moved));
source_view->get_buffer ()->signal_mark_set ().connect
@@ -330,11 +330,11 @@ struct SourceEditor::Priv {
void update_line_col_info_from_iter (const Gtk::TextBuffer::iterator &a_iter)
{
- non_comp_ctxt.current_line = a_iter.get_line () + 1;
- non_comp_ctxt.current_column = get_column_from_iter (a_iter);
- non_comp_ctxt.signal_insertion_moved.emit
- (non_comp_ctxt.current_line,
- non_comp_ctxt.current_column);
+ non_asm_ctxt.current_line = a_iter.get_line () + 1;
+ non_asm_ctxt.current_column = get_column_from_iter (a_iter);
+ non_asm_ctxt.signal_insertion_moved.emit
+ (non_asm_ctxt.current_line,
+ non_asm_ctxt.current_column);
}
void update_line_col_label ()
@@ -345,8 +345,8 @@ struct SourceEditor::Priv {
}
UString message;
message.printf (_("Line: %i, Column: %i"),
- non_comp_ctxt.current_line,
- non_comp_ctxt.current_column);
+ non_asm_ctxt.current_line,
+ non_asm_ctxt.current_column);
line_col_label->set_text (message);
}
@@ -413,7 +413,7 @@ struct SourceEditor::Priv {
source_view (Gtk::manage (new SourceView)),
line_col_label (Gtk::manage (new Gtk::Label)),
status_box (Gtk::manage (new Gtk::HBox)),
- non_comp_ctxt (-1, -1)
+ non_asm_ctxt (-1, -1)
{
init ();
@@ -421,17 +421,17 @@ struct SourceEditor::Priv {
explicit Priv (const UString &a_root_dir,
Glib::RefPtr<SourceBuffer> &a_buf,
- bool a_composite) :
+ bool a_assembly) :
root_dir (a_root_dir),
source_view (Gtk::manage (new SourceView (a_buf))),
line_col_label (Gtk::manage (new Gtk::Label)),
status_box (Gtk::manage (new Gtk::HBox)),
- non_comp_ctxt (a_buf, -1, -1)
+ non_asm_ctxt (a_buf, -1, -1)
{
- if (a_composite) {
- comp_ctxt.buffer = a_buf;
+ if (a_assembly) {
+ asm_ctxt.buffer = a_buf;
} else {
- non_comp_ctxt.buffer = a_buf;
+ non_asm_ctxt.buffer = a_buf;
}
init ();
}
@@ -441,7 +441,7 @@ struct SourceEditor::Priv {
root_dir (a_root_dir),
source_view (Gtk::manage (new SourceView (a_buf))),
status_box (Gtk::manage (new Gtk::HBox)),
- comp_ctxt (a_buf)
+ asm_ctxt (a_buf)
{
init ();
}
@@ -485,9 +485,9 @@ SourceEditor::SourceEditor ()
SourceEditor::SourceEditor (const UString &a_root_dir,
Glib::RefPtr<SourceBuffer> &a_buf,
- bool a_composite)
+ bool a_assembly)
{
- m_priv.reset (new Priv (a_root_dir, a_buf, a_composite));
+ m_priv.reset (new Priv (a_root_dir, a_buf, a_assembly));
init ();
}
@@ -506,26 +506,26 @@ SourceEditor::source_view () const
gint
SourceEditor::current_line () const
{
- return m_priv->non_comp_ctxt.current_line;
+ return m_priv->non_asm_ctxt.current_line;
}
void
SourceEditor::current_line (gint &a_line)
{
- m_priv->non_comp_ctxt.current_line = a_line;
+ m_priv->non_asm_ctxt.current_line = a_line;
}
gint
SourceEditor::current_column () const
{
- return m_priv->non_comp_ctxt.current_column;
+ return m_priv->non_asm_ctxt.current_column;
}
void
SourceEditor::current_column (gint &a_col)
{
LOG_DD ("current colnum " << (int) a_col);
- m_priv->non_comp_ctxt.current_column = a_col;
+ m_priv->non_asm_ctxt.current_column = a_col;
}
void
@@ -665,6 +665,30 @@ SourceEditor::remove_visual_breakpoint_from_line (int a_line)
m_priv->markers.erase (iter);
}
+void
+SourceEditor::clear_decorations ()
+{
+#ifdef WITH_SOURCEVIEWMM2
+ std::map<int, Glib::RefPtr<gtksourceview::SourceMark> >::iterator it;
+#else
+ std::map<int, Glib::RefPtr<gtksourceview::SourceMarker> >::iterator it;
+#endif // WITH_SOURCEVIEWMM2
+
+ // Clear breakpoint markers
+ for (it = m_priv->markers.begin (); it != m_priv->markers.end (); ++it) {
+ if (!it->second->get_deleted ()) {
+#ifdef WITH_SOURCEVIEWMM2
+ source_view ().get_source_buffer ()->delete_mark (it->second);
+#else
+ source_view ().get_source_buffer ()->delete_marker (it->second);
+#endif // WITH_SOURCEVIEWMM2
+ m_priv->markers.erase (it);
+ }
+ }
+
+ unset_where_marker ();
+}
+
bool
SourceEditor::is_visual_breakpoint_set_at_line (int a_line) const
{
@@ -732,20 +756,20 @@ SourceEditor::scroll_to_iter (Gtk::TextIter &a_iter)
void
SourceEditor::set_path (const UString &a_path)
{
- m_priv->non_comp_ctxt.path = a_path;
+ m_priv->non_asm_ctxt.path = a_path;
}
void
SourceEditor::get_path (UString &a_path) const
{
- a_path = m_priv->non_comp_ctxt.path;
+ a_path = m_priv->non_asm_ctxt.path;
}
void
SourceEditor::get_file_name (UString &a_file_name)
{
string path;
- path = Glib::locale_from_utf8 (m_priv->non_comp_ctxt.path);
+ path = Glib::locale_from_utf8 (m_priv->non_asm_ctxt.path);
path = Glib::path_get_basename (path);
a_file_name = Glib::locale_to_utf8 (path);
}
@@ -901,96 +925,96 @@ SourceEditor::do_search (const UString &a_str,
return false;
}
-/// Registers a composite source buffer
-/// \param a_buf the composite source buffer
+/// Registers a assembly source buffer
+/// \param a_buf the assembly source buffer
/// \param a_line_to_locus_func a unary function that converts a line
/// number into a meaningful location for this source buffer.
/// \param a_locus_to_line_func a unary function that converst a
/// meaningful location into a line buffer.
void
-SourceEditor::register_composite_source_buffer
+SourceEditor::register_assembly_source_buffer
(Glib::RefPtr<SourceBuffer> &a_buf)
{
- m_priv->register_composite_source_buffer (a_buf);
+ m_priv->register_assembly_source_buffer (a_buf);
}
-/// Registers a normal (non-composite) source buffer.
+/// Registers a normal (non-assembly) source buffer.
/// \param a_buf the source buffer to register.
void
-SourceEditor::register_non_composite_source_buffer
+SourceEditor::register_non_assembly_source_buffer
(Glib::RefPtr<SourceBuffer> &a_buf)
{
- m_priv->register_non_composite_source_buffer (a_buf);
+ m_priv->register_non_assembly_source_buffer (a_buf);
}
-/// Get the composite source buffer that was registered, or a NULL
+/// Get the assembly source buffer that was registered, or a NULL
/// pointer if no one was registered before.
/// \return a smart pointer to the source buffer.
Glib::RefPtr<SourceBuffer>
-SourceEditor::get_composite_source_buffer () const
+SourceEditor::get_assembly_source_buffer () const
{
- return m_priv->comp_ctxt.buffer;
+ return m_priv->asm_ctxt.buffer;
}
-/// Get the non-composite source buffer that was registered, or a NULL
+/// Get the non-assembly source buffer that was registered, or a NULL
/// pointer if no one was registered before.
/// \return a smart pointer to the source buffer.
Glib::RefPtr<SourceBuffer>
-SourceEditor::get_non_composite_source_buffer () const
+SourceEditor::get_non_assembly_source_buffer () const
{
- return m_priv->non_comp_ctxt.buffer;
+ return m_priv->non_asm_ctxt.buffer;
}
-/// Switch the editor to the composite source buffer that was
-/// registered. This function has no effect if no composite buffer was
+/// Switch the editor to the assembly source buffer that was
+/// registered. This function has no effect if no assembly buffer was
/// registered.
/// \return true if the switch was done, false otherwise.
bool
-SourceEditor::switch_to_composite_source_buffer ()
+SourceEditor::switch_to_assembly_source_buffer ()
{
- return m_priv->switch_to_composite_source_buffer ();
+ return m_priv->switch_to_assembly_source_buffer ();
}
-/// Switch the editor to the non-composite source buffer that was
-/// registered. This function has no effect if no non-composite source
+/// Switch the editor to the non-assembly source buffer that was
+/// registered. This function has no effect if no non-assembly source
/// buffer was registered.
/// \return true if the switch was done, false otherwise.
bool
-SourceEditor::switch_to_non_composite_source_buffer ()
+SourceEditor::switch_to_non_assembly_source_buffer ()
{
RETURN_VAL_IF_FAIL (m_priv && m_priv->source_view, false);
- if (m_priv->comp_ctxt.buffer
+ if (m_priv->asm_ctxt.buffer
&& (m_priv->source_view->get_source_buffer ()
- != m_priv->non_comp_ctxt.buffer)) {
- m_priv->source_view->set_source_buffer (m_priv->non_comp_ctxt.buffer);
+ != m_priv->non_asm_ctxt.buffer)) {
+ m_priv->source_view->set_source_buffer (m_priv->non_asm_ctxt.buffer);
return true;
}
return false;
}
bool
-SourceEditor::composite_buf_loc_to_line (const Address &a_addr, int &a_line)
+SourceEditor::assembly_buf_loc_to_line (const Address &a_addr, int &a_line)
{
- Glib::RefPtr<SourceBuffer> buf = get_composite_source_buffer ();
+ Glib::RefPtr<SourceBuffer> buf = get_assembly_source_buffer ();
RETURN_VAL_IF_FAIL (buf, false);
- a_line = m_priv->comp_ctxt.locus_to_line_func (buf, a_addr);
+ a_line = m_priv->asm_ctxt.locus_to_line_func (buf, a_addr);
return true;
}
bool
-SourceEditor::composite_buf_line_to_loc (int a_line, Address &a_address)
+SourceEditor::assembly_buf_line_to_loc (int a_line, Address &a_address)
{
- Glib::RefPtr<SourceBuffer> buf = get_composite_source_buffer ();
+ Glib::RefPtr<SourceBuffer> buf = get_assembly_source_buffer ();
RETURN_VAL_IF_FAIL (buf, false);
- a_address = m_priv->comp_ctxt.line_to_locus_func (buf, a_line);
+ a_address = m_priv->asm_ctxt.line_to_locus_func (buf, a_line);
return true;
}
sigc::signal<void, int, bool>&
SourceEditor::marker_region_got_clicked_signal () const
{
- return m_priv->non_comp_ctxt.marker_region_got_clicked_signal;
+ return m_priv->non_asm_ctxt.marker_region_got_clicked_signal;
}
sigc::signal<void, const Gtk::TextBuffer::iterator&>&
diff --git a/src/uicommon/nmv-source-editor.h b/src/uicommon/nmv-source-editor.h
index 4d660db..a9c59bf 100644
--- a/src/uicommon/nmv-source-editor.h
+++ b/src/uicommon/nmv-source-editor.h
@@ -75,6 +75,7 @@ public:
void unset_where_marker ();
void set_visual_breakpoint_at_line (int a_line, bool enabled=true);
void remove_visual_breakpoint_from_line (int a_line);
+ void clear_decorations ();
bool is_visual_breakpoint_set_at_line (int a_line) const;
void scroll_to_line (int a_line);
void scroll_to_iter (Gtk::TextIter &a_iter);
@@ -98,35 +99,35 @@ public:
/// \name Composite Source buffer handling.
/// @{
- /// A composite buffer is a buffer which content doesn't come
+ /// A assembly buffer is a buffer which content doesn't come
/// directly from a file. It as been composed in memory. We use
- /// composite buffers to represent the assembly view of a text file
+ /// assemyb buffers to represent the assembly view of a text file
/// being debugged.
- /// Unlike non-composite buffers, meaningful locations inside the buffer
- /// are not necessarily line numbers. They can be something else.
- /// In the case of assembly view, a meaningful location is the address
+ /// Unlike non-assembly buffers, meaningful locations inside the buffer
+ /// are not necessarily line numbers.
+ /// In an assembly view, a meaningful location is the address
/// of a machine instruction. So there somehow must be a kind of mapping
- /// between the location used for the composite buffer and the actual
+ /// between the location used for the assembly buffer and the actual
/// line number, because the underlying SourceBuffer implementation
/// relies on line numbers anyhow.
- void register_composite_source_buffer
+ void register_assembly_source_buffer
(Glib::RefPtr<SourceBuffer> &a_buf);
- void register_non_composite_source_buffer
+ void register_non_assembly_source_buffer
(Glib::RefPtr<SourceBuffer> &a_buf);
- Glib::RefPtr<SourceBuffer> get_composite_source_buffer () const;
+ Glib::RefPtr<SourceBuffer> get_assembly_source_buffer () const;
- Glib::RefPtr<SourceBuffer> get_non_composite_source_buffer () const;
+ Glib::RefPtr<SourceBuffer> get_non_assembly_source_buffer () const;
- bool switch_to_composite_source_buffer ();
+ bool switch_to_assembly_source_buffer ();
- bool switch_to_non_composite_source_buffer ();
+ bool switch_to_non_assembly_source_buffer ();
- bool composite_buf_loc_to_line (const Address &, int &);
+ bool assembly_buf_loc_to_line (const Address &, int &);
- bool composite_buf_line_to_loc (int, Address &);
+ bool assembly_buf_line_to_loc (int, Address &);
/// @}
/// \name signals
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]