forked from OSchip/llvm-project
Many GDB users always want to display disassembly when they stop by using
something like "display/4i $pc" (or something like this). With LLDB we already were showing 3 lines of source before and 3 lines of source after the current source line when showing a stop context. We now improve this by allowing the user to control the number of lines with the new "stop-line-count-before" and "stop-line-count-after" settings. Also, there is a new setting for how many disassembly lines to show: "stop-disassembly-count". This will control how many source lines are shown when there is no source or when we have no source line info. settings set stop-line-count-before 3 settings set stop-line-count-after 3 settings set stop-disassembly-count 4 settings set stop-disassembly-display no-source The default values are set as shown above and allow 3 lines of source before and after (what we used to do) the current stop location, and will display 4 lines of disassembly if the source is not available or if we have no debug info. If both "stop-source-context-before" and "stop-source-context-after" are set to zero, this will disable showing any source when stopped. The "stop-disassembly-display" setting is an enumeration that allows you to control when to display disassembly. It has 3 possible values: "never" - never show disassembly no matter what "no-source" - only show disassembly when there is no source line info or the source files are missing "always" - always show disassembly. llvm-svn: 145050
This commit is contained in:
parent
f13b855809
commit
e372b98d18
|
@ -44,6 +44,14 @@ class DebuggerInstanceSettings : public InstanceSettings
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum StopDisassemblyType
|
||||||
|
{
|
||||||
|
eStopDisassemblyTypeNever = 0,
|
||||||
|
eStopDisassemblyTypeNoSource,
|
||||||
|
eStopDisassemblyTypeAlways
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
DebuggerInstanceSettings (UserSettingsController &owner, bool live_instance = true, const char *name = NULL);
|
DebuggerInstanceSettings (UserSettingsController &owner, bool live_instance = true, const char *name = NULL);
|
||||||
|
|
||||||
DebuggerInstanceSettings (const DebuggerInstanceSettings &rhs);
|
DebuggerInstanceSettings (const DebuggerInstanceSettings &rhs);
|
||||||
|
@ -82,6 +90,44 @@ public:
|
||||||
m_term_width = term_width;
|
m_term_width = term_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
GetStopSourceLineCount (bool before) const
|
||||||
|
{
|
||||||
|
if (before)
|
||||||
|
return m_stop_source_before_count;
|
||||||
|
else
|
||||||
|
return m_stop_source_after_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SetStopSourceLineCount (bool before, uint32_t n)
|
||||||
|
{
|
||||||
|
if (before)
|
||||||
|
m_stop_source_before_count = n;
|
||||||
|
else
|
||||||
|
m_stop_source_after_count = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
StopDisassemblyType
|
||||||
|
GetStopDisassemblyDisplay () const
|
||||||
|
{
|
||||||
|
return m_stop_disassembly_display;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
GetDisassemblyLineCount () const
|
||||||
|
{
|
||||||
|
return m_stop_disassembly_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SetDisassemblyLineCount (uint32_t n)
|
||||||
|
{
|
||||||
|
m_stop_disassembly_count = n;
|
||||||
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
GetPrompt() const
|
GetPrompt() const
|
||||||
{
|
{
|
||||||
|
@ -185,30 +231,15 @@ protected:
|
||||||
const ConstString
|
const ConstString
|
||||||
CreateInstanceName ();
|
CreateInstanceName ();
|
||||||
|
|
||||||
static const ConstString &
|
static OptionEnumValueElement g_show_disassembly_enum_values[];
|
||||||
PromptVarName ();
|
|
||||||
|
|
||||||
static const ConstString &
|
|
||||||
GetFrameFormatName ();
|
|
||||||
|
|
||||||
static const ConstString &
|
|
||||||
GetThreadFormatName ();
|
|
||||||
|
|
||||||
static const ConstString &
|
|
||||||
ScriptLangVarName ();
|
|
||||||
|
|
||||||
static const ConstString &
|
|
||||||
TermWidthVarName ();
|
|
||||||
|
|
||||||
static const ConstString &
|
|
||||||
UseExternalEditorVarName ();
|
|
||||||
|
|
||||||
static const ConstString &
|
|
||||||
AutoConfirmName ();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
uint32_t m_term_width;
|
uint32_t m_term_width;
|
||||||
|
uint32_t m_stop_source_before_count;
|
||||||
|
uint32_t m_stop_source_after_count;
|
||||||
|
uint32_t m_stop_disassembly_count;
|
||||||
|
StopDisassemblyType m_stop_disassembly_display;
|
||||||
std::string m_prompt;
|
std::string m_prompt;
|
||||||
std::string m_frame_format;
|
std::string m_frame_format;
|
||||||
std::string m_thread_format;
|
std::string m_thread_format;
|
||||||
|
|
|
@ -61,6 +61,94 @@ GetDebuggerList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const ConstString &
|
||||||
|
PromptVarName ()
|
||||||
|
{
|
||||||
|
static ConstString g_const_string ("prompt");
|
||||||
|
return g_const_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const ConstString &
|
||||||
|
GetFrameFormatName ()
|
||||||
|
{
|
||||||
|
static ConstString g_const_string ("frame-format");
|
||||||
|
return g_const_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const ConstString &
|
||||||
|
GetThreadFormatName ()
|
||||||
|
{
|
||||||
|
static ConstString g_const_string ("thread-format");
|
||||||
|
return g_const_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const ConstString &
|
||||||
|
ScriptLangVarName ()
|
||||||
|
{
|
||||||
|
static ConstString g_const_string ("script-lang");
|
||||||
|
return g_const_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const ConstString &
|
||||||
|
TermWidthVarName ()
|
||||||
|
{
|
||||||
|
static ConstString g_const_string ("term-width");
|
||||||
|
return g_const_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const ConstString &
|
||||||
|
UseExternalEditorVarName ()
|
||||||
|
{
|
||||||
|
static ConstString g_const_string ("use-external-editor");
|
||||||
|
return g_const_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const ConstString &
|
||||||
|
AutoConfirmName ()
|
||||||
|
{
|
||||||
|
static ConstString g_const_string ("auto-confirm");
|
||||||
|
return g_const_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const ConstString &
|
||||||
|
StopSourceContextBeforeName ()
|
||||||
|
{
|
||||||
|
static ConstString g_const_string ("stop-line-count-before");
|
||||||
|
return g_const_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const ConstString &
|
||||||
|
StopSourceContextAfterName ()
|
||||||
|
{
|
||||||
|
static ConstString g_const_string ("stop-line-count-after");
|
||||||
|
return g_const_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const ConstString &
|
||||||
|
StopDisassemblyCountName ()
|
||||||
|
{
|
||||||
|
static ConstString g_const_string ("stop-disassembly-count");
|
||||||
|
return g_const_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const ConstString &
|
||||||
|
StopDisassemblyDisplayName ()
|
||||||
|
{
|
||||||
|
static ConstString g_const_string ("stop-disassembly-display");
|
||||||
|
return g_const_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
OptionEnumValueElement
|
||||||
|
DebuggerInstanceSettings::g_show_disassembly_enum_values[] =
|
||||||
|
{
|
||||||
|
{ eStopDisassemblyTypeNever, "never", "Never show disassembly when displaying a stop context."},
|
||||||
|
{ eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."},
|
||||||
|
{ eStopDisassemblyTypeAlways, "always", "Always show disassembly when displaying a stop context."},
|
||||||
|
{ 0, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#pragma mark Debugger
|
#pragma mark Debugger
|
||||||
|
|
||||||
UserSettingsControllerSP &
|
UserSettingsControllerSP &
|
||||||
|
@ -2108,6 +2196,10 @@ DebuggerInstanceSettings::DebuggerInstanceSettings
|
||||||
) :
|
) :
|
||||||
InstanceSettings (owner, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance),
|
InstanceSettings (owner, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance),
|
||||||
m_term_width (80),
|
m_term_width (80),
|
||||||
|
m_stop_source_before_count (3),
|
||||||
|
m_stop_source_after_count (3),
|
||||||
|
m_stop_disassembly_count (4),
|
||||||
|
m_stop_disassembly_display (eStopDisassemblyTypeNoSource),
|
||||||
m_prompt (),
|
m_prompt (),
|
||||||
m_frame_format (),
|
m_frame_format (),
|
||||||
m_thread_format (),
|
m_thread_format (),
|
||||||
|
@ -2255,6 +2347,37 @@ DebuggerInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var
|
||||||
{
|
{
|
||||||
UserSettingsController::UpdateBooleanVariable (op, m_auto_confirm_on, value, false, err);
|
UserSettingsController::UpdateBooleanVariable (op, m_auto_confirm_on, value, false, err);
|
||||||
}
|
}
|
||||||
|
else if (var_name == StopSourceContextBeforeName ())
|
||||||
|
{
|
||||||
|
uint32_t new_value = Args::StringToUInt32(value, UINT32_MAX, 10, NULL);
|
||||||
|
if (new_value != UINT32_MAX)
|
||||||
|
m_stop_source_before_count = new_value;
|
||||||
|
else
|
||||||
|
err.SetErrorStringWithFormat("invalid unsigned string value '%s' for the '%s' setting", value, StopSourceContextAfterName ().GetCString());
|
||||||
|
}
|
||||||
|
else if (var_name == StopSourceContextAfterName ())
|
||||||
|
{
|
||||||
|
uint32_t new_value = Args::StringToUInt32(value, UINT32_MAX, 10, NULL);
|
||||||
|
if (new_value != UINT32_MAX)
|
||||||
|
m_stop_source_after_count = new_value;
|
||||||
|
else
|
||||||
|
err.SetErrorStringWithFormat("invalid unsigned string value '%s' for the '%s' setting", value, StopSourceContextBeforeName ().GetCString());
|
||||||
|
}
|
||||||
|
else if (var_name == StopDisassemblyCountName ())
|
||||||
|
{
|
||||||
|
uint32_t new_value = Args::StringToUInt32(value, UINT32_MAX, 10, NULL);
|
||||||
|
if (new_value != UINT32_MAX)
|
||||||
|
m_stop_disassembly_count = new_value;
|
||||||
|
else
|
||||||
|
err.SetErrorStringWithFormat("invalid unsigned string value '%s' for the '%s' setting", value, StopDisassemblyCountName ().GetCString());
|
||||||
|
}
|
||||||
|
else if (var_name == StopDisassemblyDisplayName ())
|
||||||
|
{
|
||||||
|
int new_value;
|
||||||
|
UserSettingsController::UpdateEnumVariable (g_show_disassembly_enum_values, &new_value, value, err);
|
||||||
|
if (err.Success())
|
||||||
|
m_stop_disassembly_display = (StopDisassemblyType)new_value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -2275,7 +2398,7 @@ DebuggerInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
|
||||||
else if (var_name == TermWidthVarName())
|
else if (var_name == TermWidthVarName())
|
||||||
{
|
{
|
||||||
StreamString width_str;
|
StreamString width_str;
|
||||||
width_str.Printf ("%d", m_term_width);
|
width_str.Printf ("%u", m_term_width);
|
||||||
value.AppendString (width_str.GetData());
|
value.AppendString (width_str.GetData());
|
||||||
}
|
}
|
||||||
else if (var_name == GetFrameFormatName ())
|
else if (var_name == GetFrameFormatName ())
|
||||||
|
@ -2300,6 +2423,31 @@ DebuggerInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
|
||||||
else
|
else
|
||||||
value.AppendString ("false");
|
value.AppendString ("false");
|
||||||
}
|
}
|
||||||
|
else if (var_name == StopSourceContextAfterName ())
|
||||||
|
{
|
||||||
|
StreamString strm;
|
||||||
|
strm.Printf ("%u", m_stop_source_before_count);
|
||||||
|
value.AppendString (strm.GetData());
|
||||||
|
}
|
||||||
|
else if (var_name == StopSourceContextBeforeName ())
|
||||||
|
{
|
||||||
|
StreamString strm;
|
||||||
|
strm.Printf ("%u", m_stop_source_after_count);
|
||||||
|
value.AppendString (strm.GetData());
|
||||||
|
}
|
||||||
|
else if (var_name == StopDisassemblyCountName ())
|
||||||
|
{
|
||||||
|
StreamString strm;
|
||||||
|
strm.Printf ("%u", m_stop_disassembly_count);
|
||||||
|
value.AppendString (strm.GetData());
|
||||||
|
}
|
||||||
|
else if (var_name == StopDisassemblyDisplayName ())
|
||||||
|
{
|
||||||
|
if (m_stop_disassembly_display >= eStopDisassemblyTypeNever && m_stop_disassembly_display <= eStopDisassemblyTypeAlways)
|
||||||
|
value.AppendString (g_show_disassembly_enum_values[m_stop_disassembly_display].string_value);
|
||||||
|
else
|
||||||
|
value.AppendString ("<invalid>");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -2391,61 +2539,6 @@ DebuggerInstanceSettings::CreateInstanceName ()
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ConstString &
|
|
||||||
DebuggerInstanceSettings::PromptVarName ()
|
|
||||||
{
|
|
||||||
static ConstString prompt_var_name ("prompt");
|
|
||||||
|
|
||||||
return prompt_var_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ConstString &
|
|
||||||
DebuggerInstanceSettings::GetFrameFormatName ()
|
|
||||||
{
|
|
||||||
static ConstString prompt_var_name ("frame-format");
|
|
||||||
|
|
||||||
return prompt_var_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ConstString &
|
|
||||||
DebuggerInstanceSettings::GetThreadFormatName ()
|
|
||||||
{
|
|
||||||
static ConstString prompt_var_name ("thread-format");
|
|
||||||
|
|
||||||
return prompt_var_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ConstString &
|
|
||||||
DebuggerInstanceSettings::ScriptLangVarName ()
|
|
||||||
{
|
|
||||||
static ConstString script_lang_var_name ("script-lang");
|
|
||||||
|
|
||||||
return script_lang_var_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ConstString &
|
|
||||||
DebuggerInstanceSettings::TermWidthVarName ()
|
|
||||||
{
|
|
||||||
static ConstString term_width_var_name ("term-width");
|
|
||||||
|
|
||||||
return term_width_var_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ConstString &
|
|
||||||
DebuggerInstanceSettings::UseExternalEditorVarName ()
|
|
||||||
{
|
|
||||||
static ConstString use_external_editor_var_name ("use-external-editor");
|
|
||||||
|
|
||||||
return use_external_editor_var_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ConstString &
|
|
||||||
DebuggerInstanceSettings::AutoConfirmName ()
|
|
||||||
{
|
|
||||||
static ConstString use_external_editor_var_name ("auto-confirm");
|
|
||||||
|
|
||||||
return use_external_editor_var_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// SettingsController Variable Tables
|
// SettingsController Variable Tables
|
||||||
|
@ -2497,5 +2590,9 @@ Debugger::SettingsController::instance_settings_table[] =
|
||||||
{ "thread-format", eSetVarTypeString, DEFAULT_THREAD_FORMAT, NULL, false, false, "The default thread format string to use when displaying thread information." },
|
{ "thread-format", eSetVarTypeString, DEFAULT_THREAD_FORMAT, NULL, false, false, "The default thread format string to use when displaying thread information." },
|
||||||
{ "use-external-editor", eSetVarTypeBoolean, "false", NULL, false, false, "Whether to use an external editor or not." },
|
{ "use-external-editor", eSetVarTypeBoolean, "false", NULL, false, false, "Whether to use an external editor or not." },
|
||||||
{ "auto-confirm", eSetVarTypeBoolean, "false", NULL, false, false, "If true all confirmation prompts will receive their default reply." },
|
{ "auto-confirm", eSetVarTypeBoolean, "false", NULL, false, false, "If true all confirmation prompts will receive their default reply." },
|
||||||
|
{ "stop-line-count-before",eSetVarTypeInt, "3", NULL, false, false, "The number of sources lines to display that come before the current source line when displaying a stopped context." },
|
||||||
|
{ "stop-line-count-after", eSetVarTypeInt, "3", NULL, false, false, "The number of sources lines to display that come after the current source line when displaying a stopped context." },
|
||||||
|
{ "stop-disassembly-count", eSetVarTypeInt, "0", NULL, false, false, "The number of disassembly lines to show when displaying a stopped context." },
|
||||||
|
{ "stop-disassembly-display", eSetVarTypeEnum, "no-source", g_show_disassembly_enum_values, false, false, "Control when to display disassembly when displaying a stopped context." },
|
||||||
{ NULL, eSetVarTypeNone, NULL, NULL, false, false, NULL }
|
{ NULL, eSetVarTypeNone, NULL, NULL, false, false, NULL }
|
||||||
};
|
};
|
||||||
|
|
|
@ -1269,20 +1269,63 @@ StackFrame::GetStatus (Stream& strm,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_source)
|
if (show_source)
|
||||||
|
{
|
||||||
|
Target &target = GetThread().GetProcess().GetTarget();
|
||||||
|
Debugger &debugger = target.GetDebugger();
|
||||||
|
const uint32_t source_before = debugger.GetStopSourceLineCount(true);
|
||||||
|
const uint32_t source_after = debugger.GetStopSourceLineCount(false);
|
||||||
|
bool have_source = false;
|
||||||
|
if (source_before || source_after)
|
||||||
{
|
{
|
||||||
GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry);
|
GetSymbolContext(eSymbolContextCompUnit | eSymbolContextLineEntry);
|
||||||
|
|
||||||
if (m_sc.comp_unit && m_sc.line_entry.IsValid())
|
if (m_sc.comp_unit && m_sc.line_entry.IsValid())
|
||||||
{
|
{
|
||||||
Target &target = GetThread().GetProcess().GetTarget();
|
if (target.GetSourceManager().DisplaySourceLinesWithLineNumbers (m_sc.line_entry.file,
|
||||||
target.GetSourceManager().DisplaySourceLinesWithLineNumbers (
|
|
||||||
m_sc.line_entry.file,
|
|
||||||
m_sc.line_entry.line,
|
m_sc.line_entry.line,
|
||||||
3,
|
source_before,
|
||||||
3,
|
source_after,
|
||||||
"->",
|
"->",
|
||||||
&strm);
|
&strm))
|
||||||
|
{
|
||||||
|
have_source = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DebuggerInstanceSettings::StopDisassemblyType disasm_display = debugger.GetStopDisassemblyDisplay ();
|
||||||
|
|
||||||
|
switch (disasm_display)
|
||||||
|
{
|
||||||
|
case DebuggerInstanceSettings::eStopDisassemblyTypeNever:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DebuggerInstanceSettings::eStopDisassemblyTypeNoSource:
|
||||||
|
if (have_source)
|
||||||
|
break;
|
||||||
|
// Fall through to next case
|
||||||
|
case DebuggerInstanceSettings::eStopDisassemblyTypeAlways:
|
||||||
|
{
|
||||||
|
const uint32_t disasm_lines = debugger.GetDisassemblyLineCount();
|
||||||
|
if (disasm_lines > 0)
|
||||||
|
{
|
||||||
|
const ArchSpec &target_arch = target.GetArchitecture();
|
||||||
|
AddressRange pc_range;
|
||||||
|
pc_range.GetBaseAddress() = GetFrameCodeAddress();
|
||||||
|
pc_range.SetByteSize(disasm_lines * target_arch.GetMaximumOpcodeByteSize());
|
||||||
|
ExecutionContext exe_ctx;
|
||||||
|
CalculateExecutionContext(exe_ctx);
|
||||||
|
Disassembler::Disassemble (debugger,
|
||||||
|
target_arch,
|
||||||
|
NULL,
|
||||||
|
exe_ctx,
|
||||||
|
pc_range,
|
||||||
|
disasm_lines,
|
||||||
|
0,
|
||||||
|
Disassembler::eOptionMarkPCAddress,
|
||||||
|
strm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue