diff options
author | emaste <emaste@FreeBSD.org> | 2013-12-03 18:51:59 +0000 |
---|---|---|
committer | emaste <emaste@FreeBSD.org> | 2013-12-03 18:51:59 +0000 |
commit | 0f31a1ef7ecf609d469ee5b34b3f0cb24ae3492d (patch) | |
tree | b2051e4e4856cc58ac7e2d20242b870b4f355ca1 /source/Commands | |
parent | c727fe695d28799acb499e9961f11ec07d4f9fe2 (diff) | |
download | FreeBSD-src-0f31a1ef7ecf609d469ee5b34b3f0cb24ae3492d.zip FreeBSD-src-0f31a1ef7ecf609d469ee5b34b3f0cb24ae3492d.tar.gz |
Import lldb as of SVN r196259 (git 3be86e5)
(A number of files not required for the FreeBSD build have been removed.)
Sponsored by: DARPA, AFRL
Diffstat (limited to 'source/Commands')
-rw-r--r-- | source/Commands/CommandObjectExpression.cpp | 14 | ||||
-rw-r--r-- | source/Commands/CommandObjectMemory.cpp | 315 | ||||
-rw-r--r-- | source/Commands/CommandObjectPlatform.cpp | 277 | ||||
-rw-r--r-- | source/Commands/CommandObjectPlugin.cpp | 6 | ||||
-rw-r--r-- | source/Commands/CommandObjectProcess.cpp | 6 | ||||
-rw-r--r-- | source/Commands/CommandObjectTarget.cpp | 4 | ||||
-rw-r--r-- | source/Commands/CommandObjectThread.cpp | 64 | ||||
-rw-r--r-- | source/Commands/CommandObjectWatchpoint.cpp | 12 |
8 files changed, 490 insertions, 208 deletions
diff --git a/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp index 6d44f71..5ca44ff 100644 --- a/source/Commands/CommandObjectExpression.cpp +++ b/source/Commands/CommandObjectExpression.cpp @@ -363,13 +363,13 @@ CommandObjectExpression::EvaluateExpression bool keep_in_memory = true; EvaluateExpressionOptions options; - options.SetCoerceToId(m_varobj_options.use_objc) - .SetUnwindOnError(m_command_options.unwind_on_error) - .SetIgnoreBreakpoints (m_command_options.ignore_breakpoints) - .SetKeepInMemory(keep_in_memory) - .SetUseDynamic(m_varobj_options.use_dynamic) - .SetRunOthers(m_command_options.try_all_threads) - .SetDebug(m_command_options.debug); + options.SetCoerceToId(m_varobj_options.use_objc); + options.SetUnwindOnError(m_command_options.unwind_on_error); + options.SetIgnoreBreakpoints (m_command_options.ignore_breakpoints); + options.SetKeepInMemory(keep_in_memory); + options.SetUseDynamic(m_varobj_options.use_dynamic); + options.SetTryAllThreads(m_command_options.try_all_threads); + options.SetDebug(m_command_options.debug); if (m_command_options.timeout > 0) options.SetTimeoutUsec(m_command_options.timeout); diff --git a/source/Commands/CommandObjectMemory.cpp b/source/Commands/CommandObjectMemory.cpp index 2ee275e..cb7398f 100644 --- a/source/Commands/CommandObjectMemory.cpp +++ b/source/Commands/CommandObjectMemory.cpp @@ -914,6 +914,311 @@ protected: ClangASTType m_prev_clang_ast_type; }; +OptionDefinition +g_memory_find_option_table[] = +{ + { LLDB_OPT_SET_1, false, "expression", 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeExpression, "Evaluate an expression to obtain a byte pattern."}, + { LLDB_OPT_SET_2, false, "string", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Use text to find a byte pattern."}, + { LLDB_OPT_SET_1|LLDB_OPT_SET_2, false, "count", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCount, "How many times to perform the search."}, + { LLDB_OPT_SET_1|LLDB_OPT_SET_2, false, "dump-offset", 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeOffset, "When dumping memory for a match, an offset from the match location to start dumping from."}, +}; + +//---------------------------------------------------------------------- +// Find the specified data in memory +//---------------------------------------------------------------------- +class CommandObjectMemoryFind : public CommandObjectParsed +{ +public: + + class OptionGroupFindMemory : public OptionGroup + { + public: + OptionGroupFindMemory () : + OptionGroup(), + m_count(1), + m_offset(0) + { + } + + virtual + ~OptionGroupFindMemory () + { + } + + virtual uint32_t + GetNumDefinitions () + { + return sizeof (g_memory_find_option_table) / sizeof (OptionDefinition); + } + + virtual const OptionDefinition* + GetDefinitions () + { + return g_memory_find_option_table; + } + + virtual Error + SetOptionValue (CommandInterpreter &interpreter, + uint32_t option_idx, + const char *option_arg) + { + Error error; + const int short_option = g_memory_find_option_table[option_idx].short_option; + + switch (short_option) + { + case 'e': + m_expr.SetValueFromCString(option_arg); + break; + + case 's': + m_string.SetValueFromCString(option_arg); + break; + + case 'c': + if (m_count.SetValueFromCString(option_arg).Fail()) + error.SetErrorString("unrecognized value for count"); + break; + + case 'o': + if (m_offset.SetValueFromCString(option_arg).Fail()) + error.SetErrorString("unrecognized value for dump-offset"); + break; + + default: + error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option); + break; + } + return error; + } + + virtual void + OptionParsingStarting (CommandInterpreter &interpreter) + { + m_expr.Clear(); + m_string.Clear(); + m_count.Clear(); + } + + OptionValueString m_expr; + OptionValueString m_string; + OptionValueUInt64 m_count; + OptionValueUInt64 m_offset; + }; + + CommandObjectMemoryFind (CommandInterpreter &interpreter) : + CommandObjectParsed (interpreter, + "memory find", + "Find a value in the memory of the process being debugged.", + NULL, + eFlagRequiresProcess | eFlagProcessMustBeLaunched), + m_option_group (interpreter), + m_memory_options () + { + CommandArgumentEntry arg1; + CommandArgumentEntry arg2; + CommandArgumentData addr_arg; + CommandArgumentData value_arg; + + // Define the first (and only) variant of this arg. + addr_arg.arg_type = eArgTypeAddress; + addr_arg.arg_repetition = eArgRepeatPlain; + + // There is only one variant this argument could be; put it into the argument entry. + arg1.push_back (addr_arg); + + // Define the first (and only) variant of this arg. + value_arg.arg_type = eArgTypeValue; + value_arg.arg_repetition = eArgRepeatPlus; + + // There is only one variant this argument could be; put it into the argument entry. + arg2.push_back (value_arg); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back (arg1); + m_arguments.push_back (arg2); + + m_option_group.Append (&m_memory_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_2); + m_option_group.Finalize(); + } + + virtual + ~CommandObjectMemoryFind () + { + } + + Options * + GetOptions () + { + return &m_option_group; + } + +protected: + virtual bool + DoExecute (Args& command, CommandReturnObject &result) + { + // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid + Process *process = m_exe_ctx.GetProcessPtr(); + + const size_t argc = command.GetArgumentCount(); + + if (argc != 2) + { + result.AppendError("two addresses needed for memory find"); + return false; + } + + Error error; + lldb::addr_t low_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(0),LLDB_INVALID_ADDRESS,&error); + if (low_addr == LLDB_INVALID_ADDRESS || error.Fail()) + { + result.AppendError("invalid low address"); + return false; + } + lldb::addr_t high_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(1),LLDB_INVALID_ADDRESS,&error); + if (high_addr == LLDB_INVALID_ADDRESS || error.Fail()) + { + result.AppendError("invalid low address"); + return false; + } + + if (high_addr <= low_addr) + { + result.AppendError("starting address must be smaller than ending address"); + return false; + } + + lldb::addr_t found_location = LLDB_INVALID_ADDRESS; + + DataBufferHeap buffer; + + if (m_memory_options.m_string.OptionWasSet()) + buffer.CopyData(m_memory_options.m_string.GetStringValue(), strlen(m_memory_options.m_string.GetStringValue())); + else if (m_memory_options.m_expr.OptionWasSet()) + { + StackFrame* frame = m_exe_ctx.GetFramePtr(); + ValueObjectSP result_sp; + if (process->GetTarget().EvaluateExpression(m_memory_options.m_expr.GetStringValue(), frame, result_sp) && result_sp.get()) + { + uint64_t value = result_sp->GetValueAsUnsigned(0); + switch (result_sp->GetClangType().GetByteSize()) + { + case 1: { + uint8_t byte = (uint8_t)value; + buffer.CopyData(&byte,1); + } + break; + case 2: { + uint16_t word = (uint16_t)value; + buffer.CopyData(&word,2); + } + break; + case 4: { + uint32_t lword = (uint32_t)value; + buffer.CopyData(&lword,4); + } + break; + case 8: { + buffer.CopyData(&value, 8); + } + break; + case 3: + case 5: + case 6: + case 7: + result.AppendError("unknown type. pass a string instead"); + return false; + default: + result.AppendError("do not know how to deal with larger than 8 byte result types. pass a string instead"); + return false; + } + } + else + { + result.AppendError("expression evaluation failed. pass a string instead?"); + return false; + } + } + else + { + result.AppendError("please pass either a block of text, or an expression to evaluate."); + return false; + } + + size_t count = m_memory_options.m_count.GetCurrentValue(); + found_location = low_addr; + bool ever_found = false; + while (count) + { + found_location = Search(found_location, high_addr, buffer.GetBytes(), buffer.GetByteSize()); + if (found_location == LLDB_INVALID_ADDRESS) + { + if (!ever_found) + { + result.AppendMessage("Your data was not found within the range.\n"); + result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult); + } + else + result.AppendMessage("No more matches found within the range.\n"); + break; + } + result.AppendMessageWithFormat("Your data was found at location: 0x%" PRIx64 "\n", found_location); + + DataBufferHeap dumpbuffer(32,0); + process->ReadMemory(found_location+m_memory_options.m_offset.GetCurrentValue(), dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(), error); + if (!error.Fail()) + { + DataExtractor data(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(), process->GetByteOrder(), process->GetAddressByteSize()); + data.Dump(&result.GetOutputStream(), 0, lldb::eFormatBytesWithASCII, 1, dumpbuffer.GetByteSize(), 16, found_location+m_memory_options.m_offset.GetCurrentValue(), 0, 0); + result.GetOutputStream().EOL(); + } + + --count; + found_location++; + ever_found = true; + } + + result.SetStatus(lldb::eReturnStatusSuccessFinishResult); + return true; + } + + lldb::addr_t + Search (lldb::addr_t low, + lldb::addr_t high, + uint8_t* buffer, + size_t buffer_size) + { + Process *process = m_exe_ctx.GetProcessPtr(); + DataBufferHeap heap(buffer_size, 0); + lldb::addr_t fictional_ptr = low; + for (auto ptr = low; + low < high; + fictional_ptr++) + { + Error error; + if (ptr == low || buffer_size == 1) + process->ReadMemory(ptr, heap.GetBytes(), buffer_size, error); + else + { + memmove(heap.GetBytes(), heap.GetBytes()+1, buffer_size-1); + process->ReadMemory(ptr, heap.GetBytes()+buffer_size-1, 1, error); + } + if (error.Fail()) + return LLDB_INVALID_ADDRESS; + if (memcmp(heap.GetBytes(), buffer, buffer_size) == 0) + return fictional_ptr; + if (ptr == low) + ptr += buffer_size; + else + ptr += 1; + } + return LLDB_INVALID_ADDRESS; + } + + OptionGroupOptions m_option_group; + OptionGroupFindMemory m_memory_options; +}; + OptionDefinition g_memory_write_option_table[] = @@ -922,7 +1227,6 @@ g_memory_write_option_table[] = { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, NULL, 0, eArgTypeOffset, "Start writng bytes from an offset within the input file."}, }; - //---------------------------------------------------------------------- // Write memory to the inferior process //---------------------------------------------------------------------- @@ -948,13 +1252,13 @@ public: { return sizeof (g_memory_write_option_table) / sizeof (OptionDefinition); } - + virtual const OptionDefinition* GetDefinitions () { return g_memory_write_option_table; } - + virtual Error SetOptionValue (CommandInterpreter &interpreter, uint32_t option_idx, @@ -962,7 +1266,7 @@ public: { Error error; const int short_option = g_memory_write_option_table[option_idx].short_option; - + switch (short_option) { case 'i': @@ -973,7 +1277,7 @@ public: error.SetErrorStringWithFormat("input file does not exist: '%s'", option_arg); } break; - + case 'o': { bool success; @@ -1374,6 +1678,7 @@ CommandObjectMemory::CommandObjectMemory (CommandInterpreter &interpreter) : "A set of commands for operating on memory.", "memory <subcommand> [<subcommand-options>]") { + LoadSubCommand ("find", CommandObjectSP (new CommandObjectMemoryFind (interpreter))); LoadSubCommand ("read", CommandObjectSP (new CommandObjectMemoryRead (interpreter))); LoadSubCommand ("write", CommandObjectSP (new CommandObjectMemoryWrite (interpreter))); } diff --git a/source/Commands/CommandObjectPlatform.cpp b/source/Commands/CommandObjectPlatform.cpp index ace1ef5..5e842bf 100644 --- a/source/Commands/CommandObjectPlatform.cpp +++ b/source/Commands/CommandObjectPlatform.cpp @@ -22,6 +22,7 @@ #include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionGroupFile.h" #include "lldb/Interpreter/OptionGroupPlatform.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Platform.h" @@ -119,31 +120,31 @@ public: m_permissions = perms; } case 'r': - m_permissions |= File::ePermissionsUserRead; + m_permissions |= lldb::eFilePermissionsUserRead; break; case 'w': - m_permissions |= File::ePermissionsUserWrite; + m_permissions |= lldb::eFilePermissionsUserWrite; break; case 'x': - m_permissions |= File::ePermissionsUserExecute; + m_permissions |= lldb::eFilePermissionsUserExecute; break; case 'R': - m_permissions |= File::ePermissionsGroupRead; + m_permissions |= lldb::eFilePermissionsGroupRead; break; case 'W': - m_permissions |= File::ePermissionsGroupWrite; + m_permissions |= lldb::eFilePermissionsGroupWrite; break; case 'X': - m_permissions |= File::ePermissionsGroupExecute; + m_permissions |= lldb::eFilePermissionsGroupExecute; break; case 'd': - m_permissions |= File::ePermissionsWorldRead; + m_permissions |= lldb::eFilePermissionsWorldRead; break; case 't': - m_permissions |= File::ePermissionsWorldWrite; + m_permissions |= lldb::eFilePermissionsWorldWrite; break; case 'e': - m_permissions |= File::ePermissionsWorldExecute; + m_permissions |= lldb::eFilePermissionsWorldExecute; break; default: @@ -524,6 +525,65 @@ protected: }; //---------------------------------------------------------------------- +// "platform settings" +//---------------------------------------------------------------------- +class CommandObjectPlatformSettings : public CommandObjectParsed +{ +public: + CommandObjectPlatformSettings (CommandInterpreter &interpreter) : + CommandObjectParsed (interpreter, + "platform settings", + "Set settings for the current target's platform, or for a platform by name.", + "platform settings", + 0), + m_options (interpreter), + m_option_working_dir (LLDB_OPT_SET_1, false, "working-dir", 'w', 0, eArgTypePath, "The working directory for the platform.") + { + m_options.Append (&m_option_working_dir, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); + } + + virtual + ~CommandObjectPlatformSettings () + { + } + +protected: + virtual bool + DoExecute (Args& args, CommandReturnObject &result) + { + PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform()); + if (platform_sp) + { + if (m_option_working_dir.GetOptionValue().OptionWasSet()) + platform_sp->SetWorkingDirectory (ConstString(m_option_working_dir.GetOptionValue().GetCurrentValue().GetPath().c_str())); + } + else + { + result.AppendError ("no platform is currently selected"); + result.SetStatus (eReturnStatusFailed); + } + return result.Succeeded(); + } + + virtual Options * + GetOptions () + { + if (m_options.DidFinalize() == false) + { + m_options.Append(new OptionPermissions()); + m_options.Finalize(); + } + return &m_options; + } +protected: + + OptionGroupOptions m_options; + OptionGroupFile m_option_working_dir; + +}; + + +//---------------------------------------------------------------------- // "platform mkdir" //---------------------------------------------------------------------- class CommandObjectPlatformMkDir : public CommandObjectParsed @@ -552,15 +612,22 @@ public: { std::string cmd_line; args.GetCommandString(cmd_line); - mode_t perms; + uint32_t mode; const OptionPermissions* options_permissions = (OptionPermissions*)m_options.GetGroupWithOption('r'); if (options_permissions) - perms = options_permissions->m_permissions; + mode = options_permissions->m_permissions; else - perms = 0000700 | 0000070 | 0000007; - uint32_t retcode = platform_sp->MakeDirectory(cmd_line,perms); - result.AppendMessageWithFormat("Status = %d\n",retcode); - result.SetStatus (eReturnStatusSuccessFinishResult); + mode = lldb::eFilePermissionsUserRWX | lldb::eFilePermissionsGroupRWX | lldb::eFilePermissionsWorldRX; + Error error = platform_sp->MakeDirectory(cmd_line.c_str(), mode); + if (error.Success()) + { + result.SetStatus (eReturnStatusSuccessFinishResult); + } + else + { + result.AppendError(error.AsCString()); + result.SetStatus (eReturnStatusFailed); + } } else { @@ -619,7 +686,7 @@ public: if (options_permissions) perms = options_permissions->m_permissions; else - perms = 0000700 | 0000070 | 0000007; + perms = lldb::eFilePermissionsUserRW | lldb::eFilePermissionsGroupRW | lldb::eFilePermissionsWorldRead; lldb::user_id_t fd = platform_sp->OpenFile(FileSpec(cmd_line.c_str(),false), File::eOpenOptionRead | File::eOpenOptionWrite | File::eOpenOptionAppend | File::eOpenOptionCanCreate, @@ -2129,82 +2196,6 @@ CommandObjectPlatformShell::CommandOptions::g_option_table[] = { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } }; -struct RecurseCopyBaton -{ - const std::string& destination; - const PlatformSP& platform_sp; - Error error; -}; - - -static FileSpec::EnumerateDirectoryResult -RecurseCopy_Callback (void *baton, - FileSpec::FileType file_type, - const FileSpec &spec) -{ - RecurseCopyBaton* rc_baton = (RecurseCopyBaton*)baton; - switch (file_type) - { - case FileSpec::eFileTypePipe: - case FileSpec::eFileTypeSocket: - // we have no way to copy pipes and sockets - ignore them and continue - return FileSpec::eEnumerateDirectoryResultNext; - break; - - case FileSpec::eFileTypeSymbolicLink: - // what to do for symlinks? - return FileSpec::eEnumerateDirectoryResultNext; - break; - - case FileSpec::eFileTypeDirectory: - { - // make the new directory and get in there - FileSpec new_directory(rc_baton->destination.c_str(),false); - new_directory.AppendPathComponent(spec.GetLastPathComponent()); - uint32_t errcode = rc_baton->platform_sp->MakeDirectory(new_directory, 0777); - std::string new_directory_path (new_directory.GetPath()); - if (errcode != 0) - { - rc_baton->error.SetErrorStringWithFormat("unable to setup directory %s on remote end",new_directory_path.c_str()); - return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out - } - - // now recurse - std::string local_path (spec.GetPath()); - RecurseCopyBaton rc_baton2 = { new_directory_path, rc_baton->platform_sp, Error() }; - FileSpec::EnumerateDirectory(local_path.c_str(), true, true, true, RecurseCopy_Callback, &rc_baton2); - if (rc_baton2.error.Fail()) - { - rc_baton->error.SetErrorString(rc_baton2.error.AsCString()); - return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out - } - return FileSpec::eEnumerateDirectoryResultNext; - } - break; - - case FileSpec::eFileTypeRegular: - { - // copy the file and keep going - std::string dest(rc_baton->destination); - dest.append(spec.GetFilename().GetCString()); - Error err = rc_baton->platform_sp->PutFile(spec, FileSpec(dest.c_str(), false)); - if (err.Fail()) - { - rc_baton->error.SetErrorString(err.AsCString()); - return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out - } - return FileSpec::eEnumerateDirectoryResultNext; - } - break; - - case FileSpec::eFileTypeInvalid: - case FileSpec::eFileTypeOther: - case FileSpec::eFileTypeUnknown: - rc_baton->error.SetErrorStringWithFormat("invalid file detected during copy: %s/%s", spec.GetDirectory().GetCString(), spec.GetFilename().GetCString()); - return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out - break; - } -} //---------------------------------------------------------------------- // "platform install" - install a target to a remote end @@ -2236,10 +2227,9 @@ public: return false; } // TODO: move the bulk of this code over to the platform itself - std::string local_thing(args.GetArgumentAtIndex(0)); - std::string remote_sandbox(args.GetArgumentAtIndex(1)); - FileSpec source(local_thing.c_str(), true); - if (source.Exists() == false) + FileSpec src(args.GetArgumentAtIndex(0), true); + FileSpec dst(args.GetArgumentAtIndex(1), false); + if (src.Exists() == false) { result.AppendError("source location does not exist or is not accessible"); result.SetStatus(eReturnStatusFailed); @@ -2252,75 +2242,21 @@ public: result.SetStatus (eReturnStatusFailed); return false; } - FileSpec::FileType source_type(source.GetFileType()); - if (source_type == FileSpec::eFileTypeDirectory) - { - if (platform_sp->GetSupportsRSync()) - { - FileSpec remote_folder(remote_sandbox.c_str(), false); - Error rsync_err = platform_sp->PutFile(source, remote_folder); - if (rsync_err.Success()) - { - result.SetStatus(eReturnStatusSuccessFinishResult); - return result.Succeeded(); - } - } - FileSpec remote_folder(remote_sandbox.c_str(), false); - remote_folder.AppendPathComponent(source.GetLastPathComponent()); - // TODO: default permissions are bad - uint32_t errcode = platform_sp->MakeDirectory(remote_folder, 0777); - if (errcode != 0) - { - result.AppendError("unable to setup target directory on remote end"); - result.SetStatus(eReturnStatusSuccessFinishNoResult); - return result.Succeeded(); - } - // now recurse - std::string remote_folder_path (remote_folder.GetPath()); - Error err = RecurseCopy(source,remote_folder_path,platform_sp); - if (err.Fail()) - { - result.AppendError(err.AsCString()); - result.SetStatus(eReturnStatusFailed); - } - else - result.SetStatus(eReturnStatusSuccessFinishResult); - return result.Succeeded(); - } - else if (source_type == FileSpec::eFileTypeRegular) + + Error error = platform_sp->Install(src, dst); + if (error.Success()) { - // just a plain file - push it to remote and be done - remote_sandbox.append(source.GetFilename().GetCString()); - FileSpec destination(remote_sandbox.c_str(),false); - Error err = platform_sp->PutFile(source, destination); - if (err.Success()) - result.SetStatus(eReturnStatusSuccessFinishResult); - else - { - result.AppendError(err.AsCString()); - result.SetStatus(eReturnStatusFailed); - } - return result.Succeeded(); + result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { - result.AppendError("source is not a known type of file"); + result.AppendErrorWithFormat("install failed: %s", error.AsCString()); result.SetStatus(eReturnStatusFailed); - return result.Succeeded(); } + return result.Succeeded(); } private: - - Error - RecurseCopy (const FileSpec& source, - const std::string& destination, - const PlatformSP& platform_sp) - { - std::string source_path (source.GetPath()); - RecurseCopyBaton baton = { destination, platform_sp, Error() }; - FileSpec::EnumerateDirectory(source_path.c_str(), true, true, true, RecurseCopy_Callback, &baton); - return baton.error; - } + }; //---------------------------------------------------------------------- @@ -2332,21 +2268,22 @@ CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter) : "A set of commands to manage and create platforms.", "platform [connect|disconnect|info|list|status|select] ...") { - LoadSubCommand ("select", CommandObjectSP (new CommandObjectPlatformSelect (interpreter))); - LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformList (interpreter))); - LoadSubCommand ("status", CommandObjectSP (new CommandObjectPlatformStatus (interpreter))); - LoadSubCommand ("connect", CommandObjectSP (new CommandObjectPlatformConnect (interpreter))); - LoadSubCommand ("disconnect", CommandObjectSP (new CommandObjectPlatformDisconnect (interpreter))); + LoadSubCommand ("select", CommandObjectSP (new CommandObjectPlatformSelect (interpreter))); + LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformList (interpreter))); + LoadSubCommand ("status", CommandObjectSP (new CommandObjectPlatformStatus (interpreter))); + LoadSubCommand ("connect", CommandObjectSP (new CommandObjectPlatformConnect (interpreter))); + LoadSubCommand ("disconnect", CommandObjectSP (new CommandObjectPlatformDisconnect (interpreter))); + LoadSubCommand ("settings", CommandObjectSP (new CommandObjectPlatformSettings (interpreter))); #ifdef LLDB_CONFIGURATION_DEBUG - LoadSubCommand ("mkdir", CommandObjectSP (new CommandObjectPlatformMkDir (interpreter))); - LoadSubCommand ("file", CommandObjectSP (new CommandObjectPlatformFile (interpreter))); - LoadSubCommand ("get-file", CommandObjectSP (new CommandObjectPlatformGetFile (interpreter))); - LoadSubCommand ("get-size", CommandObjectSP (new CommandObjectPlatformGetSize (interpreter))); - LoadSubCommand ("put-file", CommandObjectSP (new CommandObjectPlatformPutFile (interpreter))); + LoadSubCommand ("mkdir", CommandObjectSP (new CommandObjectPlatformMkDir (interpreter))); + LoadSubCommand ("file", CommandObjectSP (new CommandObjectPlatformFile (interpreter))); + LoadSubCommand ("get-file", CommandObjectSP (new CommandObjectPlatformGetFile (interpreter))); + LoadSubCommand ("get-size", CommandObjectSP (new CommandObjectPlatformGetSize (interpreter))); + LoadSubCommand ("put-file", CommandObjectSP (new CommandObjectPlatformPutFile (interpreter))); #endif - LoadSubCommand ("process", CommandObjectSP (new CommandObjectPlatformProcess (interpreter))); - LoadSubCommand ("shell", CommandObjectSP (new CommandObjectPlatformShell (interpreter))); - LoadSubCommand ("target-install", CommandObjectSP (new CommandObjectPlatformInstall (interpreter))); + LoadSubCommand ("process", CommandObjectSP (new CommandObjectPlatformProcess (interpreter))); + LoadSubCommand ("shell", CommandObjectSP (new CommandObjectPlatformShell (interpreter))); + LoadSubCommand ("target-install", CommandObjectSP (new CommandObjectPlatformInstall (interpreter))); } diff --git a/source/Commands/CommandObjectPlugin.cpp b/source/Commands/CommandObjectPlugin.cpp index 1bc7632..658c077 100644 --- a/source/Commands/CommandObjectPlugin.cpp +++ b/source/Commands/CommandObjectPlugin.cpp @@ -11,10 +11,6 @@ #include "CommandObjectPlugin.h" -#include "lldb/API/SBDebugger.h" -#include "lldb/API/SBCommandInterpreter.h" -#include "lldb/API/SBCommandReturnObject.h" - #include "lldb/Host/Host.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -79,8 +75,6 @@ protected: bool DoExecute (Args& command, CommandReturnObject &result) { - typedef void (*LLDBCommandPluginInit) (lldb::SBDebugger debugger); - size_t argc = command.GetArgumentCount(); if (argc != 1) diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp index 8bdec6e..2933c78 100644 --- a/source/Commands/CommandObjectProcess.cpp +++ b/source/Commands/CommandObjectProcess.cpp @@ -251,9 +251,11 @@ protected: // then you'll pick up that incorrect value. bool synchronous_execution = m_interpreter.GetSynchronous (); + PlatformSP platform_sp (target->GetPlatform()); + // Finalize the file actions, and if none were given, default to opening // up a pseudo terminal - const bool default_to_use_pty = true; + const bool default_to_use_pty = platform_sp ? platform_sp->IsHost() : false; m_options.launch_info.FinalizeFileActions (target, default_to_use_pty); if (state == eStateConnected) @@ -267,8 +269,6 @@ protected: if (!m_options.launch_info.GetArchitecture().IsValid()) m_options.launch_info.GetArchitecture() = target->GetArchitecture(); - - PlatformSP platform_sp (target->GetPlatform()); if (platform_sp && platform_sp->CanDebugProcess ()) { diff --git a/source/Commands/CommandObjectTarget.cpp b/source/Commands/CommandObjectTarget.cpp index ef431e2..8e7e68a 100644 --- a/source/Commands/CommandObjectTarget.cpp +++ b/source/Commands/CommandObjectTarget.cpp @@ -1796,10 +1796,8 @@ LookupTypeInModule (CommandInterpreter &interpreter, strm.Printf("%zu match%s found in ", num_matches, num_matches > 1 ? "es" : ""); DumpFullpath (strm, &module->GetFileSpec(), 0); strm.PutCString(":\n"); - const uint32_t num_types = type_list.GetSize(); - for (uint32_t i=0; i<num_types; ++i) + for (TypeSP type_sp : type_list.Types()) { - TypeSP type_sp (type_list.GetTypeAtIndex(i)); if (type_sp) { // Resolve the clang type so that any forward references diff --git a/source/Commands/CommandObjectThread.cpp b/source/Commands/CommandObjectThread.cpp index f46a221..10d6618 100644 --- a/source/Commands/CommandObjectThread.cpp +++ b/source/Commands/CommandObjectThread.cpp @@ -28,6 +28,7 @@ #include "lldb/Symbol/LineEntry.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Target/SystemRuntime.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" @@ -92,6 +93,13 @@ public: if (!success) error.SetErrorStringWithFormat("invalid integer value for option '%c'", short_option); } + case 'e': + { + bool success; + m_extended_backtrace = Args::StringToBoolean (option_arg, false, &success); + if (!success) + error.SetErrorStringWithFormat("invalid boolean value for option '%c'", short_option); + } break; default: error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); @@ -106,6 +114,7 @@ public: { m_count = UINT32_MAX; m_start = 0; + m_extended_backtrace = false; } const OptionDefinition* @@ -121,6 +130,7 @@ public: // Instance variables to hold the values for command options. uint32_t m_count; uint32_t m_start; + bool m_extended_backtrace; }; CommandObjectThreadBacktrace (CommandInterpreter &interpreter) : @@ -160,6 +170,32 @@ public: } protected: + void + DoExtendedBacktrace (Thread *thread, CommandReturnObject &result) + { + SystemRuntime *runtime = thread->GetProcess()->GetSystemRuntime(); + if (runtime) + { + Stream &strm = result.GetOutputStream(); + const std::vector<ConstString> &types = runtime->GetExtendedBacktraceTypes(); + for (auto type : types) + { + ThreadSP ext_thread_sp = runtime->GetExtendedBacktraceThread (thread->shared_from_this(), type); + if (ext_thread_sp && ext_thread_sp->IsValid ()) + { + const uint32_t num_frames_with_source = 0; + if (ext_thread_sp->GetStatus (strm, + m_options.m_start, + m_options.m_count, + num_frames_with_source)) + { + DoExtendedBacktrace (ext_thread_sp.get(), result); + } + } + } + } + } + virtual bool DoExecute (Args& command, CommandReturnObject &result) { @@ -178,29 +214,36 @@ protected: num_frames_with_source)) { result.SetStatus (eReturnStatusSuccessFinishResult); + if (m_options.m_extended_backtrace) + { + DoExtendedBacktrace (thread, result); + } } } else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0) { Process *process = m_exe_ctx.GetProcessPtr(); - Mutex::Locker locker (process->GetThreadList().GetMutex()); - uint32_t num_threads = process->GetThreadList().GetSize(); - for (uint32_t i = 0; i < num_threads; i++) + uint32_t idx = 0; + for (ThreadSP thread_sp : process->Threads()) { - ThreadSP thread_sp = process->GetThreadList().GetThreadAtIndex(i); + if (idx != 0) + result.AppendMessage(""); + if (!thread_sp->GetStatus (strm, m_options.m_start, m_options.m_count, num_frames_with_source)) { - result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", i); + result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", idx); result.SetStatus (eReturnStatusFailed); return false; } + if (m_options.m_extended_backtrace) + { + DoExtendedBacktrace (thread_sp.get(), result); + } - if (i < num_threads - 1) - result.AppendMessage(""); - + ++idx; } } else @@ -244,6 +287,10 @@ protected: result.SetStatus (eReturnStatusFailed); return false; } + if (m_options.m_extended_backtrace) + { + DoExtendedBacktrace (thread_sps[i].get(), result); + } if (i < num_args - 1) result.AppendMessage(""); @@ -260,6 +307,7 @@ CommandObjectThreadBacktrace::CommandOptions::g_option_table[] = { { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, 0, eArgTypeCount, "How many frames to display (-1 for all)"}, { LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace"}, +{ LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "Show the extended backtrace, if available"}, { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } }; diff --git a/source/Commands/CommandObjectWatchpoint.cpp b/source/Commands/CommandObjectWatchpoint.cpp index ae490e3..e55b2ee 100644 --- a/source/Commands/CommandObjectWatchpoint.cpp +++ b/source/Commands/CommandObjectWatchpoint.cpp @@ -939,7 +939,7 @@ public: SetHelpLong( "Examples: \n\ \n\ - watchpoint set variable -w read_wriate my_global_var \n\ + watchpoint set variable -w read_write my_global_var \n\ # Watch my_global_var for read/write access, with the region to watch corresponding to the byte size of the data type.\n"); CommandArgumentEntry arg; @@ -1256,11 +1256,11 @@ protected: // Use expression evaluation to arrive at the address to watch. EvaluateExpressionOptions options; - options.SetCoerceToId(false) - .SetUnwindOnError(true) - .SetKeepInMemory(false) - .SetRunOthers(true) - .SetTimeoutUsec(0); + options.SetCoerceToId(false); + options.SetUnwindOnError(true); + options.SetKeepInMemory(false); + options.SetTryAllThreads(true); + options.SetTimeoutUsec(0); ExecutionResults expr_result = target->EvaluateExpression (expr, frame, |