Did some work on the "register read" command to only show the first register
set by default when dumping registers. If you want to see all of the register sets you can use the "--all" option: (lldb) register read --all If you want to just see some register sets, you can currently specify them by index: (lldb) register read --set 0 --set 2 We need to get shorter register set names soon so we can specify the register sets by name without having to type too much. I will make this change soon. You can also have any integer encoded registers resolve the address values back to any code or data from the object files using the "--lookup" option. Below is sample output when stopped in the libc function "puts" with some const strings in registers: Process 8973 stopped * thread #1: tid = 0x2c03, 0x00007fff828fa30f libSystem.B.dylib`puts + 1, stop reason = instruction step into frame #0: 0x00007fff828fa30f libSystem.B.dylib`puts + 1 (lldb) register read --lookup General Purpose Registers: rax = 0x0000000100000e98 "----------------------------------------------------------------------" rbx = 0x0000000000000000 rcx = 0x0000000000000001 rdx = 0x0000000000000000 rdi = 0x0000000100000e98 "----------------------------------------------------------------------" rsi = 0x0000000100800000 rbp = 0x00007fff5fbff710 rsp = 0x00007fff5fbff280 r8 = 0x0000000000000040 r9 = 0x0000000000000000 r10 = 0x0000000000000000 r11 = 0x0000000000000246 r12 = 0x0000000000000000 r13 = 0x0000000000000000 r14 = 0x0000000000000000 r15 = 0x0000000000000000 rip = 0x00007fff828fa30f libSystem.B.dylib`puts + 1 rflags = 0x0000000000000246 cs = 0x0000000000000027 fs = 0x0000000000000000 gs = 0x0000000000000000 As we can see, we see two constant strings and the PC (register "rip") is showing the code it resolves to. I fixed the register "--format" option to work as expected. Added a setting to disable skipping the function prologue when setting breakpoints as a target settings variable: (lldb) settings set target.skip-prologue false Updated the user settings controller boolean value handler funciton to be able to take the default value so it can correctly respond to the eVarSetOperationClear operation. Did some usability work on the OptionValue classes. Fixed the "image lookup" command to correctly respond to the "--verbose" option and display the detailed symbol context information when looking up line table entries and functions by name. This previously was only working for address lookups. llvm-svn: 129977
This commit is contained in:
parent
bafb9347dd
commit
385aa28cf6
|
@ -208,6 +208,7 @@ public:
|
|||
UpdateBooleanVariable (VarSetOperationType op,
|
||||
bool &bool_var,
|
||||
const char *new_value,
|
||||
bool clear_value, // Used for op == eVarSetOperationClear
|
||||
Error &err);
|
||||
|
||||
static void
|
||||
|
|
|
@ -60,11 +60,11 @@ namespace lldb_private {
|
|||
virtual void
|
||||
DumpValue (Stream &strm) = 0;
|
||||
|
||||
virtual bool
|
||||
virtual Error
|
||||
SetValueFromCString (const char *value) = 0;
|
||||
|
||||
virtual bool
|
||||
ResetValueToDefault () = 0;
|
||||
Clear () = 0;
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// Subclasses should NOT override these functions as they use the
|
||||
|
@ -76,6 +76,18 @@ namespace lldb_private {
|
|||
return 1u << GetType();
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
ConvertTypeToMask (OptionValue::Type type)
|
||||
{
|
||||
return 1u << type;
|
||||
}
|
||||
|
||||
// Get this value as a uint64_t value if it is encoded as a boolean,
|
||||
// uint64_t or int64_t. Other types will cause "fail_value" to be
|
||||
// returned
|
||||
uint64_t
|
||||
GetUInt64Value (uint64_t fail_value, bool *success_ptr);
|
||||
|
||||
OptionValueBoolean *
|
||||
GetAsBooleanValue ();
|
||||
|
||||
|
@ -89,13 +101,21 @@ namespace lldb_private {
|
|||
GetAsStringValue ();
|
||||
|
||||
OptionValueFileSpec *
|
||||
GetAsFileSpecValue() ;
|
||||
GetAsFileSpecValue();
|
||||
|
||||
OptionValueArray *
|
||||
GetAsArrayValue() ;
|
||||
GetAsArrayValue();
|
||||
|
||||
OptionValueDictionary *
|
||||
GetAsDictionaryValue() ;
|
||||
GetAsDictionaryValue();
|
||||
|
||||
protected:
|
||||
bool m_value_was_set; // This can be used to see if a value has been set
|
||||
// by a call to SetValueFromCString(). It is often
|
||||
// handy to know if an option value was set from
|
||||
// the command line or as a setting, versus if we
|
||||
// just have the default value that was already
|
||||
// populated in the option value.
|
||||
};
|
||||
|
||||
|
||||
|
@ -131,13 +151,14 @@ namespace lldb_private {
|
|||
virtual void
|
||||
DumpValue (Stream &strm);
|
||||
|
||||
virtual bool
|
||||
virtual Error
|
||||
SetValueFromCString (const char *value);
|
||||
|
||||
virtual bool
|
||||
ResetValueToDefault ()
|
||||
Clear ()
|
||||
{
|
||||
m_current_value = m_default_value;
|
||||
m_value_was_set = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -145,6 +166,26 @@ namespace lldb_private {
|
|||
// Subclass specific functions
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Convert to bool operator.
|
||||
///
|
||||
/// This allows code to check a OptionValueBoolean in conditions.
|
||||
///
|
||||
/// @code
|
||||
/// OptionValueBoolean bool_value(...);
|
||||
/// if (bool_value)
|
||||
/// { ...
|
||||
/// @endcode
|
||||
///
|
||||
/// @return
|
||||
/// /b True this object contains a valid namespace decl, \b
|
||||
/// false otherwise.
|
||||
//------------------------------------------------------------------
|
||||
operator bool() const
|
||||
{
|
||||
return m_current_value;
|
||||
}
|
||||
|
||||
bool
|
||||
GetCurrentValue() const
|
||||
{
|
||||
|
@ -180,10 +221,16 @@ namespace lldb_private {
|
|||
class OptionValueSInt64 : public OptionValue
|
||||
{
|
||||
public:
|
||||
OptionValueSInt64 () :
|
||||
m_current_value (0),
|
||||
m_default_value (0)
|
||||
{
|
||||
}
|
||||
|
||||
OptionValueSInt64 (int64_t current_value,
|
||||
int64_t default_value) :
|
||||
m_current_value (current_value),
|
||||
m_default_value (default_value)
|
||||
m_current_value (current_value),
|
||||
m_default_value (default_value)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -205,13 +252,14 @@ namespace lldb_private {
|
|||
virtual void
|
||||
DumpValue (Stream &strm);
|
||||
|
||||
virtual bool
|
||||
virtual Error
|
||||
SetValueFromCString (const char *value);
|
||||
|
||||
virtual bool
|
||||
ResetValueToDefault ()
|
||||
Clear ()
|
||||
{
|
||||
m_current_value = m_default_value;
|
||||
m_value_was_set = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -254,10 +302,16 @@ namespace lldb_private {
|
|||
class OptionValueUInt64 : public OptionValue
|
||||
{
|
||||
public:
|
||||
OptionValueUInt64 () :
|
||||
m_current_value (0),
|
||||
m_default_value (0)
|
||||
{
|
||||
}
|
||||
|
||||
OptionValueUInt64 (uint64_t current_value,
|
||||
uint64_t default_value) :
|
||||
m_current_value (current_value),
|
||||
m_default_value (default_value)
|
||||
m_current_value (current_value),
|
||||
m_default_value (default_value)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -266,6 +320,14 @@ namespace lldb_private {
|
|||
{
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Decode a uint64_t from "value_cstr" return a OptionValueUInt64 object
|
||||
// inside of a lldb::OptionValueSP object if all goes well. If the
|
||||
// string isn't a uint64_t value or any other error occurs, return an
|
||||
// empty lldb::OptionValueSP and fill error in with the correct stuff.
|
||||
//---------------------------------------------------------------------
|
||||
static lldb::OptionValueSP
|
||||
Create (const char *value_cstr, Error &error);
|
||||
//---------------------------------------------------------------------
|
||||
// Virtual subclass pure virtual overrides
|
||||
//---------------------------------------------------------------------
|
||||
|
@ -279,13 +341,14 @@ namespace lldb_private {
|
|||
virtual void
|
||||
DumpValue (Stream &strm);
|
||||
|
||||
virtual bool
|
||||
virtual Error
|
||||
SetValueFromCString (const char *value);
|
||||
|
||||
virtual bool
|
||||
ResetValueToDefault ()
|
||||
Clear ()
|
||||
{
|
||||
m_current_value = m_default_value;
|
||||
m_value_was_set = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -363,13 +426,14 @@ namespace lldb_private {
|
|||
virtual void
|
||||
DumpValue (Stream &strm);
|
||||
|
||||
virtual bool
|
||||
virtual Error
|
||||
SetValueFromCString (const char *value);
|
||||
|
||||
virtual bool
|
||||
ResetValueToDefault ()
|
||||
Clear ()
|
||||
{
|
||||
m_current_value = m_default_value;
|
||||
m_value_was_set = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -455,13 +519,14 @@ namespace lldb_private {
|
|||
virtual void
|
||||
DumpValue (Stream &strm);
|
||||
|
||||
virtual bool
|
||||
virtual Error
|
||||
SetValueFromCString (const char *value);
|
||||
|
||||
virtual bool
|
||||
ResetValueToDefault ()
|
||||
Clear ()
|
||||
{
|
||||
m_current_value = m_default_value;
|
||||
m_value_was_set = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -528,13 +593,14 @@ namespace lldb_private {
|
|||
virtual void
|
||||
DumpValue (Stream &strm);
|
||||
|
||||
virtual bool
|
||||
virtual Error
|
||||
SetValueFromCString (const char *value);
|
||||
|
||||
virtual bool
|
||||
ResetValueToDefault ()
|
||||
Clear ()
|
||||
{
|
||||
m_values.clear();
|
||||
m_value_was_set = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -543,7 +609,7 @@ namespace lldb_private {
|
|||
//---------------------------------------------------------------------
|
||||
|
||||
uint32_t
|
||||
GetNumValues() const
|
||||
GetSize () const
|
||||
{
|
||||
return m_values.size();
|
||||
}
|
||||
|
@ -557,6 +623,11 @@ namespace lldb_private {
|
|||
return value_sp;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
GetUInt64ValueAtIndex (uint32_t idx,
|
||||
uint64_t fail_value,
|
||||
bool *success_ptr) const;
|
||||
|
||||
bool
|
||||
AppendValue (const lldb::OptionValueSP &value_sp)
|
||||
{
|
||||
|
@ -652,13 +723,14 @@ namespace lldb_private {
|
|||
virtual void
|
||||
DumpValue (Stream &strm);
|
||||
|
||||
virtual bool
|
||||
virtual Error
|
||||
SetValueFromCString (const char *value);
|
||||
|
||||
virtual bool
|
||||
ResetValueToDefault ()
|
||||
Clear ()
|
||||
{
|
||||
m_values.clear();
|
||||
m_value_was_set = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,6 +72,12 @@ public:
|
|||
return m_prefer_dynamic_value;
|
||||
}
|
||||
|
||||
bool
|
||||
GetSkipPrologue()
|
||||
{
|
||||
return m_skip_prologue;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void
|
||||
|
@ -84,6 +90,7 @@ protected:
|
|||
std::string m_expr_prefix_path;
|
||||
std::string m_expr_prefix_contents;
|
||||
bool m_prefer_dynamic_value;
|
||||
bool m_skip_prologue;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ our @archive_files = (
|
|||
"$llvm_configuration/lib/libLLVMX86Utils.a",
|
||||
);
|
||||
|
||||
if (-e "$llvm_srcroot/lib")
|
||||
if ($ENV{CONFIGURATION} ne "BuildAndIntegration" and -e "$llvm_srcroot/lib")
|
||||
{
|
||||
print "Using standard LLVM build directory...\n";
|
||||
# LLVM in the "lldb" root is a symlink which indicates we are using a
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "lldb/Breakpoint/BreakpointLocation.h"
|
||||
#include "lldb/Core/Log.h"
|
||||
#include "lldb/Core/StreamString.h"
|
||||
#include "lldb/lldb-private-log.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
@ -146,6 +146,11 @@ BreakpointResolverName::SearchCallback
|
|||
Address break_addr;
|
||||
assert (m_breakpoint != NULL);
|
||||
|
||||
if (context.target_sp)
|
||||
{
|
||||
skip_prologue = context.target_sp->GetSkipPrologue();
|
||||
}
|
||||
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
|
||||
|
||||
if (m_class_name)
|
||||
|
|
|
@ -324,7 +324,7 @@ LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *mod
|
|||
|
||||
|
||||
static void
|
||||
DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolContextList &sc_list, bool prepend_addr)
|
||||
DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolContextList &sc_list, bool prepend_addr, bool verbose)
|
||||
{
|
||||
strm.IndentMore ();
|
||||
uint32_t i;
|
||||
|
@ -336,31 +336,50 @@ DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolCont
|
|||
if (sc_list.GetContextAtIndex(i, sc))
|
||||
{
|
||||
strm.Indent();
|
||||
ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope ();
|
||||
|
||||
if (prepend_addr)
|
||||
{
|
||||
if (sc.line_entry.range.GetBaseAddress().IsValid())
|
||||
{
|
||||
lldb::addr_t vm_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(interpreter.GetExecutionContext().target);
|
||||
int addr_size = sizeof (addr_t);
|
||||
Process *process = interpreter.GetExecutionContext().process;
|
||||
if (process)
|
||||
addr_size = process->GetTarget().GetArchitecture().GetAddressByteSize();
|
||||
if (vm_addr != LLDB_INVALID_ADDRESS)
|
||||
strm.Address (vm_addr, addr_size);
|
||||
else
|
||||
sc.line_entry.range.GetBaseAddress().Dump (&strm, NULL, Address::DumpStyleSectionNameOffset);
|
||||
|
||||
sc.line_entry.range.GetBaseAddress().Dump (&strm,
|
||||
exe_scope,
|
||||
Address::DumpStyleLoadAddress,
|
||||
Address::DumpStyleModuleWithFileAddress);
|
||||
strm.PutCString(" in ");
|
||||
}
|
||||
}
|
||||
sc.DumpStopContext(&strm, interpreter.GetExecutionContext().process, sc.line_entry.range.GetBaseAddress(), true, true, false);
|
||||
sc.DumpStopContext(&strm,
|
||||
exe_scope,
|
||||
sc.line_entry.range.GetBaseAddress(),
|
||||
true,
|
||||
true,
|
||||
false);
|
||||
strm.EOL();
|
||||
if (verbose)
|
||||
{
|
||||
if (sc.line_entry.range.GetBaseAddress().IsValid())
|
||||
{
|
||||
if (sc.line_entry.range.GetBaseAddress().Dump (&strm,
|
||||
exe_scope,
|
||||
Address::DumpStyleDetailedSymbolContext))
|
||||
strm.PutCString("\n\n");
|
||||
}
|
||||
else if (sc.function->GetAddressRange().GetBaseAddress().IsValid())
|
||||
{
|
||||
if (sc.function->GetAddressRange().GetBaseAddress().Dump (&strm,
|
||||
exe_scope,
|
||||
Address::DumpStyleDetailedSymbolContext))
|
||||
strm.PutCString("\n\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
strm.IndentLess ();
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex)
|
||||
LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose)
|
||||
{
|
||||
if (module && name && name[0])
|
||||
{
|
||||
|
@ -392,7 +411,7 @@ LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *m
|
|||
strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
|
||||
DumpFullpath (strm, &module->GetFileSpec(), 0);
|
||||
strm.PutCString(":\n");
|
||||
DumpSymbolContextList (interpreter, strm, sc_list, true);
|
||||
DumpSymbolContextList (interpreter, strm, sc_list, true, verbose);
|
||||
}
|
||||
return num_matches;
|
||||
}
|
||||
|
@ -457,7 +476,13 @@ LookupTypeInModule
|
|||
}
|
||||
|
||||
static uint32_t
|
||||
LookupFileAndLineInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const FileSpec &file_spec, uint32_t line, bool check_inlines)
|
||||
LookupFileAndLineInModule (CommandInterpreter &interpreter,
|
||||
Stream &strm,
|
||||
Module *module,
|
||||
const FileSpec &file_spec,
|
||||
uint32_t line,
|
||||
bool check_inlines,
|
||||
bool verbose)
|
||||
{
|
||||
if (module && file_spec)
|
||||
{
|
||||
|
@ -474,7 +499,7 @@ LookupFileAndLineInModule (CommandInterpreter &interpreter, Stream &strm, Module
|
|||
strm << " in ";
|
||||
DumpFullpath (strm, &module->GetFileSpec(), 0);
|
||||
strm.PutCString(":\n");
|
||||
DumpSymbolContextList (interpreter, strm, sc_list, true);
|
||||
DumpSymbolContextList (interpreter, strm, sc_list, true, verbose);
|
||||
return num_matches;
|
||||
}
|
||||
}
|
||||
|
@ -1550,7 +1575,8 @@ public:
|
|||
module,
|
||||
m_options.m_file,
|
||||
m_options.m_line_number,
|
||||
m_options.m_check_inlines))
|
||||
m_options.m_check_inlines,
|
||||
m_options.m_verbose))
|
||||
{
|
||||
result.SetStatus(eReturnStatusSuccessFinishResult);
|
||||
return true;
|
||||
|
@ -1565,7 +1591,8 @@ public:
|
|||
result.GetOutputStream(),
|
||||
module,
|
||||
m_options.m_str.c_str(),
|
||||
m_options.m_use_regex))
|
||||
m_options.m_use_regex,
|
||||
m_options.m_verbose))
|
||||
{
|
||||
result.SetStatus(eReturnStatusSuccessFinishResult);
|
||||
return true;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "lldb/Interpreter/Args.h"
|
||||
#include "lldb/Interpreter/CommandInterpreter.h"
|
||||
#include "lldb/Interpreter/CommandReturnObject.h"
|
||||
#include "lldb/Interpreter/NamedOptionValue.h"
|
||||
#include "lldb/Interpreter/Options.h"
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
#include "lldb/Target/RegisterContext.h"
|
||||
|
@ -66,6 +67,85 @@ public:
|
|||
return &m_options;
|
||||
}
|
||||
|
||||
bool
|
||||
DumpRegister (const ExecutionContext &exe_ctx,
|
||||
Stream &strm,
|
||||
RegisterContext *reg_ctx,
|
||||
const RegisterInfo *reg_info)
|
||||
{
|
||||
if (reg_info)
|
||||
{
|
||||
uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
|
||||
|
||||
DataExtractor reg_data;
|
||||
|
||||
if (reg_ctx->ReadRegisterBytes(reg, reg_data))
|
||||
{
|
||||
strm.Indent ();
|
||||
strm.Printf ("%-12s = ", reg_info ? reg_info->name : "<INVALID REGINFO>");
|
||||
Format format;
|
||||
if (m_options.format == eFormatDefault)
|
||||
format = reg_info->format;
|
||||
else
|
||||
format = m_options.format;
|
||||
|
||||
reg_data.Dump(&strm, 0, format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
|
||||
if (m_options.lookup_addresses && ((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint)))
|
||||
{
|
||||
addr_t reg_addr = reg_ctx->ReadRegisterAsUnsigned (reg, 0);
|
||||
if (reg_addr)
|
||||
{
|
||||
Address so_reg_addr;
|
||||
if (exe_ctx.target->GetSectionLoadList().ResolveLoadAddress(reg_addr, so_reg_addr))
|
||||
{
|
||||
strm.PutCString (" ");
|
||||
so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
strm.EOL();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
DumpRegisterSet (const ExecutionContext &exe_ctx,
|
||||
Stream &strm,
|
||||
RegisterContext *reg_ctx,
|
||||
uint32_t set_idx)
|
||||
{
|
||||
uint32_t unavailable_count = 0;
|
||||
uint32_t available_count = 0;
|
||||
const RegisterSet * const reg_set = reg_ctx->GetRegisterSet(set_idx);
|
||||
if (reg_set)
|
||||
{
|
||||
strm.Printf ("%s:\n", reg_set->name);
|
||||
strm.IndentMore ();
|
||||
const uint32_t num_registers = reg_set->num_registers;
|
||||
for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx)
|
||||
{
|
||||
const uint32_t reg = reg_set->registers[reg_idx];
|
||||
if (DumpRegister (exe_ctx, strm, reg_ctx, reg_ctx->GetRegisterInfoAtIndex(reg)))
|
||||
++available_count;
|
||||
else
|
||||
++unavailable_count;
|
||||
}
|
||||
strm.IndentLess ();
|
||||
if (unavailable_count)
|
||||
{
|
||||
strm.Indent ();
|
||||
strm.Printf("%u registers were unavailable.\n", unavailable_count);
|
||||
}
|
||||
strm.EOL();
|
||||
}
|
||||
return available_count > 0;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
Execute
|
||||
(
|
||||
|
@ -73,73 +153,80 @@ public:
|
|||
CommandReturnObject &result
|
||||
)
|
||||
{
|
||||
Stream &output_stream = result.GetOutputStream();
|
||||
DataExtractor reg_data;
|
||||
Stream &strm = result.GetOutputStream();
|
||||
ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
|
||||
RegisterContext *reg_context = exe_ctx.GetRegisterContext ();
|
||||
RegisterContext *reg_ctx = exe_ctx.GetRegisterContext ();
|
||||
|
||||
if (reg_context)
|
||||
if (reg_ctx)
|
||||
{
|
||||
const RegisterInfo *reg_info = NULL;
|
||||
if (command.GetArgumentCount() == 0)
|
||||
{
|
||||
uint32_t set_idx;
|
||||
const uint32_t num_register_sets = reg_context->GetRegisterSetCount();
|
||||
for (set_idx = 0; set_idx < num_register_sets; ++set_idx)
|
||||
|
||||
uint32_t num_register_sets = 1;
|
||||
const uint32_t set_array_size = m_options.set_indexes.GetSize();
|
||||
if (set_array_size > 0)
|
||||
{
|
||||
uint32_t unavailable_count = 0;
|
||||
const RegisterSet * const reg_set = reg_context->GetRegisterSet(set_idx);
|
||||
output_stream.Printf ("%s:\n", reg_set->name);
|
||||
output_stream.IndentMore ();
|
||||
const uint32_t num_registers = reg_set->num_registers;
|
||||
for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx)
|
||||
for (uint32_t i=0; i<set_array_size; ++i)
|
||||
{
|
||||
uint32_t reg = reg_set->registers[reg_idx];
|
||||
reg_info = reg_context->GetRegisterInfoAtIndex(reg);
|
||||
if (reg_context->ReadRegisterBytes(reg, reg_data))
|
||||
set_idx = m_options.set_indexes.GetUInt64ValueAtIndex (i, UINT32_MAX, NULL);
|
||||
if (set_idx != UINT32_MAX)
|
||||
{
|
||||
output_stream.Indent ();
|
||||
output_stream.Printf ("%-12s = ", reg_info ? reg_info->name : "<INVALID REGINFO>");
|
||||
reg_data.Dump(&output_stream, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
|
||||
output_stream.EOL();
|
||||
if (!DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx))
|
||||
{
|
||||
result.AppendErrorWithFormat ("invalid register set index: %u\n", set_idx);
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++unavailable_count;
|
||||
result.AppendError ("invalid register set index\n");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (unavailable_count)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_options.dump_all_sets)
|
||||
num_register_sets = reg_ctx->GetRegisterSetCount();
|
||||
|
||||
for (set_idx = 0; set_idx < num_register_sets; ++set_idx)
|
||||
{
|
||||
output_stream.Indent ();
|
||||
output_stream.Printf("%u registers were unavailable.\n", unavailable_count);
|
||||
DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx);
|
||||
}
|
||||
output_stream.IndentLess ();
|
||||
output_stream.EOL();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *arg_cstr;
|
||||
for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
|
||||
if (m_options.dump_all_sets)
|
||||
{
|
||||
reg_info = reg_context->GetRegisterInfoByName(arg_cstr);
|
||||
|
||||
if (reg_info)
|
||||
result.AppendError ("the --all option can't be used when registers names are supplied as arguments\n");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
else if (m_options.set_indexes.GetSize() > 0)
|
||||
{
|
||||
result.AppendError ("the --set <set> option can't be used when registers names are supplied as arguments\n");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *arg_cstr;
|
||||
for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
|
||||
{
|
||||
output_stream.Printf("%-12s = ", reg_info->name);
|
||||
if (reg_context->ReadRegisterBytes(reg_info->kinds[eRegisterKindLLDB], reg_data))
|
||||
reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr);
|
||||
|
||||
if (reg_info)
|
||||
{
|
||||
reg_data.Dump(&output_stream, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
|
||||
if (!DumpRegister (exe_ctx, strm, reg_ctx, reg_info))
|
||||
strm.Printf("%-12s = error: unavailable\n", reg_info->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
output_stream.PutCString ("error: unavailable");
|
||||
result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr);
|
||||
}
|
||||
output_stream.EOL();
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -157,7 +244,10 @@ protected:
|
|||
{
|
||||
public:
|
||||
CommandOptions (CommandInterpreter &interpreter) :
|
||||
Options(interpreter)
|
||||
Options(interpreter),
|
||||
set_indexes (OptionValue::ConvertTypeToMask (OptionValue::eTypeUInt64)),
|
||||
dump_all_sets (false, false), // Initial and default values are false
|
||||
lookup_addresses (false, false) // Initial and default values are false
|
||||
{
|
||||
OptionParsingStarting();
|
||||
}
|
||||
|
@ -175,7 +265,23 @@ protected:
|
|||
switch (short_option)
|
||||
{
|
||||
case 'f':
|
||||
error = Args::StringToFormat (option_arg, m_format);
|
||||
error = Args::StringToFormat (option_arg, format);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
{
|
||||
OptionValueSP value_sp (OptionValueUInt64::Create (option_arg, error));
|
||||
if (value_sp)
|
||||
set_indexes.AppendValue (value_sp);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
dump_all_sets.SetCurrentValue(true);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
lookup_addresses.SetCurrentValue(true);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -188,7 +294,10 @@ protected:
|
|||
void
|
||||
OptionParsingStarting ()
|
||||
{
|
||||
m_format = eFormatBytes;
|
||||
format = eFormatDefault;
|
||||
set_indexes.Clear();
|
||||
dump_all_sets.Clear();
|
||||
lookup_addresses.Clear();
|
||||
}
|
||||
|
||||
const OptionDefinition*
|
||||
|
@ -202,7 +311,10 @@ protected:
|
|||
static OptionDefinition g_option_table[];
|
||||
|
||||
// Instance variables to hold the values for command options.
|
||||
lldb::Format m_format;
|
||||
lldb::Format format;
|
||||
OptionValueArray set_indexes;
|
||||
OptionValueBoolean dump_all_sets;
|
||||
OptionValueBoolean lookup_addresses;
|
||||
};
|
||||
|
||||
CommandOptions m_options;
|
||||
|
@ -211,13 +323,10 @@ protected:
|
|||
OptionDefinition
|
||||
CommandObjectRegisterRead::CommandOptions::g_option_table[] =
|
||||
{
|
||||
//{ LLDB_OPT_SET_ALL, false, "language", 'l', required_argument, NULL, 0, "[c|c++|objc|objc++]", "Sets the language to use when parsing the expression."},
|
||||
//{ LLDB_OPT_SET_1, false, "format", 'f', required_argument, NULL, 0, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]", "Specify the format that the expression output should use."},
|
||||
{ LLDB_OPT_SET_1, false, "format", 'f', required_argument, NULL, 0, eArgTypeExprFormat, "Specify the format that the expression output should use."},
|
||||
{ LLDB_OPT_SET_2, false, "object-description", 'o', no_argument, NULL, 0, eArgTypeNone, "Print the object description of the value resulting from the expression."},
|
||||
{ LLDB_OPT_SET_ALL, false, "unwind-on-error", 'u', required_argument, NULL, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, breakpoint hit or signal."},
|
||||
{ LLDB_OPT_SET_ALL, false, "debug", 'g', no_argument, NULL, 0, eArgTypeNone, "Enable verbose debug logging of the expression parsing and evaluation."},
|
||||
{ LLDB_OPT_SET_ALL, false, "use-ir", 'i', no_argument, NULL, 0, eArgTypeNone, "[Temporary] Instructs the expression evaluator to use IR instead of ASTs."},
|
||||
{ LLDB_OPT_SET_ALL, false, "format", 'f', required_argument, NULL, 0, eArgTypeExprFormat, "Specify the format to use when dumping register values."},
|
||||
{ LLDB_OPT_SET_ALL, false, "lookup", 'l', no_argument , NULL, 0, eArgTypeNone , "Lookup the register values as addresses and show that each value maps to in the address space."},
|
||||
{ LLDB_OPT_SET_1 , false, "set" , 's', required_argument, NULL, 0, eArgTypeIndex , "Specify which register sets to dump by index."},
|
||||
{ LLDB_OPT_SET_2 , false, "all" , 'a', no_argument , NULL, 0, eArgTypeNone , "Show all register sets."},
|
||||
{ 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL }
|
||||
};
|
||||
|
||||
|
@ -275,9 +384,9 @@ public:
|
|||
{
|
||||
DataExtractor reg_data;
|
||||
ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
|
||||
RegisterContext *reg_context = exe_ctx.GetRegisterContext ();
|
||||
RegisterContext *reg_ctx = exe_ctx.GetRegisterContext ();
|
||||
|
||||
if (reg_context)
|
||||
if (reg_ctx)
|
||||
{
|
||||
if (command.GetArgumentCount() != 2)
|
||||
{
|
||||
|
@ -288,7 +397,7 @@ public:
|
|||
{
|
||||
const char *reg_name = command.GetArgumentAtIndex(0);
|
||||
const char *value_str = command.GetArgumentAtIndex(1);
|
||||
const RegisterInfo *reg_info = reg_context->GetRegisterInfoByName(reg_name);
|
||||
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
|
||||
|
||||
if (reg_info)
|
||||
{
|
||||
|
@ -296,7 +405,7 @@ public:
|
|||
Error error(scalar.SetValueFromCString (value_str, reg_info->encoding, reg_info->byte_size));
|
||||
if (error.Success())
|
||||
{
|
||||
if (reg_context->WriteRegisterValue(reg_info->kinds[eRegisterKindLLDB], scalar))
|
||||
if (reg_ctx->WriteRegisterValue(reg_info->kinds[eRegisterKindLLDB], scalar))
|
||||
{
|
||||
result.SetStatus (eReturnStatusSuccessFinishNoResult);
|
||||
return true;
|
||||
|
|
|
@ -1439,11 +1439,11 @@ DebuggerInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var
|
|||
}
|
||||
else if (var_name == UseExternalEditorVarName ())
|
||||
{
|
||||
UserSettingsController::UpdateBooleanVariable (op, m_use_external_editor, value, err);
|
||||
UserSettingsController::UpdateBooleanVariable (op, m_use_external_editor, value, false, err);
|
||||
}
|
||||
else if (var_name == AutoConfirmName ())
|
||||
{
|
||||
UserSettingsController::UpdateBooleanVariable (op, m_auto_confirm_on, value, err);
|
||||
UserSettingsController::UpdateBooleanVariable (op, m_auto_confirm_on, value, false, err);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -109,15 +109,23 @@ Mangled::Compare (const Mangled& a, const Mangled& b)
|
|||
void
|
||||
Mangled::SetValue (const char *s, bool mangled)
|
||||
{
|
||||
m_mangled.Clear();
|
||||
m_demangled.Clear();
|
||||
|
||||
if (s)
|
||||
{
|
||||
if (mangled)
|
||||
{
|
||||
m_demangled.Clear();
|
||||
m_mangled.SetCString (s);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_demangled.SetCString(s);
|
||||
m_mangled.Clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_demangled.Clear();
|
||||
m_mangled.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2028,32 +2028,51 @@ UserSettingsController::UpdateStringVariable (VarSetOperationType op,
|
|||
|
||||
void
|
||||
UserSettingsController::UpdateBooleanVariable (VarSetOperationType op,
|
||||
bool &bool_var,
|
||||
const char *new_value,
|
||||
bool &bool_value,
|
||||
const char *value_cstr,
|
||||
bool clear_value,
|
||||
Error &err)
|
||||
{
|
||||
if (op != eVarSetOperationAssign)
|
||||
err.SetErrorString ("Invalid operation for Boolean variable. Cannot update value.\n");
|
||||
|
||||
if (new_value && new_value[0])
|
||||
switch (op)
|
||||
{
|
||||
if ((::strcasecmp(new_value, "true") == 0) ||
|
||||
(::strcasecmp(new_value, "yes") == 0) ||
|
||||
(::strcasecmp(new_value, "on") == 0) ||
|
||||
(::strcasecmp(new_value, "1") == 0))
|
||||
bool_var = true;
|
||||
else
|
||||
if ((::strcasecmp(new_value, "false") == 0) ||
|
||||
(::strcasecmp(new_value, "no") == 0) ||
|
||||
(::strcasecmp(new_value, "off") == 0) ||
|
||||
(::strcasecmp(new_value, "0") == 0))
|
||||
bool_var = false;
|
||||
else
|
||||
err.SetErrorStringWithFormat ("Invalid boolean value '%s'\n", new_value);
|
||||
}
|
||||
else
|
||||
err.SetErrorString ("Invalid value. Cannot perform update.\n");
|
||||
case eVarSetOperationReplace:
|
||||
case eVarSetOperationInsertBefore:
|
||||
case eVarSetOperationInsertAfter:
|
||||
case eVarSetOperationRemove:
|
||||
case eVarSetOperationAppend:
|
||||
case eVarSetOperationInvalid:
|
||||
default:
|
||||
err.SetErrorString ("Invalid operation for Boolean variable. Cannot update value.\n");
|
||||
break;
|
||||
|
||||
case eVarSetOperationClear:
|
||||
err.Clear();
|
||||
bool_value = clear_value;
|
||||
break;
|
||||
|
||||
case eVarSetOperationAssign:
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
|
||||
if (value_cstr == NULL)
|
||||
err.SetErrorStringWithFormat ("invalid boolean string value (NULL)\n", value_cstr);
|
||||
else if (value_cstr[0] == '\0')
|
||||
err.SetErrorStringWithFormat ("invalid boolean string value (empty)\n", value_cstr);
|
||||
else
|
||||
{
|
||||
bool new_value = Args::StringToBoolean (value_cstr, false, &success);
|
||||
if (success)
|
||||
{
|
||||
err.Clear();
|
||||
bool_value = new_value;
|
||||
}
|
||||
else
|
||||
err.SetErrorStringWithFormat ("invalid boolean string value: '%s'\n", value_cstr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -23,6 +23,29 @@ using namespace lldb_private;
|
|||
//-------------------------------------------------------------------------
|
||||
// OptionValue
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Get this value as a uint64_t value if it is encoded as a boolean,
|
||||
// uint64_t or int64_t. Other types will cause "fail_value" to be
|
||||
// returned
|
||||
uint64_t
|
||||
OptionValue::GetUInt64Value (uint64_t fail_value, bool *success_ptr)
|
||||
{
|
||||
if (success_ptr)
|
||||
*success_ptr = true;
|
||||
switch (GetType())
|
||||
{
|
||||
case OptionValue::eTypeBoolean: return static_cast<OptionValueBoolean *>(this)->GetCurrentValue();
|
||||
case OptionValue::eTypeSInt64: return static_cast<OptionValueSInt64 *>(this)->GetCurrentValue();
|
||||
case OptionValue::eTypeUInt64: return static_cast<OptionValueUInt64 *>(this)->GetCurrentValue();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (success_ptr)
|
||||
*success_ptr = false;
|
||||
return fail_value;
|
||||
}
|
||||
|
||||
|
||||
OptionValueBoolean *
|
||||
OptionValue::GetAsBooleanValue ()
|
||||
{
|
||||
|
@ -105,17 +128,22 @@ OptionValueBoolean::DumpValue (Stream &strm)
|
|||
strm.PutCString (m_current_value ? "true" : "false");
|
||||
}
|
||||
|
||||
bool
|
||||
Error
|
||||
OptionValueBoolean::SetValueFromCString (const char *value_cstr)
|
||||
{
|
||||
Error error;
|
||||
bool success = false;
|
||||
bool value = Args::StringToBoolean(value_cstr, false, &success);
|
||||
if (success)
|
||||
{
|
||||
m_value_was_set = true;
|
||||
m_current_value = value;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
else
|
||||
{
|
||||
error.SetErrorStringWithFormat ("invalid boolean string value: '%s'\n", value_cstr);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -127,39 +155,62 @@ OptionValueSInt64::DumpValue (Stream &strm)
|
|||
strm.Printf ("%lli", m_current_value);
|
||||
}
|
||||
|
||||
bool
|
||||
Error
|
||||
OptionValueSInt64::SetValueFromCString (const char *value_cstr)
|
||||
{
|
||||
|
||||
Error error;
|
||||
bool success = false;
|
||||
int64_t value = Args::StringToSInt64 (value_cstr, 0, 0, &success);
|
||||
if (success)
|
||||
{
|
||||
m_value_was_set = true;
|
||||
m_current_value = value;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
else
|
||||
{
|
||||
error.SetErrorStringWithFormat ("invalid int64_t string value: '%s'\n", value_cstr);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OptionValueUInt64
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
lldb::OptionValueSP
|
||||
OptionValueUInt64::Create (const char *value_cstr, Error &error)
|
||||
{
|
||||
lldb::OptionValueSP value_sp (new OptionValueUInt64());
|
||||
error = value_sp->SetValueFromCString (value_cstr);
|
||||
if (error.Fail())
|
||||
value_sp.reset();
|
||||
return value_sp;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
OptionValueUInt64::DumpValue (Stream &strm)
|
||||
{
|
||||
strm.Printf ("0x%llx", m_current_value);
|
||||
}
|
||||
|
||||
bool
|
||||
Error
|
||||
OptionValueUInt64::SetValueFromCString (const char *value_cstr)
|
||||
{
|
||||
Error error;
|
||||
bool success = false;
|
||||
uint64_t value = Args::StringToUInt64 (value_cstr, 0, 0, &success);
|
||||
if (success)
|
||||
{
|
||||
m_value_was_set = true;
|
||||
m_current_value = value;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
else
|
||||
{
|
||||
error.SetErrorStringWithFormat ("invalid uint64_t string value: '%s'\n", value_cstr);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -171,11 +222,12 @@ OptionValueString::DumpValue (Stream &strm)
|
|||
strm.Printf ("\"%s\"", m_current_value.c_str());
|
||||
}
|
||||
|
||||
bool
|
||||
Error
|
||||
OptionValueString::SetValueFromCString (const char *value_cstr)
|
||||
{
|
||||
m_value_was_set = true;
|
||||
SetCurrentValue (value_cstr);
|
||||
return true;
|
||||
return Error ();
|
||||
}
|
||||
|
||||
|
||||
|
@ -202,14 +254,15 @@ OptionValueFileSpec::DumpValue (Stream &strm)
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Error
|
||||
OptionValueFileSpec::SetValueFromCString (const char *value_cstr)
|
||||
{
|
||||
if (value_cstr && value_cstr[0])
|
||||
m_current_value.SetFile(value_cstr, false);
|
||||
else
|
||||
m_current_value.Clear();
|
||||
return true;
|
||||
m_value_was_set = true;
|
||||
return Error();
|
||||
}
|
||||
|
||||
|
||||
|
@ -227,13 +280,25 @@ OptionValueArray::DumpValue (Stream &strm)
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Error
|
||||
OptionValueArray::SetValueFromCString (const char *value_cstr)
|
||||
{
|
||||
// We must be able to set this using the array specific functions
|
||||
return false;
|
||||
Error error;
|
||||
error.SetErrorStringWithFormat ("array option values don't yet support being set by string: '%s'\n", value_cstr);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
uint64_t
|
||||
OptionValueArray::GetUInt64ValueAtIndex (uint32_t idx, uint64_t fail_value, bool *success_ptr) const
|
||||
{
|
||||
if (idx < m_values.size())
|
||||
return m_values[idx]->GetUInt64Value (fail_value, success_ptr);
|
||||
return fail_value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// OptionValueDictionary
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -249,11 +314,12 @@ OptionValueDictionary::DumpValue (Stream &strm)
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Error
|
||||
OptionValueDictionary::SetValueFromCString (const char *value_cstr)
|
||||
{
|
||||
// We must be able to set this using the array specific functions
|
||||
return false;
|
||||
Error error;
|
||||
error.SetErrorStringWithFormat ("dictionary option values don't yet support being set by string: '%s'\n", value_cstr);
|
||||
return error;
|
||||
}
|
||||
|
||||
lldb::OptionValueSP
|
||||
|
|
|
@ -4062,9 +4062,9 @@ ProcessInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_
|
|||
else if (var_name == ErrorPathVarName())
|
||||
UserSettingsController::UpdateStringVariable (op, m_error_path, value, err);
|
||||
else if (var_name == DisableASLRVarName())
|
||||
UserSettingsController::UpdateBooleanVariable (op, m_disable_aslr, value, err);
|
||||
UserSettingsController::UpdateBooleanVariable (op, m_disable_aslr, value, true, err);
|
||||
else if (var_name == DisableSTDIOVarName ())
|
||||
UserSettingsController::UpdateBooleanVariable (op, m_disable_stdio, value, err);
|
||||
UserSettingsController::UpdateBooleanVariable (op, m_disable_stdio, value, false, err);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1290,6 +1290,7 @@ Target::SettingsController::CreateInstanceSettings (const char *instance_name)
|
|||
#define TSC_DEFAULT_ARCH "default-arch"
|
||||
#define TSC_EXPR_PREFIX "expr-prefix"
|
||||
#define TSC_PREFER_DYNAMIC "prefer-dynamic-value"
|
||||
#define TSC_SKIP_PROLOGUE "skip-prologue"
|
||||
|
||||
|
||||
static const ConstString &
|
||||
|
@ -1315,6 +1316,15 @@ GetSettingNameForPreferDynamicValue ()
|
|||
}
|
||||
|
||||
|
||||
static const ConstString &
|
||||
GetSettingNameForSkipPrologue ()
|
||||
{
|
||||
static ConstString g_const_string (TSC_SKIP_PROLOGUE);
|
||||
return g_const_string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
Target::SettingsController::SetGlobalVariable (const ConstString &var_name,
|
||||
const char *index_value,
|
||||
|
@ -1364,7 +1374,8 @@ TargetInstanceSettings::TargetInstanceSettings
|
|||
InstanceSettings (owner, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance),
|
||||
m_expr_prefix_path (),
|
||||
m_expr_prefix_contents (),
|
||||
m_prefer_dynamic_value (true)
|
||||
m_prefer_dynamic_value (true),
|
||||
m_skip_prologue (true)
|
||||
{
|
||||
// CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called
|
||||
// until the vtables for TargetInstanceSettings are properly set up, i.e. AFTER all the initializers.
|
||||
|
@ -1381,7 +1392,6 @@ TargetInstanceSettings::TargetInstanceSettings
|
|||
{
|
||||
const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name);
|
||||
CopyInstanceSettings (pending_settings,false);
|
||||
//m_owner.RemovePendingSettings (m_instance_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1392,7 +1402,6 @@ TargetInstanceSettings::TargetInstanceSettings (const TargetInstanceSettings &rh
|
|||
{
|
||||
const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name);
|
||||
CopyInstanceSettings (pending_settings,false);
|
||||
//m_owner.RemovePendingSettings (m_instance_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1464,36 +1473,11 @@ TargetInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_n
|
|||
}
|
||||
else if (var_name == GetSettingNameForPreferDynamicValue())
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
default:
|
||||
err.SetErrorToGenericError ();
|
||||
err.SetErrorString ("Unrecognized operation. Cannot update value.\n");
|
||||
return;
|
||||
case eVarSetOperationAssign:
|
||||
{
|
||||
bool success;
|
||||
bool result = Args::StringToBoolean(value, false, &success);
|
||||
|
||||
if (success)
|
||||
{
|
||||
m_prefer_dynamic_value = result;
|
||||
}
|
||||
else
|
||||
{
|
||||
err.SetErrorStringWithFormat ("Bad value \"%s\" for %s, should be Boolean.",
|
||||
value,
|
||||
GetSettingNameForPreferDynamicValue().AsCString());
|
||||
}
|
||||
return;
|
||||
}
|
||||
case eVarSetOperationClear:
|
||||
m_prefer_dynamic_value = true;
|
||||
case eVarSetOperationAppend:
|
||||
err.SetErrorToGenericError ();
|
||||
err.SetErrorString ("Cannot append to a bool.\n");
|
||||
return;
|
||||
}
|
||||
UserSettingsController::UpdateBooleanVariable (op, m_prefer_dynamic_value, value, true, err);
|
||||
}
|
||||
else if (var_name == GetSettingNameForSkipPrologue())
|
||||
{
|
||||
UserSettingsController::UpdateBooleanVariable (op, m_skip_prologue, value, true, err);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1527,6 +1511,13 @@ TargetInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
|
|||
else
|
||||
value.AppendString ("false");
|
||||
}
|
||||
else if (var_name == GetSettingNameForSkipPrologue())
|
||||
{
|
||||
if (m_skip_prologue)
|
||||
value.AppendString ("true");
|
||||
else
|
||||
value.AppendString ("false");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (err)
|
||||
|
@ -1570,5 +1561,6 @@ Target::SettingsController::instance_settings_table[] =
|
|||
// ================= ================== =========== ==== ====== ====== =========================================================================
|
||||
{ TSC_EXPR_PREFIX , eSetVarTypeString , NULL , NULL, false, false, "Path to a file containing expressions to be prepended to all expressions." },
|
||||
{ TSC_PREFER_DYNAMIC, eSetVarTypeBoolean ,"true" , NULL, false, false, "Should printed values be shown as their dynamic value." },
|
||||
{ TSC_SKIP_PROLOGUE , eSetVarTypeBoolean ,"true" , NULL, false, false, "Skip function prologues when setting breakpoints by name." },
|
||||
{ NULL , eSetVarTypeNone , NULL , NULL, false, false, NULL }
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue