Many improvements to the Platform base class and subclasses. The base Platform
class now implements the Host functionality for a lot of things that make
sense by default so that subclasses can check:
int
PlatformSubclass::Foo ()
{
if (IsHost())
return Platform::Foo (); // Let the platform base class do the host specific stuff
// Platform subclass specific code...
int result = ...
return result;
}
Added new functions to the platform:
virtual const char *Platform::GetUserName (uint32_t uid);
virtual const char *Platform::GetGroupName (uint32_t gid);
The user and group names are cached locally so that remote platforms can avoid
sending packets multiple times to resolve this information.
Added the parent process ID to the ProcessInfo class.
Added a new ProcessInfoMatch class which helps us to match processes up
and changed the Host layer over to using this new class. The new class allows
us to search for processs:
1 - by name (equal to, starts with, ends with, contains, and regex)
2 - by pid
3 - And further check for parent pid == value, uid == value, gid == value,
euid == value, egid == value, arch == value, parent == value.
This is all hookup up to the "platform process list" command which required
adding dumping routines to dump process information. If the Host class
implements the process lookup routines, you can now lists processes on
your local machine:
machine1.foo.com % lldb
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
94727 244 username usergroup username usergroup x86_64-apple-darwin Xcode
92742 92710 username usergroup username usergroup i386-apple-darwin debugserver
This of course also works remotely with the lldb-platform:
machine1.foo.com % lldb-platform --listen 1234
machine2.foo.com % lldb
(lldb) platform create remote-macosx
Platform: remote-macosx
Connected: no
(lldb) platform connect connect://localhost:1444
Platform: remote-macosx
Triple: x86_64-apple-darwin
OS Version: 10.6.7 (10J869)
Kernel: Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386
Hostname: machine1.foo.com
Connected: yes
(lldb) platform process list
PID PARENT USER GROUP EFF USER EFF GROUP TRIPLE NAME
====== ====== ========== ========== ========== ========== ======================== ============================
99556 244 username usergroup username usergroup x86_64-apple-darwin trustevaluation
99548 65539 username usergroup username usergroup x86_64-apple-darwin lldb
99538 1 username usergroup username usergroup x86_64-apple-darwin FileMerge
94943 1 username usergroup username usergroup x86_64-apple-darwin mdworker
94852 244 username usergroup username usergroup x86_64-apple-darwin Safari
The lldb-platform implements everything with the Host:: layer, so this should
"just work" for linux. I will probably be adding more stuff to the Host layer
for launching processes and attaching to processes so that this support should
eventually just work as well.
Modified the target to be able to be created with an architecture that differs
from the main executable. This is needed for iOS debugging since we can have
an "armv6" binary which can run on an "armv7" machine, so we want to be able
to do:
% lldb
(lldb) platform create remote-ios
(lldb) file --arch armv7 a.out
Where "a.out" is an armv6 executable. The platform then can correctly decide
to open all "armv7" images for all dependent shared libraries.
Modified the disassembly to show the current PC value. Example output:
(lldb) disassemble --frame
a.out`main:
0x1eb7: pushl %ebp
0x1eb8: movl %esp, %ebp
0x1eba: pushl %ebx
0x1ebb: subl $20, %esp
0x1ebe: calll 0x1ec3 ; main + 12 at test.c:18
0x1ec3: popl %ebx
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
0x1edb: leal 213(%ebx), %eax
0x1ee1: movl %eax, (%esp)
0x1ee4: calll 0x1f1e ; puts
0x1ee9: calll 0x1f0c ; getchar
0x1eee: movl $20, (%esp)
0x1ef5: calll 0x1e6a ; sleep_loop at test.c:6
0x1efa: movl $12, %eax
0x1eff: addl $20, %esp
0x1f02: popl %ebx
0x1f03: leave
0x1f04: ret
This can be handy when dealing with the new --line options that was recently
added:
(lldb) disassemble --line
a.out`main + 13 at test.c:19
18 {
-> 19 printf("Process: %i\n\n", getpid());
20 puts("Press any key to continue..."); getchar();
-> 0x1ec4: calll 0x1f12 ; getpid
0x1ec9: movl %eax, 4(%esp)
0x1ecd: leal 199(%ebx), %eax
0x1ed3: movl %eax, (%esp)
0x1ed6: calll 0x1f18 ; printf
Modified the ModuleList to have a lookup based solely on a UUID. Since the
UUID is typically the MD5 checksum of a binary image, there is no need
to give the path and architecture when searching for a pre-existing
image in an image list.
Now that we support remote debugging a bit better, our lldb_private::Module
needs to be able to track what the original path for file was as the platform
knows it, as well as where the file is locally. The module has the two
following functions to retrieve both paths:
const FileSpec &Module::GetFileSpec () const;
const FileSpec &Module::GetPlatformFileSpec () const;
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@128563 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Commands/CommandObjectArgs.cpp b/source/Commands/CommandObjectArgs.cpp
index 6810b45..f75ac0b 100644
--- a/source/Commands/CommandObjectArgs.cpp
+++ b/source/Commands/CommandObjectArgs.cpp
@@ -68,7 +68,6 @@
void
CommandObjectArgs::CommandOptions::ResetOptionValues ()
{
- Options::ResetOptionValues();
}
const OptionDefinition*
diff --git a/source/Commands/CommandObjectBreakpoint.cpp b/source/Commands/CommandObjectBreakpoint.cpp
index 6bf408b..8208ea8 100644
--- a/source/Commands/CommandObjectBreakpoint.cpp
+++ b/source/Commands/CommandObjectBreakpoint.cpp
@@ -235,8 +235,6 @@
void
CommandObjectBreakpointSet::CommandOptions::ResetOptionValues ()
{
- Options::ResetOptionValues();
-
m_filename.clear();
m_line_num = 0;
m_column = 0;
@@ -706,8 +704,6 @@
void
CommandObjectBreakpointList::CommandOptions::ResetOptionValues ()
{
- Options::ResetOptionValues();
-
m_level = lldb::eDescriptionLevelBrief;
m_internal = false;
}
@@ -1105,8 +1101,6 @@
void
CommandObjectBreakpointClear::CommandOptions::ResetOptionValues ()
{
- Options::ResetOptionValues();
-
m_filename.clear();
m_line_num = 0;
}
@@ -1485,8 +1479,6 @@
void
CommandObjectBreakpointModify::CommandOptions::ResetOptionValues ()
{
- Options::ResetOptionValues();
-
m_ignore_count = 0;
m_thread_id = LLDB_INVALID_THREAD_ID;
m_thread_id_passed = false;
diff --git a/source/Commands/CommandObjectBreakpointCommand.cpp b/source/Commands/CommandObjectBreakpointCommand.cpp
index 3af812c..c3d50ea 100644
--- a/source/Commands/CommandObjectBreakpointCommand.cpp
+++ b/source/Commands/CommandObjectBreakpointCommand.cpp
@@ -135,8 +135,6 @@
void
CommandObjectBreakpointCommandAdd::CommandOptions::ResetOptionValues ()
{
- Options::ResetOptionValues();
-
m_use_commands = true;
m_use_script_language = false;
m_script_language = eScriptLanguageNone;
diff --git a/source/Commands/CommandObjectCommands.cpp b/source/Commands/CommandObjectCommands.cpp
index 49fc022..b3a974b 100644
--- a/source/Commands/CommandObjectCommands.cpp
+++ b/source/Commands/CommandObjectCommands.cpp
@@ -69,8 +69,6 @@
void
ResetOptionValues ()
{
- Options::ResetOptionValues();
-
m_stop_on_error = true;
m_stop_on_continue = true;
}
@@ -358,7 +356,7 @@
if (options)
{
// See if any options were specified as part of the alias; if so, handle them appropriately
- options->ResetOptionValues ();
+ options->Reset ();
Args tmp_args (raw_command_string.c_str());
args.Unshift ("dummy_arg");
args.ParseAliasOptions (*options, result, option_arg_vector, raw_command_string);
@@ -489,7 +487,7 @@
options = sub_cmd_obj->GetOptions();
else
options = cmd_obj->GetOptions();
- options->ResetOptionValues ();
+ options->Reset ();
std::string empty_string;
args.Unshift ("dummy_arg");
args.ParseAliasOptions (*options, result, option_arg_vector, empty_string);
diff --git a/source/Commands/CommandObjectDisassemble.cpp b/source/Commands/CommandObjectDisassemble.cpp
index 74c27e3..6567a08 100644
--- a/source/Commands/CommandObjectDisassemble.cpp
+++ b/source/Commands/CommandObjectDisassemble.cpp
@@ -36,12 +36,13 @@
Options(),
num_lines_context(0),
num_instructions (0),
- m_func_name(),
- m_start_addr(),
- m_end_addr (),
- m_at_pc (false),
- m_plugin_name (),
- m_arch()
+ func_name(),
+ start_addr(),
+ end_addr (),
+ at_pc (false),
+ frame_line (false),
+ plugin_name (),
+ arch()
{
ResetOptionValues();
}
@@ -82,32 +83,39 @@
break;
case 's':
- m_start_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
- if (m_start_addr == LLDB_INVALID_ADDRESS)
- m_start_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
+ start_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
+ if (start_addr == LLDB_INVALID_ADDRESS)
+ start_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
- if (m_start_addr == LLDB_INVALID_ADDRESS)
+ if (start_addr == LLDB_INVALID_ADDRESS)
error.SetErrorStringWithFormat ("Invalid start address string '%s'.\n", option_arg);
break;
case 'e':
- m_end_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
- if (m_end_addr == LLDB_INVALID_ADDRESS)
- m_end_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
+ end_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
+ if (end_addr == LLDB_INVALID_ADDRESS)
+ end_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
- if (m_end_addr == LLDB_INVALID_ADDRESS)
+ if (end_addr == LLDB_INVALID_ADDRESS)
error.SetErrorStringWithFormat ("Invalid end address string '%s'.\n", option_arg);
break;
case 'n':
- m_func_name.assign (option_arg);
+ func_name.assign (option_arg);
break;
case 'p':
- m_at_pc = true;
+ at_pc = true;
+ break;
+
+ case 'l':
+ frame_line = true;
+ // Disassemble the current source line kind of implies showing mixed
+ // source code context.
+ show_mixed = true;
break;
case 'P':
- m_plugin_name.assign (option_arg);
+ plugin_name.assign (option_arg);
break;
case 'r':
@@ -120,7 +128,7 @@
break;
case 'a':
- m_arch.SetTriple (option_arg);
+ arch.SetTriple (option_arg);
break;
default:
@@ -134,18 +142,18 @@
void
CommandObjectDisassemble::CommandOptions::ResetOptionValues ()
{
- Options::ResetOptionValues();
show_mixed = false;
show_bytes = false;
num_lines_context = 0;
num_instructions = 0;
- m_func_name.clear();
- m_at_pc = false;
- m_start_addr = LLDB_INVALID_ADDRESS;
- m_end_addr = LLDB_INVALID_ADDRESS;
+ func_name.clear();
+ at_pc = false;
+ frame_line = false;
+ start_addr = LLDB_INVALID_ADDRESS;
+ end_addr = LLDB_INVALID_ADDRESS;
raw = false;
- m_plugin_name.clear();
- m_arch.Clear();
+ plugin_name.clear();
+ arch.Clear();
}
const OptionDefinition*
@@ -172,7 +180,8 @@
LLDB_OPT_SET_5 , false , "count", 'c', required_argument , NULL, 0, eArgTypeNumLines, "Number of instructions to display."},
{ LLDB_OPT_SET_3 , true , "name", 'n', required_argument , NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Disassemble entire contents of the given function name."},
{ LLDB_OPT_SET_4 , true , "frame", 'f', no_argument , NULL, 0, eArgTypeNone, "Disassemble from the start of the current frame's function."},
-{ LLDB_OPT_SET_5 , true , "pc", 'p', no_argument , NULL, 0, eArgTypeNone, "Disassemble from the current pc."},
+{ LLDB_OPT_SET_5 , true , "pc", 'p', no_argument , NULL, 0, eArgTypeNone, "Disassemble around the current pc."},
+{ LLDB_OPT_SET_6 , true , "line", 'l', no_argument , NULL, 0, eArgTypeNone, "Disassemble the current frame's current source line instructions if there debug line table information, else disasemble around the pc."},
{ 0 , false , NULL, 0, 0 , NULL, 0, eArgTypeNone, NULL }
};
@@ -208,10 +217,10 @@
result.SetStatus (eReturnStatusFailed);
return false;
}
- if (!m_options.m_arch.IsValid())
- m_options.m_arch = target->GetArchitecture();
+ if (!m_options.arch.IsValid())
+ m_options.arch = target->GetArchitecture();
- if (!m_options.m_arch.IsValid())
+ if (!m_options.arch.IsValid())
{
result.AppendError ("use the --arch option or set the target architecure to disassemble");
result.SetStatus (eReturnStatusFailed);
@@ -219,17 +228,17 @@
}
const char *plugin_name = m_options.GetPluginName ();
- Disassembler *disassembler = Disassembler::FindPlugin(m_options.m_arch, plugin_name);
+ Disassembler *disassembler = Disassembler::FindPlugin(m_options.arch, plugin_name);
if (disassembler == NULL)
{
if (plugin_name)
result.AppendErrorWithFormat ("Unable to find Disassembler plug-in named '%s' that supports the '%s' architecture.\n",
plugin_name,
- m_options.m_arch.GetArchitectureName());
+ m_options.arch.GetArchitectureName());
else
result.AppendErrorWithFormat ("Unable to find Disassembler plug-in for the '%s' architecture.\n",
- m_options.m_arch.GetArchitectureName());
+ m_options.arch.GetArchitectureName());
result.SetStatus (eReturnStatusFailed);
return false;
}
@@ -252,12 +261,12 @@
ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
- if (!m_options.m_func_name.empty())
+ if (!m_options.func_name.empty())
{
- ConstString name(m_options.m_func_name.c_str());
+ ConstString name(m_options.func_name.c_str());
if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
- m_options.m_arch,
+ m_options.arch,
plugin_name,
exe_ctx,
name,
@@ -278,59 +287,76 @@
}
else
{
- Address start_addr;
- lldb::addr_t range_byte_size = DEFAULT_DISASM_BYTE_SIZE;
-
- if (m_options.m_at_pc)
+ AddressRange range;
+ if (m_options.frame_line)
{
- if (exe_ctx.frame == NULL)
+ LineEntry pc_line_entry (exe_ctx.frame->GetSymbolContext(eSymbolContextLineEntry).line_entry);
+ if (pc_line_entry.IsValid())
{
- result.AppendError ("Cannot disassemble around the current PC without a selected frame.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
+ range = pc_line_entry.range;
}
- start_addr = exe_ctx.frame->GetFrameCodeAddress();
- if (m_options.num_instructions == 0)
+ else
{
- // Disassembling at the PC always disassembles some number of instructions (not the whole function).
- m_options.num_instructions = DEFAULT_DISASM_NUM_INS;
+ m_options.at_pc = true; // No line entry, so just disassemble around the current pc
+ m_options.show_mixed = false;
}
}
- else
+
+ // Did the "m_options.frame_line" find a valid range already? If so
+ // skip the rest...
+ if (range.GetByteSize() == 0)
{
- start_addr.SetOffset (m_options.m_start_addr);
- if (start_addr.IsValid())
+ if (m_options.at_pc)
{
- if (m_options.m_end_addr != LLDB_INVALID_ADDRESS)
+ if (exe_ctx.frame == NULL)
{
- if (m_options.m_end_addr < m_options.m_start_addr)
+ result.AppendError ("Cannot disassemble around the current PC without a selected frame.\n");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ range.GetBaseAddress() = exe_ctx.frame->GetFrameCodeAddress();
+ if (m_options.num_instructions == 0)
+ {
+ // Disassembling at the PC always disassembles some number of instructions (not the whole function).
+ m_options.num_instructions = DEFAULT_DISASM_NUM_INS;
+ }
+ }
+ else
+ {
+ range.GetBaseAddress().SetOffset (m_options.start_addr);
+ if (range.GetBaseAddress().IsValid())
+ {
+ if (m_options.end_addr != LLDB_INVALID_ADDRESS)
{
- result.AppendErrorWithFormat ("End address before start address.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
+ if (m_options.end_addr <= m_options.start_addr)
+ {
+ result.AppendErrorWithFormat ("End address before start address.\n");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ range.SetByteSize (m_options.end_addr - m_options.start_addr);
}
- range_byte_size = m_options.m_end_addr - m_options.m_start_addr;
}
}
}
if (m_options.num_instructions != 0)
{
- if (!start_addr.IsValid())
+ if (!range.GetBaseAddress().IsValid())
{
// The default action is to disassemble the current frame function.
if (exe_ctx.frame)
{
SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
if (sc.function)
- start_addr = sc.function->GetAddressRange().GetBaseAddress();
+ range.GetBaseAddress() = sc.function->GetAddressRange().GetBaseAddress();
else if (sc.symbol && sc.symbol->GetAddressRangePtr())
- start_addr = sc.symbol->GetAddressRangePtr()->GetBaseAddress();
+ range.GetBaseAddress() = sc.symbol->GetAddressRangePtr()->GetBaseAddress();
else
- start_addr = exe_ctx.frame->GetFrameCodeAddress();
+ range.GetBaseAddress() = exe_ctx.frame->GetFrameCodeAddress();
}
- if (!start_addr.IsValid())
+ if (!range.GetBaseAddress().IsValid())
{
result.AppendError ("invalid frame");
result.SetStatus (eReturnStatusFailed);
@@ -339,10 +365,10 @@
}
if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
- m_options.m_arch,
+ m_options.arch,
plugin_name,
exe_ctx,
- start_addr,
+ range.GetBaseAddress(),
m_options.num_instructions,
m_options.show_mixed ? m_options.num_lines_context : 0,
m_options.show_bytes,
@@ -353,19 +379,13 @@
}
else
{
- result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8llx.\n", m_options.m_start_addr);
+ result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8llx.\n", m_options.start_addr);
result.SetStatus (eReturnStatusFailed);
}
}
else
{
- AddressRange range;
- if (start_addr.IsValid())
- {
- range.GetBaseAddress() = start_addr;
- range.SetByteSize (range_byte_size);
- }
- else
+ if (!range.GetBaseAddress().IsValid())
{
// The default action is to disassemble the current frame function.
if (exe_ctx.frame)
@@ -389,7 +409,7 @@
range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);
if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
- m_options.m_arch,
+ m_options.arch,
plugin_name,
exe_ctx,
range,
@@ -403,7 +423,7 @@
}
else
{
- result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8llx.\n", m_options.m_start_addr);
+ result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8llx.\n", m_options.start_addr);
result.SetStatus (eReturnStatusFailed);
}
}
diff --git a/source/Commands/CommandObjectDisassemble.h b/source/Commands/CommandObjectDisassemble.h
index 42ede79..46b4bac 100644
--- a/source/Commands/CommandObjectDisassemble.h
+++ b/source/Commands/CommandObjectDisassemble.h
@@ -47,9 +47,9 @@
const char *
GetPluginName ()
{
- if (m_plugin_name.empty())
+ if (plugin_name.empty())
return NULL;
- return m_plugin_name.c_str();
+ return plugin_name.c_str();
}
@@ -58,12 +58,13 @@
uint32_t num_lines_context;
uint32_t num_instructions;
bool raw;
- std::string m_func_name;
- lldb::addr_t m_start_addr;
- lldb::addr_t m_end_addr;
- bool m_at_pc;
- std::string m_plugin_name;
- ArchSpec m_arch;
+ std::string func_name;
+ lldb::addr_t start_addr;
+ lldb::addr_t end_addr;
+ bool at_pc;
+ bool frame_line;
+ std::string plugin_name;
+ ArchSpec arch;
static OptionDefinition g_option_table[];
};
diff --git a/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp
index e7b1183..fd9271b 100644
--- a/source/Commands/CommandObjectExpression.cpp
+++ b/source/Commands/CommandObjectExpression.cpp
@@ -95,7 +95,6 @@
void
CommandObjectExpression::CommandOptions::ResetOptionValues ()
{
- Options::ResetOptionValues();
//language.Clear();
debug = false;
format = eFormatDefault;
@@ -298,7 +297,7 @@
{
m_exe_ctx = m_interpreter.GetDebugger().GetExecutionContext();
- m_options.ResetOptionValues();
+ m_options.Reset();
const char * expr = NULL;
diff --git a/source/Commands/CommandObjectFile.cpp b/source/Commands/CommandObjectFile.cpp
index 7d17af9..6f1267e 100644
--- a/source/Commands/CommandObjectFile.cpp
+++ b/source/Commands/CommandObjectFile.cpp
@@ -77,7 +77,6 @@
void
CommandObjectFile::CommandOptions::ResetOptionValues ()
{
- Options::ResetOptionValues();
m_arch.Clear();
}
diff --git a/source/Commands/CommandObjectFrame.cpp b/source/Commands/CommandObjectFrame.cpp
index 8efb164..25f7638 100644
--- a/source/Commands/CommandObjectFrame.cpp
+++ b/source/Commands/CommandObjectFrame.cpp
@@ -135,7 +135,6 @@
void
ResetOptionValues ()
{
- Options::ResetOptionValues();
relative_frame_offset = INT32_MIN;
}
@@ -352,8 +351,6 @@
void
ResetOptionValues ()
{
- Options::ResetOptionValues();
-
use_objc = false;
use_regex = false;
show_args = true;
diff --git a/source/Commands/CommandObjectImage.cpp b/source/Commands/CommandObjectImage.cpp
index ed19647..d684bb2 100644
--- a/source/Commands/CommandObjectImage.cpp
+++ b/source/Commands/CommandObjectImage.cpp
@@ -763,7 +763,6 @@
void
ResetOptionValues ()
{
- Options::ResetOptionValues();
m_sort_order = eSortOrderNone;
}
@@ -1167,7 +1166,6 @@
void
ResetOptionValues ()
{
- Options::ResetOptionValues();
m_format_array.clear();
}
@@ -1429,7 +1427,6 @@
void
ResetOptionValues ()
{
- Options::ResetOptionValues();
m_type = eLookupTypeInvalid;
m_str.clear();
m_file.Clear();
diff --git a/source/Commands/CommandObjectLog.cpp b/source/Commands/CommandObjectLog.cpp
index d49485a..383e299 100644
--- a/source/Commands/CommandObjectLog.cpp
+++ b/source/Commands/CommandObjectLog.cpp
@@ -208,7 +208,6 @@
void
ResetOptionValues ()
{
- Options::ResetOptionValues();
log_file.clear();
log_options = 0;
}
diff --git a/source/Commands/CommandObjectMemory.cpp b/source/Commands/CommandObjectMemory.cpp
index 4225f86..f63848c 100644
--- a/source/Commands/CommandObjectMemory.cpp
+++ b/source/Commands/CommandObjectMemory.cpp
@@ -164,7 +164,6 @@
void
ResetOptionValues ()
{
- Options::ResetOptionValues();
m_format = eFormatBytesWithASCII;
m_byte_size = 0;
m_count = 0;
@@ -493,7 +492,6 @@
void
ResetOptionValues ()
{
- Options::ResetOptionValues();
m_format = eFormatBytes;
m_byte_size = 1;
m_infile.Clear();
diff --git a/source/Commands/CommandObjectPlatform.cpp b/source/Commands/CommandObjectPlatform.cpp
index 0e321d0..b57a51b 100644
--- a/source/Commands/CommandObjectPlatform.cpp
+++ b/source/Commands/CommandObjectPlatform.cpp
@@ -68,7 +68,7 @@
}
else
{
- result.AppendError ("command not implemented\n");
+ result.AppendError ("platform create takes a platform name as an argument\n");
result.SetStatus (eReturnStatusFailed);
}
return result.Succeeded();
@@ -409,6 +409,308 @@
};
+//----------------------------------------------------------------------
+// "platform process list"
+//----------------------------------------------------------------------
+class CommandObjectPlatformProcessList : public CommandObject
+{
+public:
+ CommandObjectPlatformProcessList (CommandInterpreter &interpreter) :
+ CommandObject (interpreter,
+ "platform process list",
+ "List processes on a remote platform by name, pid, or many other matching attributes.",
+ "platform process list",
+ 0)
+ {
+ }
+
+ virtual
+ ~CommandObjectPlatformProcessList ()
+ {
+ }
+
+ virtual bool
+ Execute (Args& args, CommandReturnObject &result)
+ {
+ PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform());
+
+ if (platform_sp)
+ {
+ Error error;
+ if (args.GetArgumentCount() == 0)
+ {
+
+ if (platform_sp)
+ {
+ lldb::pid_t pid = m_options.match_info.GetProcessInfo().GetProcessID();
+ if (pid != LLDB_INVALID_PROCESS_ID)
+ {
+ ProcessInfo proc_info;
+ if (platform_sp->GetProcessInfo (pid, proc_info))
+ {
+ proc_info.Dump (result.GetOutputStream(), platform_sp.get());
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ }
+ else
+ {
+ result.AppendErrorWithFormat ("no process found with pid = %i\n", pid);
+ result.SetStatus (eReturnStatusFailed);
+ }
+ }
+ else
+ {
+ ProcessInfoList proc_infos;
+ const uint32_t matches = platform_sp->FindProcesses (m_options.match_info, proc_infos);
+ if (matches == 0)
+ {
+ const char *match_desc = NULL;
+ const char *match_name = m_options.match_info.GetProcessInfo().GetName();
+ if (match_name && match_name[0])
+ {
+ switch (m_options.match_info.GetNameMatchType())
+ {
+ case eNameMatchIgnore: break;
+ case eNameMatchEquals: match_desc = "match"; break;
+ case eNameMatchContains: match_desc = "contains"; break;
+ case eNameMatchStartsWith: match_desc = "starts with"; break;
+ case eNameMatchEndsWith: match_desc = "end with"; break;
+ case eNameMatchRegularExpression: match_desc = "match the regular expression"; break;
+ }
+ }
+ if (match_desc)
+ result.AppendErrorWithFormat ("no processes were found that %s \"%s\" on the \"%s\" platform\n",
+ match_desc,
+ match_name,
+ platform_sp->GetShortPluginName());
+ else
+ result.AppendErrorWithFormat ("no processes were found on the \"%s\" platform\n", platform_sp->GetShortPluginName());
+ result.SetStatus (eReturnStatusFailed);
+ }
+ else
+ {
+ Stream &ostrm = result.GetOutputStream();
+
+ ProcessInfo::DumpTableHeader (ostrm, platform_sp.get());
+ for (uint32_t i=0; i<matches; ++i)
+ {
+ proc_infos.GetProcessInfoAtIndex(i).DumpAsTableRow(ostrm, platform_sp.get());
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ result.AppendError ("invalid args: process list takes only options\n");
+ result.SetStatus (eReturnStatusFailed);
+ }
+ }
+ else
+ {
+ result.AppendError ("no platform is selected\n");
+ result.SetStatus (eReturnStatusFailed);
+ }
+ return result.Succeeded();
+ }
+
+ virtual Options *
+ GetOptions ()
+ {
+ return &m_options;
+ }
+
+protected:
+
+ class CommandOptions : public Options
+ {
+ public:
+
+ CommandOptions () :
+ match_info ()
+ {
+ }
+
+ virtual
+ ~CommandOptions ()
+ {
+ }
+
+ virtual Error
+ SetOptionValue (int option_idx, const char *option_arg)
+ {
+ Error error;
+ char short_option = (char) m_getopt_table[option_idx].val;
+ bool success = false;
+
+ switch (short_option)
+ {
+ case 'p':
+ match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
+ if (!success)
+ error.SetErrorStringWithFormat("invalid process ID string: '%s'", option_arg);
+ break;
+
+ case 'P':
+ match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success));
+ if (!success)
+ error.SetErrorStringWithFormat("invalid parent process ID string: '%s'", option_arg);
+ break;
+
+ case 'u':
+ match_info.GetProcessInfo().SetRealUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
+ if (!success)
+ error.SetErrorStringWithFormat("invalid user ID string: '%s'", option_arg);
+ break;
+
+ case 'U':
+ match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
+ if (!success)
+ error.SetErrorStringWithFormat("invalid effective user ID string: '%s'", option_arg);
+ break;
+
+ case 'g':
+ match_info.GetProcessInfo().SetRealGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
+ if (!success)
+ error.SetErrorStringWithFormat("invalid group ID string: '%s'", option_arg);
+ break;
+
+ case 'G':
+ match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success));
+ if (!success)
+ error.SetErrorStringWithFormat("invalid effective group ID string: '%s'", option_arg);
+ break;
+
+ case 'a':
+ match_info.GetProcessInfo().GetArchitecture().SetTriple (option_arg);
+ break;
+
+ case 'n':
+ match_info.GetProcessInfo().SetName (option_arg);
+ if (match_info.GetNameMatchType() == eNameMatchIgnore)
+ match_info.SetNameMatchType (eNameMatchEquals);
+ break;
+
+ case 'e':
+ match_info.SetNameMatchType (eNameMatchEndsWith);
+ break;
+
+ case 's':
+ match_info.SetNameMatchType (eNameMatchStartsWith);
+ break;
+
+ case 'c':
+ match_info.SetNameMatchType (eNameMatchContains);
+ break;
+
+ case 'r':
+ match_info.SetNameMatchType (eNameMatchRegularExpression);
+ break;
+
+ default:
+ error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
+ break;
+ }
+
+ return error;
+ }
+
+ void
+ ResetOptionValues ()
+ {
+ match_info.Clear();
+ }
+
+ const OptionDefinition*
+ GetDefinitions ()
+ {
+ return g_option_table;
+ }
+
+ // Options table: Required for subclasses of Options.
+
+ static OptionDefinition g_option_table[];
+
+ // Instance variables to hold the values for command options.
+
+ ProcessInfoMatch match_info;
+ };
+ CommandOptions m_options;
+};
+
+OptionDefinition
+CommandObjectPlatformProcessList::CommandOptions::g_option_table[] =
+{
+{ LLDB_OPT_SET_1, false, "pid" , 'p', required_argument, NULL, 0, eArgTypePid , "List the process info for a specific process ID." },
+{ LLDB_OPT_SET_2|
+ LLDB_OPT_SET_3|
+ LLDB_OPT_SET_4|
+ LLDB_OPT_SET_5, true , "name" , 'n', required_argument, NULL, 0, eArgTypeProcessName , "Find processes that match the supplied name." },
+{ LLDB_OPT_SET_2, false, "ends-with" , 'e', no_argument , NULL, 0, eArgTypeNone , "Process names must end with the name supplied with the --name option." },
+{ LLDB_OPT_SET_3, false, "starts-with" , 's', no_argument , NULL, 0, eArgTypeNone , "Process names must start with the name supplied with the --name option." },
+{ LLDB_OPT_SET_4, false, "contains" , 'c', no_argument , NULL, 0, eArgTypeNone , "Process names must contain the name supplied with the --name option." },
+{ LLDB_OPT_SET_5, false, "regex" , 'r', no_argument , NULL, 0, eArgTypeNone , "Process names must match name supplied with the --name option as a regular expression." },
+{ LLDB_OPT_SET_2|
+ LLDB_OPT_SET_3|
+ LLDB_OPT_SET_4|
+ LLDB_OPT_SET_5|
+ LLDB_OPT_SET_6, false, "parent" , 'P', required_argument, NULL, 0, eArgTypePid , "Find processes that have a matching parent process ID." },
+{ LLDB_OPT_SET_2|
+ LLDB_OPT_SET_3|
+ LLDB_OPT_SET_4|
+ LLDB_OPT_SET_5|
+ LLDB_OPT_SET_6, false, "uid" , 'u', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching user ID." },
+{ LLDB_OPT_SET_2|
+ LLDB_OPT_SET_3|
+ LLDB_OPT_SET_4|
+ LLDB_OPT_SET_5|
+ LLDB_OPT_SET_6, false, "euid" , 'U', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching effective user ID." },
+{ LLDB_OPT_SET_2|
+ LLDB_OPT_SET_3|
+ LLDB_OPT_SET_4|
+ LLDB_OPT_SET_5|
+ LLDB_OPT_SET_6, false, "gid" , 'g', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching group ID." },
+{ LLDB_OPT_SET_2|
+ LLDB_OPT_SET_3|
+ LLDB_OPT_SET_4|
+ LLDB_OPT_SET_5|
+ LLDB_OPT_SET_6, false, "egid" , 'G', required_argument, NULL, 0, eArgTypeNone , "Find processes that have a matching effective group ID." },
+{ LLDB_OPT_SET_2|
+ LLDB_OPT_SET_3|
+ LLDB_OPT_SET_4|
+ LLDB_OPT_SET_5|
+ LLDB_OPT_SET_6, false, "arch" , 'a', required_argument, NULL, 0, eArgTypeArchitecture , "Find processes that have a matching architecture." },
+{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone , NULL }
+};
+
+class CommandObjectPlatformProcess : public CommandObjectMultiword
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ CommandObjectPlatformProcess (CommandInterpreter &interpreter) :
+ CommandObjectMultiword (interpreter,
+ "platform process",
+ "A set of commands to query, launch and attach to platform processes",
+ "platform process [attach|launch|list] ...")
+ {
+// LoadSubCommand ("attach", CommandObjectSP (new CommandObjectPlatformProcessAttach (interpreter)));
+// LoadSubCommand ("launch", CommandObjectSP (new CommandObjectPlatformProcessLaunch (interpreter)));
+ LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformProcessList (interpreter)));
+
+ }
+
+ virtual
+ ~CommandObjectPlatformProcess ()
+ {
+ }
+
+private:
+ //------------------------------------------------------------------
+ // For CommandObjectPlatform only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (CommandObjectPlatformProcess);
+};
//----------------------------------------------------------------------
// CommandObjectPlatform constructor
@@ -425,6 +727,7 @@
LoadSubCommand ("status", CommandObjectSP (new CommandObjectPlatformStatus (interpreter)));
LoadSubCommand ("connect", CommandObjectSP (new CommandObjectPlatformConnect (interpreter)));
LoadSubCommand ("disconnect", CommandObjectSP (new CommandObjectPlatformDisconnect (interpreter)));
+ LoadSubCommand ("process", CommandObjectSP (new CommandObjectPlatformProcess (interpreter)));
}
diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp
index 7eb7c4a..8287481 100644
--- a/source/Commands/CommandObjectProcess.cpp
+++ b/source/Commands/CommandObjectProcess.cpp
@@ -82,7 +82,6 @@
void
ResetOptionValues ()
{
- Options::ResetOptionValues();
stop_at_entry = false;
in_new_tty = false;
tty_name.clear();
@@ -483,7 +482,6 @@
void
ResetOptionValues ()
{
- Options::ResetOptionValues();
pid = LLDB_INVALID_PROCESS_ID;
name.clear();
waitfor = false;
@@ -527,7 +525,13 @@
if (platform_sp)
{
ProcessInfoList process_infos;
- platform_sp->FindProcessesByName (partial_name, partial_name ? eNameMatchStartsWith : eNameMatchIgnore, process_infos);
+ ProcessInfoMatch match_info;
+ if (partial_name)
+ {
+ match_info.GetProcessInfo().SetName(partial_name);
+ match_info.SetNameMatchType(eNameMatchStartsWith);
+ }
+ platform_sp->FindProcesses (match_info, process_infos);
const uint32_t num_matches = process_infos.GetSize();
if (num_matches > 0)
{
@@ -706,7 +710,8 @@
PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform ());
if (platform_sp)
{
- platform_sp->FindProcessesByName (wait_name, eNameMatchEquals, process_infos);
+ ProcessInfoMatch match_info (wait_name, eNameMatchEquals);
+ platform_sp->FindProcesses (match_info, process_infos);
}
if (process_infos.GetSize() > 1)
{
@@ -1011,7 +1016,6 @@
void
ResetOptionValues ()
{
- Options::ResetOptionValues();
plugin_name.clear();
}
@@ -1601,7 +1605,6 @@
void
ResetOptionValues ()
{
- Options::ResetOptionValues();
stop.clear();
notify.clear();
pass.clear();
diff --git a/source/Commands/CommandObjectRegister.cpp b/source/Commands/CommandObjectRegister.cpp
index d9cb5de..55a4782 100644
--- a/source/Commands/CommandObjectRegister.cpp
+++ b/source/Commands/CommandObjectRegister.cpp
@@ -58,6 +58,12 @@
{
}
+ Options *
+ GetOptions ()
+ {
+ return &m_options;
+ }
+
virtual bool
Execute
(
@@ -143,8 +149,77 @@
}
return result.Succeeded();
}
+
+protected:
+ class CommandOptions : public Options
+ {
+ public:
+ CommandOptions () :
+ Options()
+ {
+ ResetOptionValues();
+ }
+
+ virtual
+ ~CommandOptions ()
+ {
+ }
+
+ virtual Error
+ SetOptionValue (int option_idx, const char *option_arg)
+ {
+ Error error;
+ char short_option = (char) m_getopt_table[option_idx].val;
+ switch (short_option)
+ {
+ case 'f':
+ error = Args::StringToFormat (option_arg, m_format);
+ break;
+
+ default:
+ error.SetErrorStringWithFormat("Unrecognized short option '%c'\n", short_option);
+ break;
+ }
+ return error;
+ }
+
+ void
+ ResetOptionValues ()
+ {
+ m_format = eFormatBytes;
+ }
+
+ const OptionDefinition*
+ GetDefinitions ()
+ {
+ return g_option_table;
+ }
+
+ // Options table: Required for subclasses of Options.
+
+ static OptionDefinition g_option_table[];
+
+ // Instance variables to hold the values for command options.
+ lldb::Format m_format;
+ };
+
+ CommandOptions m_options;
};
+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."},
+ { 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL }
+};
+
+
//----------------------------------------------------------------------
// "register write"
diff --git a/source/Commands/CommandObjectSettings.cpp b/source/Commands/CommandObjectSettings.cpp
index 348885d..82a4929 100644
--- a/source/Commands/CommandObjectSettings.cpp
+++ b/source/Commands/CommandObjectSettings.cpp
@@ -287,8 +287,6 @@
void
CommandObjectSettingsSet::CommandOptions::ResetOptionValues ()
{
- Options::ResetOptionValues ();
-
m_override = true;
m_reset = false;
}
diff --git a/source/Commands/CommandObjectSource.cpp b/source/Commands/CommandObjectSource.cpp
index 2c7fb33..7435b85 100644
--- a/source/Commands/CommandObjectSource.cpp
+++ b/source/Commands/CommandObjectSource.cpp
@@ -74,8 +74,6 @@
void
ResetOptionValues ()
{
- Options::ResetOptionValues();
-
file_spec.Clear();
file_name.clear();
start_line = 0;
@@ -200,8 +198,6 @@
void
ResetOptionValues ()
{
- Options::ResetOptionValues();
-
file_spec.Clear();
file_name.clear();
symbol_name.clear();
diff --git a/source/Commands/CommandObjectThread.cpp b/source/Commands/CommandObjectThread.cpp
index 977f63f..d5da880 100644
--- a/source/Commands/CommandObjectThread.cpp
+++ b/source/Commands/CommandObjectThread.cpp
@@ -300,7 +300,6 @@
void
ResetOptionValues ()
{
- Options::ResetOptionValues();
m_count = -1;
m_start = 0;
}
@@ -545,7 +544,6 @@
void
ResetOptionValues ()
{
- Options::ResetOptionValues();
m_avoid_no_debug = true;
m_run_mode = eOnlyDuringStepping;
m_avoid_regexp.clear();
@@ -1044,7 +1042,6 @@
void
ResetOptionValues ()
{
- Options::ResetOptionValues();
m_thread_idx = LLDB_INVALID_THREAD_ID;
m_frame_idx = 0;
m_stop_others = false;