diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Target')
44 files changed, 1416 insertions, 876 deletions
diff --git a/contrib/llvm/tools/lldb/source/Target/ABI.cpp b/contrib/llvm/tools/lldb/source/Target/ABI.cpp index 87363a3..72f58be 100644 --- a/contrib/llvm/tools/lldb/source/Target/ABI.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ABI.cpp @@ -25,7 +25,7 @@ using namespace lldb; using namespace lldb_private; ABISP -ABI::FindPlugin(const ArchSpec &arch) { +ABI::FindPlugin(lldb::ProcessSP process_sp, const ArchSpec &arch) { ABISP abi_sp; ABICreateInstance create_callback; @@ -33,7 +33,7 @@ ABI::FindPlugin(const ArchSpec &arch) { (create_callback = PluginManager::GetABICreateCallbackAtIndex(idx)) != nullptr; ++idx) { - abi_sp = create_callback(arch); + abi_sp = create_callback(process_sp, arch); if (abi_sp) return abi_sp; @@ -42,8 +42,6 @@ ABI::FindPlugin(const ArchSpec &arch) { return abi_sp; } -ABI::ABI() = default; - ABI::~ABI() = default; bool ABI::GetRegisterInfoByName(const ConstString &name, RegisterInfo &info) { diff --git a/contrib/llvm/tools/lldb/source/Target/FileAction.cpp b/contrib/llvm/tools/lldb/source/Target/FileAction.cpp index 7c2567e..c9cc325 100644 --- a/contrib/llvm/tools/lldb/source/Target/FileAction.cpp +++ b/contrib/llvm/tools/lldb/source/Target/FileAction.cpp @@ -9,9 +9,9 @@ #include <fcntl.h> -#include "lldb/Core/Stream.h" #include "lldb/Host/PosixApi.h" #include "lldb/Target/FileAction.h" +#include "lldb/Utility/Stream.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Target/InstrumentationRuntime.cpp b/contrib/llvm/tools/lldb/source/Target/InstrumentationRuntime.cpp index f3bc145..ac8b5df 100644 --- a/contrib/llvm/tools/lldb/source/Target/InstrumentationRuntime.cpp +++ b/contrib/llvm/tools/lldb/source/Target/InstrumentationRuntime.cpp @@ -15,8 +15,8 @@ #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegularExpression.h" #include "lldb/Target/Process.h" +#include "lldb/Utility/RegularExpression.h" #include "lldb/lldb-private.h" using namespace lldb; diff --git a/contrib/llvm/tools/lldb/source/Target/Language.cpp b/contrib/llvm/tools/lldb/source/Target/Language.cpp index 938d80a..cde6f86 100644 --- a/contrib/llvm/tools/lldb/source/Target/Language.cpp +++ b/contrib/llvm/tools/lldb/source/Target/Language.cpp @@ -15,10 +15,12 @@ #include "lldb/Target/Language.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/Stream.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/TypeList.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/Stream.h" + +#include "llvm/Support/Threading.h" using namespace lldb; using namespace lldb_private; @@ -29,9 +31,9 @@ typedef std::map<lldb::LanguageType, LanguageUP> LanguagesMap; static LanguagesMap &GetLanguagesMap() { static LanguagesMap *g_map = nullptr; - static std::once_flag g_initialize; + static llvm::once_flag g_initialize; - std::call_once(g_initialize, [] { + llvm::call_once(g_initialize, [] { g_map = new LanguagesMap(); // NOTE: INTENTIONAL LEAK due to global // destructor chain }); @@ -40,9 +42,9 @@ static LanguagesMap &GetLanguagesMap() { } static std::mutex &GetLanguagesMutex() { static std::mutex *g_mutex = nullptr; - static std::once_flag g_initialize; + static llvm::once_flag g_initialize; - std::call_once(g_initialize, [] { + llvm::call_once(g_initialize, [] { g_mutex = new std::mutex(); // NOTE: INTENTIONAL LEAK due to global // destructor chain }); @@ -385,7 +387,7 @@ DumpValueObjectOptions::DeclPrintingHelper Language::GetDeclPrintingHelper() { return nullptr; } -LazyBool Language::IsLogicalTrue(ValueObject &valobj, Error &error) { +LazyBool Language::IsLogicalTrue(ValueObject &valobj, Status &error) { return eLazyBoolCalculate; } diff --git a/contrib/llvm/tools/lldb/source/Target/LanguageRuntime.cpp b/contrib/llvm/tools/lldb/source/Target/LanguageRuntime.cpp index cacb491..bd02121 100644 --- a/contrib/llvm/tools/lldb/source/Target/LanguageRuntime.cpp +++ b/contrib/llvm/tools/lldb/source/Target/LanguageRuntime.cpp @@ -12,7 +12,6 @@ // Other libraries and framework includes // Project includes #include "lldb/Target/LanguageRuntime.h" -#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/SearchFilter.h" @@ -90,7 +89,8 @@ ExceptionSearchFilter::DoCopyForBreakpoint(Breakpoint &breakpoint) { } SearchFilter *ExceptionSearchFilter::CreateFromStructuredData( - Target &target, const StructuredData::Dictionary &data_dict, Error &error) { + Target &target, const StructuredData::Dictionary &data_dict, + Status &error) { SearchFilter *result = nullptr; return result; } diff --git a/contrib/llvm/tools/lldb/source/Target/Memory.cpp b/contrib/llvm/tools/lldb/source/Target/Memory.cpp index 775d0b3..ced3594 100644 --- a/contrib/llvm/tools/lldb/source/Target/Memory.cpp +++ b/contrib/llvm/tools/lldb/source/Target/Memory.cpp @@ -13,11 +13,11 @@ // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/Log.h" #include "lldb/Core/RangeMap.h" #include "lldb/Core/State.h" #include "lldb/Target/Process.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/Log.h" using namespace lldb; using namespace lldb_private; @@ -129,7 +129,8 @@ bool MemoryCache::RemoveInvalidRange(lldb::addr_t base_addr, return false; } -size_t MemoryCache::Read(addr_t addr, void *dst, size_t dst_len, Error &error) { +size_t MemoryCache::Read(addr_t addr, void *dst, size_t dst_len, + Status &error) { size_t bytes_left = dst_len; // Check the L1 cache for a range that contain the entire memory read. @@ -252,146 +253,78 @@ size_t MemoryCache::Read(addr_t addr, void *dst, size_t dst_len, Error &error) { AllocatedBlock::AllocatedBlock(lldb::addr_t addr, uint32_t byte_size, uint32_t permissions, uint32_t chunk_size) - : m_addr(addr), m_byte_size(byte_size), m_permissions(permissions), - m_chunk_size(chunk_size), m_offset_to_chunk_size() -// m_allocated (byte_size / chunk_size) + : m_range(addr, byte_size), m_permissions(permissions), + m_chunk_size(chunk_size) { + // The entire address range is free to start with. + m_free_blocks.Append(m_range); assert(byte_size > chunk_size); } AllocatedBlock::~AllocatedBlock() {} lldb::addr_t AllocatedBlock::ReserveBlock(uint32_t size) { - addr_t addr = LLDB_INVALID_ADDRESS; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE)); - if (size <= m_byte_size) { - const uint32_t needed_chunks = CalculateChunksNeededForSize(size); - - if (m_offset_to_chunk_size.empty()) { - m_offset_to_chunk_size[0] = needed_chunks; - if (log) - log->Printf("[1] AllocatedBlock::ReserveBlock(%p) (size = %u (0x%x)) " - "=> offset = 0x%x, %u %u bit chunks", - (void *)this, size, size, 0, needed_chunks, m_chunk_size); - addr = m_addr; - } else { - uint32_t last_offset = 0; - OffsetToChunkSize::const_iterator pos = m_offset_to_chunk_size.begin(); - OffsetToChunkSize::const_iterator end = m_offset_to_chunk_size.end(); - while (pos != end) { - if (pos->first > last_offset) { - const uint32_t bytes_available = pos->first - last_offset; - const uint32_t num_chunks = - CalculateChunksNeededForSize(bytes_available); - if (num_chunks >= needed_chunks) { - m_offset_to_chunk_size[last_offset] = needed_chunks; - if (log) - log->Printf("[2] AllocatedBlock::ReserveBlock(%p) (size = %u " - "(0x%x)) => offset = 0x%x, %u %u bit chunks - " - "num_chunks %zu", - (void *)this, size, size, last_offset, needed_chunks, - m_chunk_size, m_offset_to_chunk_size.size()); - addr = m_addr + last_offset; - break; - } - } - - last_offset = pos->first + pos->second * m_chunk_size; - - if (++pos == end) { - // Last entry... - const uint32_t chunks_left = - CalculateChunksNeededForSize(m_byte_size - last_offset); - if (chunks_left >= needed_chunks) { - m_offset_to_chunk_size[last_offset] = needed_chunks; - if (log) - log->Printf("[3] AllocatedBlock::ReserveBlock(%p) (size = %u " - "(0x%x)) => offset = 0x%x, %u %u bit chunks - " - "num_chunks %zu", - (void *)this, size, size, last_offset, needed_chunks, - m_chunk_size, m_offset_to_chunk_size.size()); - addr = m_addr + last_offset; - break; - } - } + // We must return something valid for zero bytes. + if (size == 0) + size = 1; + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + + const size_t free_count = m_free_blocks.GetSize(); + for (size_t i=0; i<free_count; ++i) + { + auto &free_block = m_free_blocks.GetEntryRef(i); + const lldb::addr_t range_size = free_block.GetByteSize(); + if (range_size >= size) + { + // We found a free block that is big enough for our data. Figure out how + // many chunks we will need and calculate the resulting block size we will + // reserve. + addr_t addr = free_block.GetRangeBase(); + size_t num_chunks = CalculateChunksNeededForSize(size); + lldb::addr_t block_size = num_chunks * m_chunk_size; + lldb::addr_t bytes_left = range_size - block_size; + if (bytes_left == 0) + { + // The newly allocated block will take all of the bytes in this + // available block, so we can just add it to the allocated ranges and + // remove the range from the free ranges. + m_reserved_blocks.Insert(free_block, false); + m_free_blocks.RemoveEntryAtIndex(i); + } + else + { + // Make the new allocated range and add it to the allocated ranges. + Range<lldb::addr_t, uint32_t> reserved_block(free_block); + reserved_block.SetByteSize(block_size); + // Insert the reserved range and don't combine it with other blocks + // in the reserved blocks list. + m_reserved_blocks.Insert(reserved_block, false); + // Adjust the free range in place since we won't change the sorted + // ordering of the m_free_blocks list. + free_block.SetRangeBase(reserved_block.GetRangeEnd()); + free_block.SetByteSize(bytes_left); } + LLDB_LOGV(log, "({0}) (size = {1} ({1:x})) => {2:x}", this, size, addr); + return addr; } - // const uint32_t total_chunks = m_allocated.size (); - // uint32_t unallocated_idx = 0; - // uint32_t allocated_idx = m_allocated.find_first(); - // uint32_t first_chunk_idx = UINT32_MAX; - // uint32_t num_chunks; - // while (1) - // { - // if (allocated_idx == UINT32_MAX) - // { - // // No more bits are set starting from unallocated_idx, so - // we - // // either have enough chunks for the request, or we don't. - // // Either way we break out of the while loop... - // num_chunks = total_chunks - unallocated_idx; - // if (needed_chunks <= num_chunks) - // first_chunk_idx = unallocated_idx; - // break; - // } - // else if (allocated_idx > unallocated_idx) - // { - // // We have some allocated chunks, check if there are - // enough - // // free chunks to satisfy the request? - // num_chunks = allocated_idx - unallocated_idx; - // if (needed_chunks <= num_chunks) - // { - // // Yep, we have enough! - // first_chunk_idx = unallocated_idx; - // break; - // } - // } - // - // while (unallocated_idx < total_chunks) - // { - // if (m_allocated[unallocated_idx]) - // ++unallocated_idx; - // else - // break; - // } - // - // if (unallocated_idx >= total_chunks) - // break; - // - // allocated_idx = m_allocated.find_next(unallocated_idx); - // } - // - // if (first_chunk_idx != UINT32_MAX) - // { - // const uint32_t end_bit_idx = unallocated_idx + needed_chunks; - // for (uint32_t idx = first_chunk_idx; idx < end_bit_idx; ++idx) - // m_allocated.set(idx); - // return m_addr + m_chunk_size * first_chunk_idx; - // } } - if (log) - log->Printf("AllocatedBlock::ReserveBlock(%p) (size = %u (0x%x)) => " - "0x%16.16" PRIx64, - (void *)this, size, size, (uint64_t)addr); - return addr; + LLDB_LOGV(log, "({0}) (size = {1} ({1:x})) => {2:x}", this, size, + LLDB_INVALID_ADDRESS); + return LLDB_INVALID_ADDRESS; } bool AllocatedBlock::FreeBlock(addr_t addr) { - uint32_t offset = addr - m_addr; - OffsetToChunkSize::iterator pos = m_offset_to_chunk_size.find(offset); bool success = false; - if (pos != m_offset_to_chunk_size.end()) { - m_offset_to_chunk_size.erase(pos); + auto entry_idx = m_reserved_blocks.FindEntryIndexThatContains(addr); + if (entry_idx != UINT32_MAX) + { + m_free_blocks.Insert(m_reserved_blocks.GetEntryRef(entry_idx), true); + m_reserved_blocks.RemoveEntryAtIndex(entry_idx); success = true; } - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE)); - if (log) - log->Printf("AllocatedBlock::FreeBlock(%p) (addr = 0x%16.16" PRIx64 - ") => %i, num_chunks: %zu", - (void *)this, (uint64_t)addr, success, - m_offset_to_chunk_size.size()); + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + LLDB_LOGV(log, "({0}) (addr = {1:x}) => {2}", this, addr, success); return success; } @@ -412,7 +345,7 @@ void AllocatedMemoryCache::Clear() { AllocatedMemoryCache::AllocatedBlockSP AllocatedMemoryCache::AllocatePage(uint32_t byte_size, uint32_t permissions, - uint32_t chunk_size, Error &error) { + uint32_t chunk_size, Status &error) { AllocatedBlockSP block_sp; const size_t page_size = 4096; const size_t num_pages = (byte_size + page_size - 1) / page_size; @@ -438,7 +371,7 @@ AllocatedMemoryCache::AllocatePage(uint32_t byte_size, uint32_t permissions, lldb::addr_t AllocatedMemoryCache::AllocateMemory(size_t byte_size, uint32_t permissions, - Error &error) { + Status &error) { std::lock_guard<std::recursive_mutex> guard(m_mutex); addr_t addr = LLDB_INVALID_ADDRESS; diff --git a/contrib/llvm/tools/lldb/source/Target/ModuleCache.cpp b/contrib/llvm/tools/lldb/source/Target/ModuleCache.cpp new file mode 100644 index 0000000..2b65477 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Target/ModuleCache.cpp @@ -0,0 +1,332 @@ +//===--------------------- ModuleCache.cpp ----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/ModuleCache.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Host/File.h" +#include "lldb/Host/LockFile.h" +#include "lldb/Utility/Log.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/FileUtilities.h" + +#include <assert.h> + +#include <cstdio> + +using namespace lldb; +using namespace lldb_private; + +namespace { + +const char *kModulesSubdir = ".cache"; +const char *kLockDirName = ".lock"; +const char *kTempFileName = ".temp"; +const char *kTempSymFileName = ".symtemp"; +const char *kSymFileExtension = ".sym"; +const char *kFSIllegalChars = "\\/:*?\"<>|"; + +std::string GetEscapedHostname(const char *hostname) { + if (hostname == nullptr) + hostname = "unknown"; + std::string result(hostname); + size_t size = result.size(); + for (size_t i = 0; i < size; ++i) { + if ((result[i] >= 1 && result[i] <= 31) || + strchr(kFSIllegalChars, result[i]) != nullptr) + result[i] = '_'; + } + return result; +} + +class ModuleLock { +private: + File m_file; + std::unique_ptr<lldb_private::LockFile> m_lock; + FileSpec m_file_spec; + +public: + ModuleLock(const FileSpec &root_dir_spec, const UUID &uuid, Status &error); + void Delete(); +}; + +static FileSpec JoinPath(const FileSpec &path1, const char *path2) { + FileSpec result_spec(path1); + result_spec.AppendPathComponent(path2); + return result_spec; +} + +static Status MakeDirectory(const FileSpec &dir_path) { + namespace fs = llvm::sys::fs; + + return fs::create_directories(dir_path.GetPath(), true, fs::perms::owner_all); +} + +FileSpec GetModuleDirectory(const FileSpec &root_dir_spec, const UUID &uuid) { + const auto modules_dir_spec = JoinPath(root_dir_spec, kModulesSubdir); + return JoinPath(modules_dir_spec, uuid.GetAsString().c_str()); +} + +FileSpec GetSymbolFileSpec(const FileSpec &module_file_spec) { + return FileSpec(module_file_spec.GetPath() + kSymFileExtension, false); +} + +void DeleteExistingModule(const FileSpec &root_dir_spec, + const FileSpec &sysroot_module_path_spec) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES)); + UUID module_uuid; + { + auto module_sp = + std::make_shared<Module>(ModuleSpec(sysroot_module_path_spec)); + module_uuid = module_sp->GetUUID(); + } + + if (!module_uuid.IsValid()) + return; + + Status error; + ModuleLock lock(root_dir_spec, module_uuid, error); + if (error.Fail()) { + if (log) + log->Printf("Failed to lock module %s: %s", + module_uuid.GetAsString().c_str(), error.AsCString()); + } + + namespace fs = llvm::sys::fs; + fs::file_status st; + if (status(sysroot_module_path_spec.GetPath(), st)) + return; + + if (st.getLinkCount() > 2) // module is referred by other hosts. + return; + + const auto module_spec_dir = GetModuleDirectory(root_dir_spec, module_uuid); + llvm::sys::fs::remove_directories(module_spec_dir.GetPath()); + lock.Delete(); +} + +void DecrementRefExistingModule(const FileSpec &root_dir_spec, + const FileSpec &sysroot_module_path_spec) { + // Remove $platform/.cache/$uuid folder if nobody else references it. + DeleteExistingModule(root_dir_spec, sysroot_module_path_spec); + + // Remove sysroot link. + llvm::sys::fs::remove(sysroot_module_path_spec.GetPath()); + + FileSpec symfile_spec = GetSymbolFileSpec(sysroot_module_path_spec); + llvm::sys::fs::remove(symfile_spec.GetPath()); +} + +Status CreateHostSysRootModuleLink(const FileSpec &root_dir_spec, + const char *hostname, + const FileSpec &platform_module_spec, + const FileSpec &local_module_spec, + bool delete_existing) { + const auto sysroot_module_path_spec = + JoinPath(JoinPath(root_dir_spec, hostname), + platform_module_spec.GetPath().c_str()); + if (sysroot_module_path_spec.Exists()) { + if (!delete_existing) + return Status(); + + DecrementRefExistingModule(root_dir_spec, sysroot_module_path_spec); + } + + const auto error = MakeDirectory( + FileSpec(sysroot_module_path_spec.GetDirectory().AsCString(), false)); + if (error.Fail()) + return error; + + return llvm::sys::fs::create_hard_link(local_module_spec.GetPath(), + sysroot_module_path_spec.GetPath()); +} + +} // namespace + +ModuleLock::ModuleLock(const FileSpec &root_dir_spec, const UUID &uuid, + Status &error) { + const auto lock_dir_spec = JoinPath(root_dir_spec, kLockDirName); + error = MakeDirectory(lock_dir_spec); + if (error.Fail()) + return; + + m_file_spec = JoinPath(lock_dir_spec, uuid.GetAsString().c_str()); + m_file.Open(m_file_spec.GetCString(), File::eOpenOptionWrite | + File::eOpenOptionCanCreate | + File::eOpenOptionCloseOnExec); + if (!m_file) { + error.SetErrorToErrno(); + return; + } + + m_lock.reset(new lldb_private::LockFile(m_file.GetDescriptor())); + error = m_lock->WriteLock(0, 1); + if (error.Fail()) + error.SetErrorStringWithFormat("Failed to lock file: %s", + error.AsCString()); +} + +void ModuleLock::Delete() { + if (!m_file) + return; + + m_file.Close(); + llvm::sys::fs::remove(m_file_spec.GetPath()); +} + +///////////////////////////////////////////////////////////////////////// + +Status ModuleCache::Put(const FileSpec &root_dir_spec, const char *hostname, + const ModuleSpec &module_spec, const FileSpec &tmp_file, + const FileSpec &target_file) { + const auto module_spec_dir = + GetModuleDirectory(root_dir_spec, module_spec.GetUUID()); + const auto module_file_path = + JoinPath(module_spec_dir, target_file.GetFilename().AsCString()); + + const auto tmp_file_path = tmp_file.GetPath(); + const auto err_code = + llvm::sys::fs::rename(tmp_file_path, module_file_path.GetPath()); + if (err_code) + return Status("Failed to rename file %s to %s: %s", tmp_file_path.c_str(), + module_file_path.GetPath().c_str(), + err_code.message().c_str()); + + const auto error = CreateHostSysRootModuleLink( + root_dir_spec, hostname, target_file, module_file_path, true); + if (error.Fail()) + return Status("Failed to create link to %s: %s", + module_file_path.GetPath().c_str(), error.AsCString()); + return Status(); +} + +Status ModuleCache::Get(const FileSpec &root_dir_spec, const char *hostname, + const ModuleSpec &module_spec, + ModuleSP &cached_module_sp, bool *did_create_ptr) { + const auto find_it = + m_loaded_modules.find(module_spec.GetUUID().GetAsString()); + if (find_it != m_loaded_modules.end()) { + cached_module_sp = (*find_it).second.lock(); + if (cached_module_sp) + return Status(); + m_loaded_modules.erase(find_it); + } + + const auto module_spec_dir = + GetModuleDirectory(root_dir_spec, module_spec.GetUUID()); + const auto module_file_path = JoinPath( + module_spec_dir, module_spec.GetFileSpec().GetFilename().AsCString()); + + if (!module_file_path.Exists()) + return Status("Module %s not found", module_file_path.GetPath().c_str()); + if (module_file_path.GetByteSize() != module_spec.GetObjectSize()) + return Status("Module %s has invalid file size", + module_file_path.GetPath().c_str()); + + // We may have already cached module but downloaded from an another host - in + // this case let's create a link to it. + auto error = CreateHostSysRootModuleLink(root_dir_spec, hostname, + module_spec.GetFileSpec(), + module_file_path, false); + if (error.Fail()) + return Status("Failed to create link to %s: %s", + module_file_path.GetPath().c_str(), error.AsCString()); + + auto cached_module_spec(module_spec); + cached_module_spec.GetUUID().Clear(); // Clear UUID since it may contain md5 + // content hash instead of real UUID. + cached_module_spec.GetFileSpec() = module_file_path; + cached_module_spec.GetPlatformFileSpec() = module_spec.GetFileSpec(); + + error = ModuleList::GetSharedModule(cached_module_spec, cached_module_sp, + nullptr, nullptr, did_create_ptr, false); + if (error.Fail()) + return error; + + FileSpec symfile_spec = GetSymbolFileSpec(cached_module_sp->GetFileSpec()); + if (symfile_spec.Exists()) + cached_module_sp->SetSymbolFileFileSpec(symfile_spec); + + m_loaded_modules.insert( + std::make_pair(module_spec.GetUUID().GetAsString(), cached_module_sp)); + + return Status(); +} + +Status ModuleCache::GetAndPut(const FileSpec &root_dir_spec, + const char *hostname, + const ModuleSpec &module_spec, + const ModuleDownloader &module_downloader, + const SymfileDownloader &symfile_downloader, + lldb::ModuleSP &cached_module_sp, + bool *did_create_ptr) { + const auto module_spec_dir = + GetModuleDirectory(root_dir_spec, module_spec.GetUUID()); + auto error = MakeDirectory(module_spec_dir); + if (error.Fail()) + return error; + + ModuleLock lock(root_dir_spec, module_spec.GetUUID(), error); + if (error.Fail()) + return Status("Failed to lock module %s: %s", + module_spec.GetUUID().GetAsString().c_str(), + error.AsCString()); + + const auto escaped_hostname(GetEscapedHostname(hostname)); + // Check local cache for a module. + error = Get(root_dir_spec, escaped_hostname.c_str(), module_spec, + cached_module_sp, did_create_ptr); + if (error.Success()) + return error; + + const auto tmp_download_file_spec = JoinPath(module_spec_dir, kTempFileName); + error = module_downloader(module_spec, tmp_download_file_spec); + llvm::FileRemover tmp_file_remover(tmp_download_file_spec.GetPath()); + if (error.Fail()) + return Status("Failed to download module: %s", error.AsCString()); + + // Put downloaded file into local module cache. + error = Put(root_dir_spec, escaped_hostname.c_str(), module_spec, + tmp_download_file_spec, module_spec.GetFileSpec()); + if (error.Fail()) + return Status("Failed to put module into cache: %s", error.AsCString()); + + tmp_file_remover.releaseFile(); + error = Get(root_dir_spec, escaped_hostname.c_str(), module_spec, + cached_module_sp, did_create_ptr); + if (error.Fail()) + return error; + + // Fetching a symbol file for the module + const auto tmp_download_sym_file_spec = + JoinPath(module_spec_dir, kTempSymFileName); + error = symfile_downloader(cached_module_sp, tmp_download_sym_file_spec); + llvm::FileRemover tmp_symfile_remover(tmp_download_sym_file_spec.GetPath()); + if (error.Fail()) + // Failed to download a symfile but fetching the module was successful. The + // module might + // contain the necessary symbols and the debugging is also possible without + // a symfile. + return Status(); + + error = Put(root_dir_spec, escaped_hostname.c_str(), module_spec, + tmp_download_sym_file_spec, + GetSymbolFileSpec(module_spec.GetFileSpec())); + if (error.Fail()) + return Status("Failed to put symbol file into cache: %s", + error.AsCString()); + + tmp_symfile_remover.releaseFile(); + + FileSpec symfile_spec = GetSymbolFileSpec(cached_module_sp->GetFileSpec()); + cached_module_sp->SetSymbolFileFileSpec(symfile_spec); + return Status(); +} diff --git a/contrib/llvm/tools/lldb/source/Target/ObjCLanguageRuntime.cpp b/contrib/llvm/tools/lldb/source/Target/ObjCLanguageRuntime.cpp index 3ee4dd3..d3cc7c0 100644 --- a/contrib/llvm/tools/lldb/source/Target/ObjCLanguageRuntime.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ObjCLanguageRuntime.cpp @@ -8,11 +8,9 @@ //===----------------------------------------------------------------------===// #include "clang/AST/Type.h" -#include "lldb/Core/Log.h" #include "lldb/Core/MappedHash.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/Timer.h" #include "lldb/Core/ValueObject.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/SymbolContext.h" @@ -21,6 +19,8 @@ #include "lldb/Symbol/TypeList.h" #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Timer.h" #include "llvm/ADT/StringRef.h" @@ -250,7 +250,7 @@ ObjCLanguageRuntime::GetClassDescriptor(ValueObject &valobj) { Process *process = exe_ctx.GetProcessPtr(); if (process) { - Error error; + Status error; ObjCISA isa = process->ReadPointerFromMemory(isa_pointer, error); if (isa != LLDB_INVALID_ADDRESS) objc_class_sp = GetClassDescriptorFromISA(isa); @@ -377,9 +377,9 @@ bool ObjCLanguageRuntime::ObjCExceptionPrecondition::EvaluatePrecondition( void ObjCLanguageRuntime::ObjCExceptionPrecondition::GetDescription( Stream &stream, lldb::DescriptionLevel level) {} -Error ObjCLanguageRuntime::ObjCExceptionPrecondition::ConfigurePrecondition( +Status ObjCLanguageRuntime::ObjCExceptionPrecondition::ConfigurePrecondition( Args &args) { - Error error; + Status error; if (args.GetArgumentCount() > 0) error.SetErrorString( "The ObjC Exception breakpoint doesn't support extra options."); diff --git a/contrib/llvm/tools/lldb/source/Target/PathMappingList.cpp b/contrib/llvm/tools/lldb/source/Target/PathMappingList.cpp index 90fff57..b834a36 100644 --- a/contrib/llvm/tools/lldb/source/Target/PathMappingList.cpp +++ b/contrib/llvm/tools/lldb/source/Target/PathMappingList.cpp @@ -14,11 +14,11 @@ // Other libraries and framework includes // Project includes -#include "lldb/Core/Error.h" -#include "lldb/Core/Stream.h" -#include "lldb/Host/FileSpec.h" #include "lldb/Host/PosixApi.h" #include "lldb/Target/PathMappingList.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/Status.h" +#include "lldb/Utility/Stream.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Target/Platform.cpp b/contrib/llvm/tools/lldb/source/Target/Platform.cpp index d8db536..1d72887 100644 --- a/contrib/llvm/tools/lldb/source/Target/Platform.cpp +++ b/contrib/llvm/tools/lldb/source/Target/Platform.cpp @@ -18,30 +18,32 @@ #include "llvm/Support/Path.h" // Project includes -#include "Utility/ModuleCache.h" #include "lldb/Breakpoint/BreakpointIDList.h" #include "lldb/Breakpoint/BreakpointLocation.h" -#include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/Error.h" -#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/StreamFile.h" -#include "lldb/Core/StructuredData.h" -#include "lldb/Host/FileSpec.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" +#include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Interpreter/Property.h" #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Target/ModuleCache.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/UnixSignals.h" -#include "lldb/Utility/Utils.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Status.h" +#include "lldb/Utility/StructuredData.h" + +#include "llvm/Support/FileSystem.h" // Define these constants from POSIX mman.h rather than include the file // so that they will be correct even when compiled on Linux. @@ -168,11 +170,11 @@ void Platform::SetHostPlatform(const lldb::PlatformSP &platform_sp) { } } -Error Platform::GetFileWithUUID(const FileSpec &platform_file, - const UUID *uuid_ptr, FileSpec &local_file) { +Status Platform::GetFileWithUUID(const FileSpec &platform_file, + const UUID *uuid_ptr, FileSpec &local_file) { // Default to the local case local_file = platform_file; - return Error(); + return Status(); } FileSpecList @@ -215,11 +217,11 @@ Platform::LocateExecutableScriptingResources(Target *target, Module &module, // return PlatformSP(); //} -Error Platform::GetSharedModule(const ModuleSpec &module_spec, Process *process, - ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, - ModuleSP *old_module_sp_ptr, - bool *did_create_ptr) { +Status Platform::GetSharedModule(const ModuleSpec &module_spec, + Process *process, ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr, + ModuleSP *old_module_sp_ptr, + bool *did_create_ptr) { if (IsHost()) return ModuleList::GetSharedModule( module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, @@ -227,7 +229,7 @@ Error Platform::GetSharedModule(const ModuleSpec &module_spec, Process *process, return GetRemoteSharedModule(module_spec, process, module_sp, [&](const ModuleSpec &spec) { - Error error = ModuleList::GetSharedModule( + Status error = ModuleList::GetSharedModule( spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr, false); if (error.Success() && module_sp) @@ -265,7 +267,7 @@ PlatformSP Platform::Find(const ConstString &name) { return PlatformSP(); } -PlatformSP Platform::Create(const ConstString &name, Error &error) { +PlatformSP Platform::Create(const ConstString &name, Status &error) { PlatformCreateInstance create_callback = nullptr; lldb::PlatformSP platform_sp; if (name) { @@ -293,7 +295,7 @@ PlatformSP Platform::Create(const ConstString &name, Error &error) { } PlatformSP Platform::Create(const ArchSpec &arch, ArchSpec *platform_arch_ptr, - Error &error) { + Status &error) { lldb::PlatformSP platform_sp; if (arch.IsValid()) { // Scope for locker @@ -523,11 +525,11 @@ void Platform::AddClangModuleCompilationOptions( FileSpec Platform::GetWorkingDirectory() { if (IsHost()) { - char cwd[PATH_MAX]; - if (getcwd(cwd, sizeof(cwd))) - return FileSpec{cwd, true}; - else + llvm::SmallString<64> cwd; + if (llvm::sys::fs::current_path(cwd)) return FileSpec{}; + else + return FileSpec(cwd, true); } else { if (!m_working_dir) m_working_dir = GetRemoteWorkingDirectory(); @@ -538,26 +540,27 @@ FileSpec Platform::GetWorkingDirectory() { struct RecurseCopyBaton { const FileSpec &dst; Platform *platform_ptr; - Error error; + Status error; }; static FileSpec::EnumerateDirectoryResult -RecurseCopy_Callback(void *baton, FileSpec::FileType file_type, +RecurseCopy_Callback(void *baton, llvm::sys::fs::file_type ft, const FileSpec &src) { RecurseCopyBaton *rc_baton = (RecurseCopyBaton *)baton; - switch (file_type) { - case FileSpec::eFileTypePipe: - case FileSpec::eFileTypeSocket: + namespace fs = llvm::sys::fs; + switch (ft) { + case fs::file_type::fifo_file: + case fs::file_type::socket_file: // we have no way to copy pipes and sockets - ignore them and continue return FileSpec::eEnumerateDirectoryResultNext; break; - case FileSpec::eFileTypeDirectory: { + case fs::file_type::directory_file: { // make the new directory and get in there FileSpec dst_dir = rc_baton->dst; if (!dst_dir.GetFilename()) dst_dir.GetFilename() = src.GetLastPathComponent(); - Error error = rc_baton->platform_ptr->MakeDirectory( + Status error = rc_baton->platform_ptr->MakeDirectory( dst_dir, lldb::eFilePermissionsDirectoryDefault); if (error.Fail()) { rc_baton->error.SetErrorStringWithFormat( @@ -572,7 +575,8 @@ RecurseCopy_Callback(void *baton, FileSpec::FileType file_type, // when we enumerate we can quickly fill in the filename for dst copies FileSpec recurse_dst; recurse_dst.GetDirectory().SetCString(dst_dir.GetPath().c_str()); - RecurseCopyBaton rc_baton2 = {recurse_dst, rc_baton->platform_ptr, Error()}; + RecurseCopyBaton rc_baton2 = {recurse_dst, rc_baton->platform_ptr, + Status()}; FileSpec::EnumerateDirectory(src_dir_path, true, true, true, RecurseCopy_Callback, &rc_baton2); if (rc_baton2.error.Fail()) { @@ -582,7 +586,7 @@ RecurseCopy_Callback(void *baton, FileSpec::FileType file_type, return FileSpec::eEnumerateDirectoryResultNext; } break; - case FileSpec::eFileTypeSymbolicLink: { + case fs::file_type::symlink_file: { // copy the file and keep going FileSpec dst_file = rc_baton->dst; if (!dst_file.GetFilename()) @@ -604,12 +608,12 @@ RecurseCopy_Callback(void *baton, FileSpec::FileType file_type, return FileSpec::eEnumerateDirectoryResultNext; } break; - case FileSpec::eFileTypeRegular: { + case fs::file_type::regular_file: { // copy the file and keep going FileSpec dst_file = rc_baton->dst; if (!dst_file.GetFilename()) dst_file.GetFilename() = src.GetFilename(); - Error err = rc_baton->platform_ptr->PutFile(src, dst_file); + Status err = rc_baton->platform_ptr->PutFile(src, dst_file); if (err.Fail()) { rc_baton->error.SetErrorString(err.AsCString()); return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out @@ -617,19 +621,17 @@ RecurseCopy_Callback(void *baton, FileSpec::FileType file_type, return FileSpec::eEnumerateDirectoryResultNext; } break; - case FileSpec::eFileTypeInvalid: - case FileSpec::eFileTypeOther: - case FileSpec::eFileTypeUnknown: + default: rc_baton->error.SetErrorStringWithFormat( "invalid file detected during copy: %s", src.GetPath().c_str()); return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out break; } - llvm_unreachable("Unhandled FileSpec::FileType!"); + llvm_unreachable("Unhandled file_type!"); } -Error Platform::Install(const FileSpec &src, const FileSpec &dst) { - Error error; +Status Platform::Install(const FileSpec &src, const FileSpec &dst) { + Status error; Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); if (log) @@ -693,10 +695,10 @@ Error Platform::Install(const FileSpec &src, const FileSpec &dst) { if (GetSupportsRSync()) { error = PutFile(src, dst); } else { - switch (src.GetFileType()) { - case FileSpec::eFileTypeDirectory: { - if (GetFileExists(fixed_dst)) - Unlink(fixed_dst); + namespace fs = llvm::sys::fs; + switch (fs::get_file_type(src.GetPath(), false)) { + case fs::file_type::directory_file: { + llvm::sys::fs::remove(fixed_dst.GetPath()); uint32_t permissions = src.GetPermissions(); if (permissions == 0) permissions = eFilePermissionsDirectoryDefault; @@ -707,36 +709,32 @@ Error Platform::Install(const FileSpec &src, const FileSpec &dst) { FileSpec recurse_dst; recurse_dst.GetDirectory().SetCString(fixed_dst.GetCString()); std::string src_dir_path(src.GetPath()); - RecurseCopyBaton baton = {recurse_dst, this, Error()}; + RecurseCopyBaton baton = {recurse_dst, this, Status()}; FileSpec::EnumerateDirectory(src_dir_path, true, true, true, RecurseCopy_Callback, &baton); return baton.error; } } break; - case FileSpec::eFileTypeRegular: - if (GetFileExists(fixed_dst)) - Unlink(fixed_dst); + case fs::file_type::regular_file: + llvm::sys::fs::remove(fixed_dst.GetPath()); error = PutFile(src, fixed_dst); break; - case FileSpec::eFileTypeSymbolicLink: { - if (GetFileExists(fixed_dst)) - Unlink(fixed_dst); + case fs::file_type::symlink_file: { + llvm::sys::fs::remove(fixed_dst.GetPath()); FileSpec src_resolved; error = FileSystem::Readlink(src, src_resolved); if (error.Success()) error = CreateSymlink(dst, src_resolved); } break; - case FileSpec::eFileTypePipe: + case fs::file_type::fifo_file: error.SetErrorString("platform install doesn't handle pipes"); break; - case FileSpec::eFileTypeSocket: + case fs::file_type::socket_file: error.SetErrorString("platform install doesn't handle sockets"); break; - case FileSpec::eFileTypeInvalid: - case FileSpec::eFileTypeUnknown: - case FileSpec::eFileTypeOther: + default: error.SetErrorString( "platform install doesn't handle non file or directory items"); break; @@ -748,25 +746,24 @@ Error Platform::Install(const FileSpec &src, const FileSpec &dst) { bool Platform::SetWorkingDirectory(const FileSpec &file_spec) { if (IsHost()) { Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM); - if (log) - log->Printf("Platform::SetWorkingDirectory('%s')", - file_spec.GetCString()); - if (file_spec) { - if (::chdir(file_spec.GetCString()) == 0) - return true; + LLDB_LOG(log, "{0}", file_spec); + if (std::error_code ec = llvm::sys::fs::set_current_path(file_spec.GetPath())) { + LLDB_LOG(log, "error: {0}", ec.message()); + return false; } - return false; + return true; } else { m_working_dir.Clear(); return SetRemoteWorkingDirectory(file_spec); } } -Error Platform::MakeDirectory(const FileSpec &file_spec, uint32_t permissions) { +Status Platform::MakeDirectory(const FileSpec &file_spec, + uint32_t permissions) { if (IsHost()) - return FileSystem::MakeDirectory(file_spec, permissions); + return llvm::sys::fs::create_directory(file_spec.GetPath(), permissions); else { - Error error; + Status error; error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), LLVM_PRETTY_FUNCTION); @@ -774,12 +771,15 @@ Error Platform::MakeDirectory(const FileSpec &file_spec, uint32_t permissions) { } } -Error Platform::GetFilePermissions(const FileSpec &file_spec, - uint32_t &file_permissions) { - if (IsHost()) - return FileSystem::GetFilePermissions(file_spec, file_permissions); - else { - Error error; +Status Platform::GetFilePermissions(const FileSpec &file_spec, + uint32_t &file_permissions) { + if (IsHost()) { + auto Value = llvm::sys::fs::getPermissions(file_spec.GetPath()); + if (Value) + file_permissions = Value.get(); + return Status(Value.getError()); + } else { + Status error; error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), LLVM_PRETTY_FUNCTION); @@ -787,12 +787,13 @@ Error Platform::GetFilePermissions(const FileSpec &file_spec, } } -Error Platform::SetFilePermissions(const FileSpec &file_spec, - uint32_t file_permissions) { - if (IsHost()) - return FileSystem::SetFilePermissions(file_spec, file_permissions); - else { - Error error; +Status Platform::SetFilePermissions(const FileSpec &file_spec, + uint32_t file_permissions) { + if (IsHost()) { + auto Perms = static_cast<llvm::sys::fs::perms>(file_permissions); + return llvm::sys::fs::setPermissions(file_spec.GetPath(), Perms); + } else { + Status error; error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), LLVM_PRETTY_FUNCTION); @@ -878,10 +879,11 @@ bool Platform::SetOSVersion(uint32_t major, uint32_t minor, uint32_t update) { return false; } -Error Platform::ResolveExecutable(const ModuleSpec &module_spec, - lldb::ModuleSP &exe_module_sp, - const FileSpecList *module_search_paths_ptr) { - Error error; +Status +Platform::ResolveExecutable(const ModuleSpec &module_spec, + lldb::ModuleSP &exe_module_sp, + const FileSpecList *module_search_paths_ptr) { + Status error; if (module_spec.GetFileSpec().Exists()) { if (module_spec.GetArchitecture().IsValid()) { error = ModuleList::GetSharedModule(module_spec, exe_module_sp, @@ -910,9 +912,9 @@ Error Platform::ResolveExecutable(const ModuleSpec &module_spec, return error; } -Error Platform::ResolveSymbolFile(Target &target, const ModuleSpec &sym_spec, - FileSpec &sym_file) { - Error error; +Status Platform::ResolveSymbolFile(Target &target, const ModuleSpec &sym_spec, + FileSpec &sym_file) { + Status error; if (sym_spec.GetSymbolFileSpec().Exists()) sym_file = sym_spec.GetSymbolFileSpec(); else @@ -961,8 +963,8 @@ const ArchSpec &Platform::GetSystemArchitecture() { return m_system_arch; } -Error Platform::ConnectRemote(Args &args) { - Error error; +Status Platform::ConnectRemote(Args &args) { + Status error; if (IsHost()) error.SetErrorStringWithFormat("The currently selected platform (%s) is " "the host platform and is always connected.", @@ -974,8 +976,8 @@ Error Platform::ConnectRemote(Args &args) { return error; } -Error Platform::DisconnectRemote() { - Error error; +Status Platform::DisconnectRemote() { + Status error; if (IsHost()) error.SetErrorStringWithFormat("The currently selected platform (%s) is " "the host platform and is always connected.", @@ -1006,8 +1008,8 @@ uint32_t Platform::FindProcesses(const ProcessInstanceInfoMatch &match_info, return match_count; } -Error Platform::LaunchProcess(ProcessLaunchInfo &launch_info) { - Error error; +Status Platform::LaunchProcess(ProcessLaunchInfo &launch_info) { + Status error; Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); if (log) log->Printf("Platform::%s()", __FUNCTION__); @@ -1058,13 +1060,13 @@ Error Platform::LaunchProcess(ProcessLaunchInfo &launch_info) { return error; } -Error Platform::ShellExpandArguments(ProcessLaunchInfo &launch_info) { +Status Platform::ShellExpandArguments(ProcessLaunchInfo &launch_info) { if (IsHost()) return Host::ShellExpandArguments(launch_info); - return Error("base lldb_private::Platform class can't expand arguments"); + return Status("base lldb_private::Platform class can't expand arguments"); } -Error Platform::KillProcess(const lldb::pid_t pid) { +Status Platform::KillProcess(const lldb::pid_t pid) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); if (log) log->Printf("Platform::%s, pid %" PRIu64, __FUNCTION__, pid); @@ -1084,19 +1086,19 @@ Error Platform::KillProcess(const lldb::pid_t pid) { } if (!IsHost()) { - return Error( + return Status( "base lldb_private::Platform class can't kill remote processes unless " "they are controlled by a process plugin"); } Host::Kill(pid, SIGTERM); - return Error(); + return Status(); } lldb::ProcessSP Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, Target *target, // Can be nullptr, if nullptr create a // new target, else use existing one - Error &error) { + Status &error) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); if (log) log->Printf("Platform::%s entered (target %p)", __FUNCTION__, @@ -1187,7 +1189,7 @@ lldb::PlatformSP Platform::GetPlatformForArchitecture(const ArchSpec &arch, ArchSpec *platform_arch_ptr) { lldb::PlatformSP platform_sp; - Error error; + Status error; if (arch.IsValid()) platform_sp = Platform::Create(arch, platform_arch_ptr, error); return platform_sp; @@ -1231,25 +1233,26 @@ bool Platform::IsCompatibleArchitecture(const ArchSpec &arch, return false; } -Error Platform::PutFile(const FileSpec &source, const FileSpec &destination, - uint32_t uid, uint32_t gid) { +Status Platform::PutFile(const FileSpec &source, const FileSpec &destination, + uint32_t uid, uint32_t gid) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); if (log) log->Printf("[PutFile] Using block by block transfer....\n"); uint32_t source_open_options = File::eOpenOptionRead | File::eOpenOptionCloseOnExec; - if (source.GetFileType() == FileSpec::eFileTypeSymbolicLink) + namespace fs = llvm::sys::fs; + if (fs::is_symlink_file(source.GetPath())) source_open_options |= File::eOpenOptionDontFollowSymlinks; File source_file(source, source_open_options, lldb::eFilePermissionsUserRW); - Error error; + Status error; uint32_t permissions = source_file.GetPermissions(error); if (permissions == 0) permissions = lldb::eFilePermissionsFileDefault; if (!source_file.IsValid()) - return Error("PutFile: unable to open source file"); + return Status("PutFile: unable to open source file"); lldb::user_id_t dest_file = OpenFile( destination, File::eOpenOptionCanCreate | File::eOpenOptionWrite | File::eOpenOptionTruncate | File::eOpenOptionCloseOnExec, @@ -1260,7 +1263,7 @@ Error Platform::PutFile(const FileSpec &source, const FileSpec &destination, if (error.Fail()) return error; if (dest_file == UINT64_MAX) - return Error("unable to open target file"); + return Status("unable to open target file"); lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0)); uint64_t offset = 0; for (;;) { @@ -1291,16 +1294,16 @@ Error Platform::PutFile(const FileSpec &source, const FileSpec &destination, return error; } -Error Platform::GetFile(const FileSpec &source, const FileSpec &destination) { - Error error("unimplemented"); +Status Platform::GetFile(const FileSpec &source, const FileSpec &destination) { + Status error("unimplemented"); return error; } -Error Platform::CreateSymlink( - const FileSpec &src, // The name of the link is in src - const FileSpec &dst) // The symlink points to dst +Status +Platform::CreateSymlink(const FileSpec &src, // The name of the link is in src + const FileSpec &dst) // The symlink points to dst { - Error error("unimplemented"); + Status error("unimplemented"); return error; } @@ -1308,22 +1311,26 @@ bool Platform::GetFileExists(const lldb_private::FileSpec &file_spec) { return false; } -Error Platform::Unlink(const FileSpec &path) { - Error error("unimplemented"); +Status Platform::Unlink(const FileSpec &path) { + Status error("unimplemented"); return error; } -uint64_t Platform::ConvertMmapFlagsToPlatform(const ArchSpec &arch, - unsigned flags) { +MmapArgList Platform::GetMmapArgumentList(const ArchSpec &arch, addr_t addr, + addr_t length, unsigned prot, + unsigned flags, addr_t fd, + addr_t offset) { uint64_t flags_platform = 0; if (flags & eMmapFlagsPrivate) flags_platform |= MAP_PRIVATE; if (flags & eMmapFlagsAnon) flags_platform |= MAP_ANON; - return flags_platform; + + MmapArgList args({addr, length, prot, flags_platform, fd, offset}); + return args; } -lldb_private::Error Platform::RunShellCommand( +lldb_private::Status Platform::RunShellCommand( const char *command, // Shouldn't be nullptr const FileSpec & working_dir, // Pass empty FileSpec to use the current working directory @@ -1339,15 +1346,18 @@ lldb_private::Error Platform::RunShellCommand( return Host::RunShellCommand(command, working_dir, status_ptr, signo_ptr, command_output, timeout_sec); else - return Error("unimplemented"); + return Status("unimplemented"); } bool Platform::CalculateMD5(const FileSpec &file_spec, uint64_t &low, uint64_t &high) { - if (IsHost()) - return FileSystem::CalculateMD5(file_spec, low, high); - else + if (!IsHost()) + return false; + auto Result = llvm::sys::fs::md5_contents(file_spec.GetPath()); + if (!Result) return false; + std::tie(high, low) = Result->words(); + return true; } void Platform::SetLocalCacheDirectory(const char *local) { @@ -1399,11 +1409,11 @@ void OptionGroupPlatformRSync::OptionParsingStarting( m_ignores_remote_hostname = false; } -lldb_private::Error +lldb_private::Status OptionGroupPlatformRSync::SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) { - Error error; + Status error; char short_option = (char)GetDefinitions()[option_idx].short_option; switch (short_option) { case 'r': @@ -1445,11 +1455,11 @@ void OptionGroupPlatformSSH::OptionParsingStarting( m_ssh_opts.clear(); } -lldb_private::Error +lldb_private::Status OptionGroupPlatformSSH::SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) { - Error error; + Status error; char short_option = (char)GetDefinitions()[option_idx].short_option; switch (short_option) { case 's': @@ -1477,10 +1487,10 @@ void OptionGroupPlatformCaching::OptionParsingStarting( m_cache_dir.clear(); } -lldb_private::Error OptionGroupPlatformCaching::SetOptionValue( +lldb_private::Status OptionGroupPlatformCaching::SetOptionValue( uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) { - Error error; + Status error; char short_option = (char)GetDefinitions()[option_idx].short_option; switch (short_option) { case 'c': @@ -1511,10 +1521,9 @@ const std::vector<ConstString> &Platform::GetTrapHandlerSymbolNames() { return m_trap_handlers; } -Error Platform::GetCachedExecutable(ModuleSpec &module_spec, - lldb::ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, - Platform &remote_platform) { +Status Platform::GetCachedExecutable( + ModuleSpec &module_spec, lldb::ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr, Platform &remote_platform) { const auto platform_spec = module_spec.GetFileSpec(); const auto error = LoadCachedExecutable( module_spec, module_sp, module_search_paths_ptr, remote_platform); @@ -1526,7 +1535,7 @@ Error Platform::GetCachedExecutable(ModuleSpec &module_spec, return error; } -Error Platform::LoadCachedExecutable( +Status Platform::LoadCachedExecutable( const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr, Platform &remote_platform) { return GetRemoteSharedModule(module_spec, nullptr, module_sp, @@ -1537,11 +1546,11 @@ Error Platform::LoadCachedExecutable( nullptr); } -Error Platform::GetRemoteSharedModule(const ModuleSpec &module_spec, - Process *process, - lldb::ModuleSP &module_sp, - const ModuleResolver &module_resolver, - bool *did_create_ptr) { +Status Platform::GetRemoteSharedModule(const ModuleSpec &module_spec, + Process *process, + lldb::ModuleSP &module_sp, + const ModuleResolver &module_resolver, + bool *did_create_ptr) { // Get module information from a target. ModuleSpec resolved_module_spec; bool got_module_spec = false; @@ -1558,7 +1567,7 @@ Error Platform::GetRemoteSharedModule(const ModuleSpec &module_spec, } if (module_spec.GetArchitecture().IsValid() == false) { - Error error; + Status error; // No valid architecture was specified, ask the platform for // the architectures that we should be using (in the correct order) // and see if we can find a match that way @@ -1597,7 +1606,7 @@ Error Platform::GetRemoteSharedModule(const ModuleSpec &module_spec, const auto error = module_resolver(resolved_module_spec); if (error.Fail()) { if (GetCachedSharedModule(resolved_module_spec, module_sp, did_create_ptr)) - return Error(); + return Status(); } return error; @@ -1637,14 +1646,15 @@ bool Platform::GetCachedSharedModule(const ModuleSpec &module_spec, return false; } -Error Platform::DownloadModuleSlice(const FileSpec &src_file_spec, - const uint64_t src_offset, - const uint64_t src_size, - const FileSpec &dst_file_spec) { - Error error; +Status Platform::DownloadModuleSlice(const FileSpec &src_file_spec, + const uint64_t src_offset, + const uint64_t src_size, + const FileSpec &dst_file_spec) { + Status error; - std::ofstream dst(dst_file_spec.GetPath(), std::ios::out | std::ios::binary); - if (!dst.is_open()) { + std::error_code EC; + llvm::raw_fd_ostream dst(dst_file_spec.GetPath(), EC, llvm::sys::fs::F_None); + if (EC) { error.SetErrorStringWithFormat("unable to open destination file: %s", dst_file_spec.GetPath().c_str()); return error; @@ -1678,15 +1688,15 @@ Error Platform::DownloadModuleSlice(const FileSpec &src_file_spec, dst.write(&buffer[0], n_read); } - Error close_error; + Status close_error; CloseFile(src_fd, close_error); // Ignoring close error. return error; } -Error Platform::DownloadSymbolFile(const lldb::ModuleSP &module_sp, - const FileSpec &dst_file_spec) { - return Error( +Status Platform::DownloadSymbolFile(const lldb::ModuleSP &module_sp, + const FileSpec &dst_file_spec) { + return Status( "Symbol file downloading not supported by the default platform."); } @@ -1712,7 +1722,7 @@ const UnixSignalsSP &Platform::GetUnixSignals() { uint32_t Platform::LoadImage(lldb_private::Process *process, const lldb_private::FileSpec &local_file, const lldb_private::FileSpec &remote_file, - lldb_private::Error &error) { + lldb_private::Status &error) { if (local_file && remote_file) { // Both local and remote file was specified. Install the local file to the // given location. @@ -1748,21 +1758,21 @@ uint32_t Platform::LoadImage(lldb_private::Process *process, uint32_t Platform::DoLoadImage(lldb_private::Process *process, const lldb_private::FileSpec &remote_file, - lldb_private::Error &error) { + lldb_private::Status &error) { error.SetErrorString("LoadImage is not supported on the current platform"); return LLDB_INVALID_IMAGE_TOKEN; } -Error Platform::UnloadImage(lldb_private::Process *process, - uint32_t image_token) { - return Error("UnloadImage is not supported on the current platform"); +Status Platform::UnloadImage(lldb_private::Process *process, + uint32_t image_token) { + return Status("UnloadImage is not supported on the current platform"); } lldb::ProcessSP Platform::ConnectProcess(llvm::StringRef connect_url, llvm::StringRef plugin_name, lldb_private::Debugger &debugger, lldb_private::Target *target, - lldb_private::Error &error) { + lldb_private::Status &error) { error.Clear(); if (!target) { @@ -1791,7 +1801,7 @@ lldb::ProcessSP Platform::ConnectProcess(llvm::StringRef connect_url, } size_t Platform::ConnectToWaitingProcesses(lldb_private::Debugger &debugger, - lldb_private::Error &error) { + lldb_private::Status &error) { error.Clear(); return 0; } diff --git a/contrib/llvm/tools/lldb/source/Target/Process.cpp b/contrib/llvm/tools/lldb/source/Target/Process.cpp index c72662e..6cbe289 100644 --- a/contrib/llvm/tools/lldb/source/Target/Process.cpp +++ b/contrib/llvm/tools/lldb/source/Target/Process.cpp @@ -14,13 +14,14 @@ // Other libraries and framework includes #include "llvm/Support/ScopedPrinter.h" +#include "llvm/Support/Threading.h" + // Project includes #include "Plugins/Process/Utility/InferiorCallPOSIX.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Event.h" -#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" @@ -33,6 +34,7 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" +#include "lldb/Host/OptionParser.h" #include "lldb/Host/Pipe.h" #include "lldb/Host/Terminal.h" #include "lldb/Host/ThreadLauncher.h" @@ -63,6 +65,7 @@ #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/ThreadPlanBase.h" #include "lldb/Target/UnixSignals.h" +#include "lldb/Utility/Log.h" #include "lldb/Utility/NameMatches.h" #include "lldb/Utility/SelectHelper.h" @@ -412,10 +415,10 @@ void ProcessInstanceInfo::DumpAsTableRow(Stream &s, Platform *platform, } } -Error ProcessLaunchCommandOptions::SetOptionValue( +Status ProcessLaunchCommandOptions::SetOptionValue( uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) { - Error error; + Status error; const int short_option = m_getopt_table[option_idx].val; switch (short_option) { @@ -581,7 +584,7 @@ llvm::ArrayRef<OptionDefinition> ProcessLaunchCommandOptions::GetDefinitions() { } bool ProcessInstanceInfoMatch::NameMatches(const char *process_name) const { - if (m_name_match_type == eNameMatchIgnore || process_name == nullptr) + if (m_name_match_type == NameMatch::Ignore || process_name == nullptr) return true; const char *match_name = m_match_info.GetName(); if (!match_name) @@ -627,7 +630,7 @@ bool ProcessInstanceInfoMatch::Matches( } bool ProcessInstanceInfoMatch::MatchAllProcesses() const { - if (m_name_match_type != eNameMatchIgnore) + if (m_name_match_type != NameMatch::Ignore) return false; if (m_match_info.ProcessIDIsValid()) @@ -659,7 +662,7 @@ bool ProcessInstanceInfoMatch::MatchAllProcesses() const { void ProcessInstanceInfoMatch::Clear() { m_match_info.Clear(); - m_name_match_type = eNameMatchIgnore; + m_name_match_type = NameMatch::Ignore; m_match_all_users = false; } @@ -982,10 +985,7 @@ StateType Process::WaitForProcessToStop(const Timeout<std::micro> &timeout, return state; Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); - if (log) - log->Printf( - "Process::%s (timeout = %llu)", __FUNCTION__, - static_cast<unsigned long long>(timeout ? timeout->count() : -1)); + LLDB_LOG(log, "timeout = {0}", timeout); if (!wait_always && StateIsStoppedState(state, true) && StateIsStoppedState(GetPrivateState(), true)) { @@ -1261,11 +1261,7 @@ StateType Process::GetStateChangedEvents(EventSP &event_sp, const Timeout<std::micro> &timeout, ListenerSP hijack_listener_sp) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); - - if (log) - log->Printf( - "Process::%s (timeout = %llu, event_sp)...", __FUNCTION__, - static_cast<unsigned long long>(timeout ? timeout->count() : -1)); + LLDB_LOG(log, "timeout = {0}, event_sp)...", timeout); ListenerSP listener_sp = hijack_listener_sp; if (!listener_sp) @@ -1277,15 +1273,11 @@ StateType Process::GetStateChangedEvents(EventSP &event_sp, timeout)) { if (event_sp && event_sp->GetType() == eBroadcastBitStateChanged) state = Process::ProcessEventData::GetStateFromEvent(event_sp.get()); - else if (log) - log->Printf("Process::%s got no event or was interrupted.", __FUNCTION__); + else + LLDB_LOG(log, "got no event or was interrupted."); } - if (log) - log->Printf( - "Process::%s (timeout = %llu, event_sp) => %s", __FUNCTION__, - static_cast<unsigned long long>(timeout ? timeout->count() : -1), - StateAsCString(state)); + LLDB_LOG(log, "timeout = {0}, event_sp) => {1}", timeout, state); return state; } @@ -1314,11 +1306,7 @@ StateType Process::GetStateChangedEventsPrivate(EventSP &event_sp, const Timeout<std::micro> &timeout) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); - - if (log) - log->Printf( - "Process::%s (timeout = %llu, event_sp)...", __FUNCTION__, - static_cast<unsigned long long>(timeout ? timeout->count() : -1)); + LLDB_LOG(log, "timeout = {0}, event_sp)...", timeout); StateType state = eStateInvalid; if (m_private_state_listener_sp->GetEventForBroadcasterWithType( @@ -1328,14 +1316,8 @@ Process::GetStateChangedEventsPrivate(EventSP &event_sp, if (event_sp && event_sp->GetType() == eBroadcastBitStateChanged) state = Process::ProcessEventData::GetStateFromEvent(event_sp.get()); - // This is a bit of a hack, but when we wait here we could very well return - // to the command-line, and that could disable the log, which would render the - // log we got above invalid. - if (log) - log->Printf( - "Process::%s (timeout = %llu, event_sp) => %s", __FUNCTION__, - static_cast<unsigned long long>(timeout ? timeout->count() : -1), - state == eStateInvalid ? "TIMEOUT" : StateAsCString(state)); + LLDB_LOG(log, "timeout = {0}, event_sp) => {1}", timeout, + state == eStateInvalid ? "TIMEOUT" : StateAsCString(state)); return state; } @@ -1343,11 +1325,7 @@ bool Process::GetEventsPrivate(EventSP &event_sp, const Timeout<std::micro> &timeout, bool control_only) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); - - if (log) - log->Printf( - "Process::%s (timeout = %llu, event_sp)...", __FUNCTION__, - static_cast<unsigned long long>(timeout ? timeout->count() : -1)); + LLDB_LOG(log, "timeout = {0}, event_sp)...", timeout); if (control_only) return m_private_state_listener_sp->GetEventForBroadcaster( @@ -1632,13 +1610,13 @@ void Process::SetPublicState(StateType new_state, bool restarted) { } } -Error Process::Resume() { +Status Process::Resume() { Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STATE | LIBLLDB_LOG_PROCESS)); if (log) log->Printf("Process::Resume -- locking run lock"); if (!m_public_run_lock.TrySetRunning()) { - Error error("Resume request failed - process still running."); + Status error("Resume request failed - process still running."); if (log) log->Printf("Process::Resume: -- TrySetRunning failed, not resuming."); return error; @@ -1646,13 +1624,13 @@ Error Process::Resume() { return PrivateResume(); } -Error Process::ResumeSynchronous(Stream *stream) { +Status Process::ResumeSynchronous(Stream *stream) { Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STATE | LIBLLDB_LOG_PROCESS)); if (log) log->Printf("Process::ResumeSynchronous -- locking run lock"); if (!m_public_run_lock.TrySetRunning()) { - Error error("Resume request failed - process still running."); + Status error("Resume request failed - process still running."); if (log) log->Printf("Process::Resume: -- TrySetRunning failed, not resuming."); return error; @@ -1662,7 +1640,7 @@ Error Process::ResumeSynchronous(Stream *stream) { Listener::MakeListener("lldb.Process.ResumeSynchronous.hijack")); HijackProcessEvents(listener_sp); - Error error = PrivateResume(); + Status error = PrivateResume(); if (error.Success()) { StateType state = WaitForProcessToStop(llvm::None, NULL, true, listener_sp, stream); @@ -1757,7 +1735,7 @@ addr_t Process::GetImageInfoAddress() { return LLDB_INVALID_ADDRESS; } const lldb::ABISP &Process::GetABI() { if (!m_abi_sp) - m_abi_sp = ABI::FindPlugin(GetTarget().GetArchitecture()); + m_abi_sp = ABI::FindPlugin(shared_from_this(), GetTarget().GetArchitecture()); return m_abi_sp; } @@ -1835,8 +1813,8 @@ void Process::DisableAllBreakpointSites() { }); } -Error Process::ClearBreakpointSiteByID(lldb::user_id_t break_id) { - Error error(DisableBreakpointSiteByID(break_id)); +Status Process::ClearBreakpointSiteByID(lldb::user_id_t break_id) { + Status error(DisableBreakpointSiteByID(break_id)); if (error.Success()) m_breakpoint_site_list.Remove(break_id); @@ -1844,8 +1822,8 @@ Error Process::ClearBreakpointSiteByID(lldb::user_id_t break_id) { return error; } -Error Process::DisableBreakpointSiteByID(lldb::user_id_t break_id) { - Error error; +Status Process::DisableBreakpointSiteByID(lldb::user_id_t break_id) { + Status error; BreakpointSiteSP bp_site_sp = m_breakpoint_site_list.FindByID(break_id); if (bp_site_sp) { if (bp_site_sp->IsEnabled()) @@ -1858,8 +1836,8 @@ Error Process::DisableBreakpointSiteByID(lldb::user_id_t break_id) { return error; } -Error Process::EnableBreakpointSiteByID(lldb::user_id_t break_id) { - Error error; +Status Process::EnableBreakpointSiteByID(lldb::user_id_t break_id) { + Status error; BreakpointSiteSP bp_site_sp = m_breakpoint_site_list.FindByID(break_id); if (bp_site_sp) { if (!bp_site_sp->IsEnabled()) @@ -1904,7 +1882,7 @@ Process::CreateBreakpointSite(const BreakpointLocationSP &owner, if (owner->ShouldResolveIndirectFunctions()) { Symbol *symbol = owner->GetAddress().CalculateSymbolContextSymbol(); if (symbol && symbol->IsIndirect()) { - Error error; + Status error; Address symbol_address = symbol->GetAddress(); load_addr = ResolveIndirectFunction(&symbol_address, error); if (!error.Success() && show_error) { @@ -1941,7 +1919,7 @@ Process::CreateBreakpointSite(const BreakpointLocationSP &owner, bp_site_sp.reset(new BreakpointSite(&m_breakpoint_site_list, owner, load_addr, use_hardware)); if (bp_site_sp) { - Error error = EnableBreakpointSite(bp_site_sp.get()); + Status error = EnableBreakpointSite(bp_site_sp.get()); if (error.Success()) { owner->SetBreakpointSite(bp_site_sp); return m_breakpoint_site_list.Add(bp_site_sp); @@ -1981,8 +1959,8 @@ size_t Process::RemoveBreakpointOpcodesFromBuffer(addr_t bp_addr, size_t size, if (m_breakpoint_site_list.FindInRange(bp_addr, bp_addr + size, bp_sites_in_range)) { - bp_sites_in_range.ForEach([bp_addr, size, buf, &bytes_removed]( - BreakpointSite *bp_site) -> void { + bp_sites_in_range.ForEach([bp_addr, size, + buf](BreakpointSite *bp_site) -> void { if (bp_site->GetType() == BreakpointSite::eSoftware) { addr_t intersect_addr; size_t intersect_size; @@ -2011,8 +1989,8 @@ size_t Process::GetSoftwareBreakpointTrapOpcode(BreakpointSite *bp_site) { return 0; } -Error Process::EnableSoftwareBreakpoint(BreakpointSite *bp_site) { - Error error; +Status Process::EnableSoftwareBreakpoint(BreakpointSite *bp_site) { + Status error; assert(bp_site != nullptr); Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); const addr_t bp_addr = bp_site->GetLoadAddress(); @@ -2087,8 +2065,8 @@ Error Process::EnableSoftwareBreakpoint(BreakpointSite *bp_site) { return error; } -Error Process::DisableSoftwareBreakpoint(BreakpointSite *bp_site) { - Error error; +Status Process::DisableSoftwareBreakpoint(BreakpointSite *bp_site) { + Status error; assert(bp_site != nullptr); Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); addr_t bp_addr = bp_site->GetLoadAddress(); @@ -2180,7 +2158,7 @@ Error Process::DisableSoftwareBreakpoint(BreakpointSite *bp_site) { // Uncomment to verify memory caching works after making changes to caching code //#define VERIFY_MEMORY_READS -size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Error &error) { +size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Status &error) { error.Clear(); if (!GetDisableMemoryCache()) { #if defined(VERIFY_MEMORY_READS) @@ -2199,7 +2177,7 @@ size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Error &error) { assert(verify_buf.size() == size); const size_t cache_bytes_read = m_memory_cache.Read(this, addr, buf, size, error); - Error verify_error; + Status verify_error; const size_t verify_bytes_read = ReadMemoryFromInferior(addr, const_cast<char *>(verify_buf.data()), verify_buf.size(), verify_error); @@ -2222,7 +2200,7 @@ size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Error &error) { } size_t Process::ReadCStringFromMemory(addr_t addr, std::string &out_str, - Error &error) { + Status &error) { char buf[256]; out_str.clear(); addr_t curr_addr = addr; @@ -2242,7 +2220,7 @@ size_t Process::ReadCStringFromMemory(addr_t addr, std::string &out_str, } size_t Process::ReadStringFromMemory(addr_t addr, char *dst, size_t max_bytes, - Error &error, size_t type_width) { + Status &error, size_t type_width) { size_t total_bytes_read = 0; if (dst && max_bytes && type_width && max_bytes >= type_width) { // Ensure a null terminator independent of the number of bytes that is read. @@ -2295,13 +2273,14 @@ size_t Process::ReadStringFromMemory(addr_t addr, char *dst, size_t max_bytes, // correct code to find // null terminators. size_t Process::ReadCStringFromMemory(addr_t addr, char *dst, - size_t dst_max_len, Error &result_error) { + size_t dst_max_len, + Status &result_error) { size_t total_cstr_len = 0; if (dst && dst_max_len) { result_error.Clear(); // NULL out everything just to be safe memset(dst, 0, dst_max_len); - Error error; + Status error; addr_t curr_addr = addr; const size_t cache_line_size = m_memory_cache.GetMemoryCacheLineSize(); size_t bytes_left = dst_max_len - 1; @@ -2340,7 +2319,7 @@ size_t Process::ReadCStringFromMemory(addr_t addr, char *dst, } size_t Process::ReadMemoryFromInferior(addr_t addr, void *buf, size_t size, - Error &error) { + Status &error) { if (buf == nullptr || size == 0) return 0; @@ -2366,7 +2345,7 @@ size_t Process::ReadMemoryFromInferior(addr_t addr, void *buf, size_t size, uint64_t Process::ReadUnsignedIntegerFromMemory(lldb::addr_t vm_addr, size_t integer_byte_size, uint64_t fail_value, - Error &error) { + Status &error) { Scalar scalar; if (ReadScalarIntegerFromMemory(vm_addr, integer_byte_size, false, scalar, error)) @@ -2376,7 +2355,8 @@ uint64_t Process::ReadUnsignedIntegerFromMemory(lldb::addr_t vm_addr, int64_t Process::ReadSignedIntegerFromMemory(lldb::addr_t vm_addr, size_t integer_byte_size, - int64_t fail_value, Error &error) { + int64_t fail_value, + Status &error) { Scalar scalar; if (ReadScalarIntegerFromMemory(vm_addr, integer_byte_size, true, scalar, error)) @@ -2384,7 +2364,7 @@ int64_t Process::ReadSignedIntegerFromMemory(lldb::addr_t vm_addr, return fail_value; } -addr_t Process::ReadPointerFromMemory(lldb::addr_t vm_addr, Error &error) { +addr_t Process::ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error) { Scalar scalar; if (ReadScalarIntegerFromMemory(vm_addr, GetAddressByteSize(), false, scalar, error)) @@ -2393,7 +2373,7 @@ addr_t Process::ReadPointerFromMemory(lldb::addr_t vm_addr, Error &error) { } bool Process::WritePointerToMemory(lldb::addr_t vm_addr, lldb::addr_t ptr_value, - Error &error) { + Status &error) { Scalar scalar; const uint32_t addr_byte_size = GetAddressByteSize(); if (addr_byte_size <= 4) @@ -2405,7 +2385,7 @@ bool Process::WritePointerToMemory(lldb::addr_t vm_addr, lldb::addr_t ptr_value, } size_t Process::WriteMemoryPrivate(addr_t addr, const void *buf, size_t size, - Error &error) { + Status &error) { size_t bytes_written = 0; const uint8_t *bytes = (const uint8_t *)buf; @@ -2421,7 +2401,7 @@ size_t Process::WriteMemoryPrivate(addr_t addr, const void *buf, size_t size, } size_t Process::WriteMemory(addr_t addr, const void *buf, size_t size, - Error &error) { + Status &error) { #if defined(ENABLE_MEMORY_CACHING) m_memory_cache.Flush(addr, size); #endif @@ -2500,7 +2480,7 @@ size_t Process::WriteMemory(addr_t addr, const void *buf, size_t size, } size_t Process::WriteScalarToMemory(addr_t addr, const Scalar &scalar, - size_t byte_size, Error &error) { + size_t byte_size, Status &error) { if (byte_size == UINT32_MAX) byte_size = scalar.GetByteSize(); if (byte_size > 0) { @@ -2519,7 +2499,7 @@ size_t Process::WriteScalarToMemory(addr_t addr, const Scalar &scalar, size_t Process::ReadScalarIntegerFromMemory(addr_t addr, uint32_t byte_size, bool is_signed, Scalar &scalar, - Error &error) { + Status &error) { uint64_t uval = 0; if (byte_size == 0) { error.SetErrorString("byte size is zero"); @@ -2549,7 +2529,7 @@ size_t Process::ReadScalarIntegerFromMemory(addr_t addr, uint32_t byte_size, #define USE_ALLOCATE_MEMORY_CACHE 1 addr_t Process::AllocateMemory(size_t size, uint32_t permissions, - Error &error) { + Status &error) { if (GetPrivateState() != eStateStopped) return LLDB_INVALID_ADDRESS; @@ -2570,7 +2550,7 @@ addr_t Process::AllocateMemory(size_t size, uint32_t permissions, } addr_t Process::CallocateMemory(size_t size, uint32_t permissions, - Error &error) { + Status &error) { addr_t return_addr = AllocateMemory(size, permissions, error); if (error.Success()) { std::string buffer(size, 0); @@ -2582,7 +2562,7 @@ addr_t Process::CallocateMemory(size_t size, uint32_t permissions, bool Process::CanJIT() { if (m_can_jit == eCanJITDontKnow) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); - Error err; + Status err; uint64_t allocated_memory = AllocateMemory( 8, ePermissionsReadable | ePermissionsWritable | ePermissionsExecutable, @@ -2617,8 +2597,8 @@ void Process::SetCanRunCode(bool can_run_code) { m_can_interpret_function_calls = can_run_code; } -Error Process::DeallocateMemory(addr_t ptr) { - Error error; +Status Process::DeallocateMemory(addr_t ptr) { + Status error; #if defined(USE_ALLOCATE_MEMORY_CACHE) if (!m_allocated_memory_cache.DeallocateMemory(ptr)) { error.SetErrorStringWithFormat( @@ -2647,7 +2627,7 @@ ModuleSP Process::ReadModuleFromMemory(const FileSpec &file_spec, } ModuleSP module_sp(new Module(file_spec, ArchSpec())); if (module_sp) { - Error error; + Status error; ObjectFile *objfile = module_sp->GetMemoryObjectFile( shared_from_this(), header_addr, error, size_to_read); if (objfile) @@ -2660,7 +2640,7 @@ bool Process::GetLoadAddressPermissions(lldb::addr_t load_addr, uint32_t &permissions) { MemoryRegionInfo range_info; permissions = 0; - Error error(GetMemoryRegionInfo(load_addr, range_info)); + Status error(GetMemoryRegionInfo(load_addr, range_info)); if (!error.Success()) return false; if (range_info.GetReadable() == MemoryRegionInfo::eDontKnow || @@ -2681,14 +2661,14 @@ bool Process::GetLoadAddressPermissions(lldb::addr_t load_addr, return true; } -Error Process::EnableWatchpoint(Watchpoint *watchpoint, bool notify) { - Error error; +Status Process::EnableWatchpoint(Watchpoint *watchpoint, bool notify) { + Status error; error.SetErrorString("watchpoints are not supported"); return error; } -Error Process::DisableWatchpoint(Watchpoint *watchpoint, bool notify) { - Error error; +Status Process::DisableWatchpoint(Watchpoint *watchpoint, bool notify) { + Status error; error.SetErrorString("watchpoints are not supported"); return error; } @@ -2724,8 +2704,8 @@ void Process::LoadOperatingSystemPlugin(bool flush) { Flush(); } -Error Process::Launch(ProcessLaunchInfo &launch_info) { - Error error; +Status Process::Launch(ProcessLaunchInfo &launch_info) { + Status error; m_abi_sp.reset(); m_dyld_ap.reset(); m_jit_loaders_ap.reset(); @@ -2798,7 +2778,12 @@ Error Process::Launch(ProcessLaunchInfo &launch_info) { if (system_runtime) system_runtime->DidLaunch(); - LoadOperatingSystemPlugin(false); + if (!m_os_ap) + LoadOperatingSystemPlugin(false); + + // We successfully launched the process and stopped, + // now it the right time to set up signal filters before resuming. + UpdateAutomaticSignalFiltering(); // Note, the stop event was consumed above, but not handled. This // was done @@ -2840,8 +2825,8 @@ Error Process::Launch(ProcessLaunchInfo &launch_info) { return error; } -Error Process::LoadCore() { - Error error = DoLoadCore(); +Status Process::LoadCore() { + Status error = DoLoadCore(); if (error.Success()) { ListenerSP listener_sp( Listener::MakeListener("lldb.process.load_core_listener")); @@ -2862,7 +2847,9 @@ Error Process::LoadCore() { if (system_runtime) system_runtime->DidAttach(); - m_os_ap.reset(OperatingSystem::FindPlugin(this, nullptr)); + if (!m_os_ap) + LoadOperatingSystemPlugin(false); + // We successfully loaded a core file, now pretend we stopped so we can // show all of the threads in the core file and explore the crashed // state. @@ -2992,7 +2979,7 @@ ListenerSP ProcessAttachInfo::GetListenerForProcess(Debugger &debugger) { return debugger.GetListener(); } -Error Process::Attach(ProcessAttachInfo &attach_info) { +Status Process::Attach(ProcessAttachInfo &attach_info) { m_abi_sp.reset(); m_process_input_reader.reset(); m_dyld_ap.reset(); @@ -3002,7 +2989,7 @@ Error Process::Attach(ProcessAttachInfo &attach_info) { m_stop_info_override_callback = nullptr; lldb::pid_t attach_pid = attach_info.GetProcessID(); - Error error; + Status error; if (attach_pid == LLDB_INVALID_PROCESS_ID) { char process_name[PATH_MAX]; @@ -3046,7 +3033,7 @@ Error Process::Attach(ProcessAttachInfo &attach_info) { if (platform_sp) { ProcessInstanceInfoMatch match_info; match_info.GetProcessInfo() = attach_info; - match_info.SetNameMatchType(eNameMatchEquals); + match_info.SetNameMatchType(NameMatch::Equals); platform_sp->FindProcesses(match_info, process_infos); const uint32_t num_matches = process_infos.GetSize(); if (num_matches == 1) { @@ -3205,7 +3192,8 @@ void Process::CompleteAttach() { } } - m_os_ap.reset(OperatingSystem::FindPlugin(this, nullptr)); + if (!m_os_ap) + LoadOperatingSystemPlugin(false); // Figure out which one is the executable, and set that in our target: const ModuleList &target_modules = GetTarget().GetImages(); std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex()); @@ -3235,14 +3223,14 @@ void Process::CompleteAttach() { m_stop_info_override_callback = process_arch.GetStopInfoOverrideCallback(); } -Error Process::ConnectRemote(Stream *strm, llvm::StringRef remote_url) { +Status Process::ConnectRemote(Stream *strm, llvm::StringRef remote_url) { m_abi_sp.reset(); m_process_input_reader.reset(); // Find the process and its architecture. Make sure it matches the // architecture of the current Target, and if not adjust it. - Error error(DoConnectRemote(strm, remote_url)); + Status error(DoConnectRemote(strm, remote_url)); if (error.Success()) { if (GetID() != LLDB_INVALID_PROCESS_ID) { EventSP event_sp; @@ -3267,7 +3255,7 @@ Error Process::ConnectRemote(Stream *strm, llvm::StringRef remote_url) { return error; } -Error Process::PrivateResume() { +Status Process::PrivateResume() { Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_STEP)); if (log) @@ -3276,7 +3264,11 @@ Error Process::PrivateResume() { m_mod_id.GetStopID(), StateAsCString(m_public_state.GetValue()), StateAsCString(m_private_state.GetValue())); - Error error(WillResume()); + // If signals handing status changed we might want to update + // our signal filters before resuming. + UpdateAutomaticSignalFiltering(); + + Status error(WillResume()); // Tell the process it is about to resume before the thread list if (error.Success()) { // Now let the thread list know we are about to resume so it @@ -3321,9 +3313,9 @@ Error Process::PrivateResume() { return error; } -Error Process::Halt(bool clear_thread_plans, bool use_run_lock) { +Status Process::Halt(bool clear_thread_plans, bool use_run_lock) { if (!StateIsRunningState(m_public_state.GetValue())) - return Error("Process is not running."); + return Status("Process is not running."); // Don't clear the m_clear_thread_plans_on_stop, only set it to true if // in case it was already set and some thread plan logic calls halt on its @@ -3344,7 +3336,7 @@ Error Process::Halt(bool clear_thread_plans, bool use_run_lock) { RestoreProcessEvents(); SetExitStatus(SIGKILL, "Cancelled async attach."); Destroy(false); - return Error(); + return Status(); } // Wait for 10 second for the process to stop. @@ -3354,16 +3346,16 @@ Error Process::Halt(bool clear_thread_plans, bool use_run_lock) { if (state == eStateInvalid || !event_sp) { // We timed out and didn't get a stop event... - return Error("Halt timed out. State = %s", StateAsCString(GetState())); + return Status("Halt timed out. State = %s", StateAsCString(GetState())); } BroadcastEvent(event_sp); - return Error(); + return Status(); } -Error Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp) { - Error error; +Status Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp) { + Status error; // Check both the public & private states here. If we're hung evaluating an // expression, for instance, then @@ -3410,18 +3402,19 @@ Error Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp) { // then continue on. StateType private_state = m_private_state.GetValue(); if (private_state != eStateStopped) { - return Error("Attempt to stop the target in order to detach timed out. " - "State = %s", - StateAsCString(GetState())); + return Status( + "Attempt to stop the target in order to detach timed out. " + "State = %s", + StateAsCString(GetState())); } } } return error; } -Error Process::Detach(bool keep_stopped) { +Status Process::Detach(bool keep_stopped) { EventSP exit_event_sp; - Error error; + Status error; m_destroy_in_process = true; error = WillDetach(); @@ -3473,7 +3466,7 @@ Error Process::Detach(bool keep_stopped) { return error; } -Error Process::Destroy(bool force_kill) { +Status Process::Destroy(bool force_kill) { // Tell ourselves we are in the process of destroying the process, so that we // don't do any unnecessary work @@ -3493,7 +3486,7 @@ Error Process::Destroy(bool force_kill) { m_destroy_in_process = true; - Error error(WillDestroy()); + Status error(WillDestroy()); if (error.Success()) { EventSP exit_event_sp; if (DestroyRequiresHalt()) { @@ -3548,8 +3541,8 @@ Error Process::Destroy(bool force_kill) { return error; } -Error Process::Signal(int signal) { - Error error(WillSignal()); +Status Process::Signal(int signal) { + Status error(WillSignal()); if (error.Success()) { error = DoSignal(signal); if (error.Success()) @@ -3754,8 +3747,8 @@ bool Process::StartPrivateStateThread(bool is_secondary_thread) { // Create a thread that watches our internal state and controls which // events make it to clients (into the DCProcess event queue). char thread_name[1024]; - - if (HostInfo::GetMaxThreadNameLength() <= 30) { + uint32_t max_len = llvm::get_max_thread_name_length(); + if (max_len > 0 && max_len <= 30) { // On platforms with abbreviated thread name lengths, choose thread names // that fit within the limit. if (already_running) @@ -3977,9 +3970,9 @@ void Process::HandlePrivateEvent(EventSP &event_sp) { } } -Error Process::HaltPrivate() { +Status Process::HaltPrivate() { EventSP event_sp; - Error error(WillHalt()); + Status error(WillHalt()); if (error.Fail()) return error; @@ -4047,7 +4040,7 @@ thread_result_t Process::RunPrivateStateThread(bool is_secondary_thread) { log->Printf("Process::%s (arg = %p, pid = %" PRIu64 ") woke up with an interrupt - Halting.", __FUNCTION__, static_cast<void *>(this), GetID()); - Error error = HaltPrivate(); + Status error = HaltPrivate(); if (error.Fail() && log) log->Printf("Process::%s (arg = %p, pid = %" PRIu64 ") failed to halt the process: %s", @@ -4487,7 +4480,7 @@ Process::GetStructuredDataPlugin(const ConstString &type_name) const { return StructuredDataPluginSP(); } -size_t Process::GetAsyncProfileData(char *buf, size_t buf_size, Error &error) { +size_t Process::GetAsyncProfileData(char *buf, size_t buf_size, Status &error) { std::lock_guard<std::recursive_mutex> guard(m_profile_data_comm_mutex); if (m_profile_data.empty()) return 0; @@ -4515,7 +4508,7 @@ size_t Process::GetAsyncProfileData(char *buf, size_t buf_size, Error &error) { // Process STDIO //------------------------------------------------------------------ -size_t Process::GetSTDOUT(char *buf, size_t buf_size, Error &error) { +size_t Process::GetSTDOUT(char *buf, size_t buf_size, Status &error) { std::lock_guard<std::recursive_mutex> guard(m_stdio_communication_mutex); size_t bytes_available = m_stdout_data.size(); if (bytes_available > 0) { @@ -4535,7 +4528,7 @@ size_t Process::GetSTDOUT(char *buf, size_t buf_size, Error &error) { return bytes_available; } -size_t Process::GetSTDERR(char *buf, size_t buf_size, Error &error) { +size_t Process::GetSTDERR(char *buf, size_t buf_size, Status &error) { std::lock_guard<std::recursive_mutex> gaurd(m_stdio_communication_mutex); size_t bytes_available = m_stderr_data.size(); if (bytes_available > 0) { @@ -4598,7 +4591,7 @@ public: SelectHelper select_helper; select_helper.FDSetRead(read_fd); select_helper.FDSetRead(pipe_read_fd); - Error error = select_helper.Select(); + Status error = select_helper.Select(); if (error.Fail()) { SetIsDone(true); @@ -4616,7 +4609,7 @@ public: if (select_helper.FDIsSetRead(pipe_read_fd)) { size_t bytes_read; // Consume the interrupt byte - Error error = m_pipe.Read(&ch, 1, bytes_read); + Status error = m_pipe.Read(&ch, 1, bytes_read); if (error.Success()) { switch (ch) { case 'q': @@ -4667,7 +4660,7 @@ public: if (m_active) { char ch = 'i'; // Send 'i' for interrupt size_t bytes_written = 0; - Error result = m_pipe.Write(&ch, 1, bytes_written); + Status result = m_pipe.Write(&ch, 1, bytes_written); return result.Success(); } else { // This IOHandler might be pushed on the stack, but not being run @@ -4830,6 +4823,48 @@ GetExpressionTimeout(const EvaluateExpressionOptions &options, return *options.GetTimeout() - GetOneThreadExpressionTimeout(options); } +static llvm::Optional<ExpressionResults> +HandleStoppedEvent(Thread &thread, const ThreadPlanSP &thread_plan_sp, + RestorePlanState &restorer, const EventSP &event_sp, + EventSP &event_to_broadcast_sp, + const EvaluateExpressionOptions &options, bool handle_interrupts) { + Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_STEP | LIBLLDB_LOG_PROCESS); + + ThreadPlanSP plan = thread.GetCompletedPlan(); + if (plan == thread_plan_sp && plan->PlanSucceeded()) { + LLDB_LOG(log, "execution completed successfully"); + + // Restore the plan state so it will get reported as intended when we are + // done. + restorer.Clean(); + return eExpressionCompleted; + } + + StopInfoSP stop_info_sp = thread.GetStopInfo(); + if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint && + stop_info_sp->ShouldNotify(event_sp.get())) { + LLDB_LOG(log, "stopped for breakpoint: {0}.", stop_info_sp->GetDescription()); + if (!options.DoesIgnoreBreakpoints()) { + // Restore the plan state and then force Private to false. We are going + // to stop because of this plan so we need it to become a public plan or + // it won't report correctly when we continue to its termination later on. + restorer.Clean(); + thread_plan_sp->SetPrivate(false); + event_to_broadcast_sp = event_sp; + } + return eExpressionHitBreakpoint; + } + + if (!handle_interrupts && + Process::ProcessEventData::GetInterruptedFromEvent(event_sp.get())) + return llvm::None; + + LLDB_LOG(log, "thread plan did not successfully complete"); + if (!options.DoesUnwindOnError()) + event_to_broadcast_sp = event_sp; + return eExpressionInterrupted; +} + ExpressionResults Process::RunThreadPlan(ExecutionContext &exe_ctx, lldb::ThreadPlanSP &thread_plan_sp, @@ -5092,7 +5127,7 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx, if (do_resume) { num_resumes++; - Error resume_error = PrivateResume(); + Status resume_error = PrivateResume(); if (!resume_error.Success()) { diagnostic_manager.Printf( eDiagnosticSeverityError, @@ -5235,69 +5270,22 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx, "but our thread (index-id=%u) has vanished.", thread_idx_id); return_value = eExpressionInterrupted; - } else { + } else if (Process::ProcessEventData::GetRestartedFromEvent( + event_sp.get())) { // If we were restarted, we just need to go back up to fetch // another event. - if (Process::ProcessEventData::GetRestartedFromEvent( - event_sp.get())) { - if (log) { - log->Printf("Process::RunThreadPlan(): Got a stop and " - "restart, so we'll continue waiting."); - } - keep_going = true; - do_resume = false; - handle_running_event = true; - } else { - StopInfoSP stop_info_sp(thread_sp->GetStopInfo()); - StopReason stop_reason = eStopReasonInvalid; - if (stop_info_sp) - stop_reason = stop_info_sp->GetStopReason(); - - // FIXME: We only check if the stop reason is plan complete, - // should we make sure that - // it is OUR plan that is complete? - if (stop_reason == eStopReasonPlanComplete) { - if (log) - log->PutCString("Process::RunThreadPlan(): execution " - "completed successfully."); - - // Restore the plan state so it will get reported as - // intended when we are done. - thread_plan_restorer.Clean(); - - return_value = eExpressionCompleted; - } else { - // Something restarted the target, so just wait for it to - // stop for real. - if (stop_reason == eStopReasonBreakpoint) { - if (log) - log->Printf("Process::RunThreadPlan() stopped for " - "breakpoint: %s.", - stop_info_sp->GetDescription()); - return_value = eExpressionHitBreakpoint; - if (!options.DoesIgnoreBreakpoints()) { - // Restore the plan state and then force Private to - // false. We are - // going to stop because of this plan so we need it to - // become a public - // plan or it won't report correctly when we continue to - // its termination - // later on. - thread_plan_restorer.Clean(); - if (thread_plan_sp) - thread_plan_sp->SetPrivate(false); - event_to_broadcast_sp = event_sp; - } - } else { - if (log) - log->PutCString("Process::RunThreadPlan(): thread plan " - "didn't successfully complete."); - if (!options.DoesUnwindOnError()) - event_to_broadcast_sp = event_sp; - return_value = eExpressionInterrupted; - } - } + if (log) { + log->Printf("Process::RunThreadPlan(): Got a stop and " + "restart, so we'll continue waiting."); } + keep_going = true; + do_resume = false; + handle_running_event = true; + } else { + const bool handle_interrupts = true; + return_value = *HandleStoppedEvent( + *thread, thread_plan_sp, thread_plan_restorer, event_sp, + event_to_broadcast_sp, options, handle_interrupts); } } break; @@ -5348,19 +5336,16 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx, if (log) { if (options.GetTryAllThreads()) { if (before_first_timeout) { - log->Printf("Process::RunThreadPlan(): Running function with " - "one thread timeout timed out."); + LLDB_LOG(log, + "Running function with one thread timeout timed out."); } else - log->Printf("Process::RunThreadPlan(): Restarting function with " - "all threads enabled " - "and timeout: %" PRIu64 - " timed out, abandoning execution.", - timeout ? timeout->count() : -1); + LLDB_LOG(log, "Restarting function with all threads enabled and " + "timeout: {0} timed out, abandoning execution.", + timeout); } else - log->Printf("Process::RunThreadPlan(): Running function with " - "timeout: %" PRIu64 " timed out, " - "abandoning execution.", - timeout ? timeout->count() : -1); + LLDB_LOG(log, "Running function with timeout: {0} timed out, " + "abandoning execution.", + timeout); } // It is possible that between the time we issued the Halt, and we get @@ -5378,7 +5363,7 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx, bool do_halt = true; const uint32_t num_retries = 5; while (try_halt_again < num_retries) { - Error halt_error; + Status halt_error; if (do_halt) { if (log) log->Printf("Process::RunThreadPlan(): Running Halt."); @@ -5406,20 +5391,6 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx, } if (stop_state == lldb::eStateStopped) { - // Between the time we initiated the Halt and the time we - // delivered it, the process could have - // already finished its job. Check that here: - - if (thread->IsThreadPlanDone(thread_plan_sp.get())) { - if (log) - log->PutCString("Process::RunThreadPlan(): Even though we " - "timed out, the call plan was done. " - "Exiting wait loop."); - return_value = eExpressionCompleted; - back_to_top = false; - break; - } - if (Process::ProcessEventData::GetRestartedFromEvent( event_sp.get())) { if (log) @@ -5433,6 +5404,18 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx, continue; } + // Between the time we initiated the Halt and the time we + // delivered it, the process could have + // already finished its job. Check that here: + const bool handle_interrupts = false; + if (auto result = HandleStoppedEvent( + *thread, thread_plan_sp, thread_plan_restorer, event_sp, + event_to_broadcast_sp, options, handle_interrupts)) { + return_value = *result; + back_to_top = false; + break; + } + if (!options.GetTryAllThreads()) { if (log) log->PutCString("Process::RunThreadPlan(): try_all_threads " @@ -5490,7 +5473,7 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx, // plan, shut it down now. if (backup_private_state_thread.IsJoinable()) { StopPrivateStateThread(); - Error error; + Status error; m_private_state_thread = backup_private_state_thread; if (stopper_base_plan_sp) { thread->DiscardThreadPlansUpToPlan(stopper_base_plan_sp); @@ -5879,7 +5862,7 @@ void Process::DidExec() { target.DidExec(); } -addr_t Process::ResolveIndirectFunction(const Address *address, Error &error) { +addr_t Process::ResolveIndirectFunction(const Address *address, Status &error) { if (address == nullptr) { error.SetErrorString("Invalid address argument"); return LLDB_INVALID_ADDRESS; @@ -6107,10 +6090,10 @@ Process::AdvanceAddressToNextBranchInstruction(Address default_stop_addr, return retval; } -Error Process::GetMemoryRegions( - std::vector<lldb::MemoryRegionInfoSP> ®ion_list) { +Status +Process::GetMemoryRegions(std::vector<lldb::MemoryRegionInfoSP> ®ion_list) { - Error error; + Status error; lldb::addr_t range_end = 0; @@ -6133,12 +6116,13 @@ Error Process::GetMemoryRegions( return error; } -Error Process::ConfigureStructuredData( - const ConstString &type_name, const StructuredData::ObjectSP &config_sp) { +Status +Process::ConfigureStructuredData(const ConstString &type_name, + const StructuredData::ObjectSP &config_sp) { // If you get this, the Process-derived class needs to implement a method // to enable an already-reported asynchronous structured data feature. // See ProcessGDBRemote for an example implementation over gdb-remote. - return Error("unimplemented"); + return Status("unimplemented"); } void Process::MapSupportedStructuredDataPlugins( @@ -6175,8 +6159,7 @@ void Process::MapSupportedStructuredDataPlugins( } const_type_names.insert(ConstString(type_name->GetValue())); - if (log) - log->Printf("- %s", type_name->GetValue().c_str()); + LLDB_LOG(log, "- {0}", type_name->GetValue()); return true; }); @@ -6245,3 +6228,9 @@ bool Process::RouteAsyncStructuredData( find_it->second->HandleArrivalOfStructuredData(*this, type_name, object_sp); return true; } + +Status Process::UpdateAutomaticSignalFiltering() { + // Default implementation does nothign. + // No automatic signal filtering to speak of. + return Status(); +} diff --git a/contrib/llvm/tools/lldb/source/Target/ProcessInfo.cpp b/contrib/llvm/tools/lldb/source/Target/ProcessInfo.cpp index 5c4b2f07..0d986bc 100644 --- a/contrib/llvm/tools/lldb/source/Target/ProcessInfo.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ProcessInfo.cpp @@ -15,8 +15,8 @@ // Other libraries and framework includes // Project includes -#include "lldb/Core/Stream.h" #include "lldb/Host/PosixApi.h" +#include "lldb/Utility/Stream.h" #include "llvm/ADT/SmallString.h" diff --git a/contrib/llvm/tools/lldb/source/Target/ProcessLaunchInfo.cpp b/contrib/llvm/tools/lldb/source/Target/ProcessLaunchInfo.cpp index 92d9371..3fa40dc 100644 --- a/contrib/llvm/tools/lldb/source/Target/ProcessLaunchInfo.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ProcessLaunchInfo.cpp @@ -14,15 +14,17 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/Debugger.h" -#include "lldb/Core/Log.h" #include "lldb/Host/Config.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/HostInfo.h" #include "lldb/Target/FileAction.h" #include "lldb/Target/ProcessLaunchInfo.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/StreamString.h" #include "llvm/Support/ConvertUTF.h" +#include "llvm/Support/FileSystem.h" #if !defined(_WIN32) #include <limits.h> @@ -328,7 +330,7 @@ void ProcessLaunchInfo::FinalizeFileActions(Target *target, } bool ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell( - Error &error, bool localhost, bool will_debug, + Status &error, bool localhost, bool will_debug, bool first_arg_is_full_shell_command, int32_t num_resumes) { error.Clear(); @@ -368,10 +370,8 @@ bool ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell( if (working_dir) { new_path += working_dir.GetPath(); } else { - char current_working_dir[PATH_MAX]; - const char *cwd = - getcwd(current_working_dir, sizeof(current_working_dir)); - if (cwd && cwd[0]) + llvm::SmallString<64> cwd; + if (! llvm::sys::fs::current_path(cwd)) new_path += cwd; } std::string curr_path; diff --git a/contrib/llvm/tools/lldb/source/Target/RegisterContext.cpp b/contrib/llvm/tools/lldb/source/Target/RegisterContext.cpp index 4cce4dd..66164c1 100644 --- a/contrib/llvm/tools/lldb/source/Target/RegisterContext.cpp +++ b/contrib/llvm/tools/lldb/source/Target/RegisterContext.cpp @@ -12,18 +12,18 @@ // Other libraries and framework includes // Project includes #include "lldb/Target/RegisterContext.h" -#include "lldb/Core/DataExtractor.h" #include "lldb/Core/Module.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/Scalar.h" #include "lldb/Core/Value.h" #include "lldb/Expression/DWARFExpression.h" -#include "lldb/Host/Endian.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" using namespace lldb; using namespace lldb_private; @@ -91,7 +91,7 @@ RegisterContext::UpdateDynamicRegisterSize(const lldb_private::ArchSpec &arch, DWARFExpression dwarf_expr(opcode_ctx, dwarf_data, nullptr, 0, dwarf_opcode_len); Value result; - Error error; + Status error; const lldb::offset_t offset = 0; if (dwarf_expr.Evaluate(&exe_ctx, nullptr, nullptr, this, opcode_ctx, dwarf_data, nullptr, offset, dwarf_opcode_len, @@ -299,11 +299,10 @@ bool RegisterContext::ClearHardwareWatchpoint(uint32_t hw_index) { bool RegisterContext::HardwareSingleStep(bool enable) { return false; } -Error RegisterContext::ReadRegisterValueFromMemory(const RegisterInfo *reg_info, - lldb::addr_t src_addr, - uint32_t src_len, - RegisterValue ®_value) { - Error error; +Status RegisterContext::ReadRegisterValueFromMemory( + const RegisterInfo *reg_info, lldb::addr_t src_addr, uint32_t src_len, + RegisterValue ®_value) { + Status error; if (reg_info == nullptr) { error.SetErrorString("invalid register info argument."); return error; @@ -318,7 +317,7 @@ Error RegisterContext::ReadRegisterValueFromMemory(const RegisterInfo *reg_info, // // Case 2: src_len > dst_len // - // Error! (The register should always be big enough to hold the data) + // Status! (The register should always be big enough to hold the data) // // Case 3: src_len < dst_len // @@ -371,12 +370,12 @@ Error RegisterContext::ReadRegisterValueFromMemory(const RegisterInfo *reg_info, return error; } -Error RegisterContext::WriteRegisterValueToMemory( +Status RegisterContext::WriteRegisterValueToMemory( const RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len, const RegisterValue ®_value) { uint8_t dst[RegisterValue::kMaxRegisterByteSize]; - Error error; + Status error; ProcessSP process_sp(m_thread.GetProcess()); if (process_sp) { diff --git a/contrib/llvm/tools/lldb/source/Target/RegisterNumber.cpp b/contrib/llvm/tools/lldb/source/Target/RegisterNumber.cpp new file mode 100644 index 0000000..d1bb8ad --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Target/RegisterNumber.cpp @@ -0,0 +1,119 @@ +//===--------------------- RegisterNumber.cpp -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/RegisterNumber.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/Thread.h" + +using namespace lldb_private; + +RegisterNumber::RegisterNumber(lldb_private::Thread &thread, + lldb::RegisterKind kind, uint32_t num) + : m_reg_ctx_sp(thread.GetRegisterContext()), m_regnum(num), m_kind(kind), + m_kind_regnum_map(), m_name("") { + if (m_reg_ctx_sp.get()) { + const lldb_private::RegisterInfo *reginfo = + m_reg_ctx_sp->GetRegisterInfoAtIndex( + GetAsKind(lldb::eRegisterKindLLDB)); + if (reginfo && reginfo->name) { + m_name = reginfo->name; + } + } +} + +RegisterNumber::RegisterNumber() + : m_reg_ctx_sp(), m_regnum(LLDB_INVALID_REGNUM), + m_kind(lldb::kNumRegisterKinds), m_kind_regnum_map(), m_name(nullptr) {} + +void RegisterNumber::init(lldb_private::Thread &thread, lldb::RegisterKind kind, + uint32_t num) { + m_reg_ctx_sp = thread.GetRegisterContext(); + m_regnum = num; + m_kind = kind; + if (m_reg_ctx_sp.get()) { + const lldb_private::RegisterInfo *reginfo = + m_reg_ctx_sp->GetRegisterInfoAtIndex( + GetAsKind(lldb::eRegisterKindLLDB)); + if (reginfo && reginfo->name) { + m_name = reginfo->name; + } + } +} + +const RegisterNumber &RegisterNumber::operator=(const RegisterNumber &rhs) { + m_reg_ctx_sp = rhs.m_reg_ctx_sp; + m_regnum = rhs.m_regnum; + m_kind = rhs.m_kind; + for (auto it : rhs.m_kind_regnum_map) + m_kind_regnum_map[it.first] = it.second; + m_name = rhs.m_name; + return *this; +} + +bool RegisterNumber::operator==(RegisterNumber &rhs) { + if (IsValid() != rhs.IsValid()) + return false; + + if (m_kind == rhs.m_kind) { + if (m_regnum == rhs.m_regnum) + return true; + else + return false; + } + + uint32_t rhs_regnum = rhs.GetAsKind(m_kind); + if (rhs_regnum != LLDB_INVALID_REGNUM) { + if (m_regnum == rhs_regnum) + return true; + else + return false; + } + uint32_t lhs_regnum = GetAsKind(rhs.m_kind); + { + if (lhs_regnum == rhs.m_regnum) + return true; + else + return false; + } + return false; +} + +bool RegisterNumber::operator!=(RegisterNumber &rhs) { return !(*this == rhs); } + +bool RegisterNumber::IsValid() const { + return m_reg_ctx_sp.get() && m_kind != lldb::kNumRegisterKinds && + m_regnum != LLDB_INVALID_REGNUM; +} + +uint32_t RegisterNumber::GetAsKind(lldb::RegisterKind kind) { + if (m_regnum == LLDB_INVALID_REGNUM) + return LLDB_INVALID_REGNUM; + + if (kind == m_kind) + return m_regnum; + + Collection::iterator iter = m_kind_regnum_map.find(kind); + if (iter != m_kind_regnum_map.end()) { + return iter->second; + } + uint32_t output_regnum = LLDB_INVALID_REGNUM; + if (m_reg_ctx_sp && + m_reg_ctx_sp->ConvertBetweenRegisterKinds(m_kind, m_regnum, kind, + output_regnum) && + output_regnum != LLDB_INVALID_REGNUM) { + m_kind_regnum_map[kind] = output_regnum; + } + return output_regnum; +} + +uint32_t RegisterNumber::GetRegisterNumber() const { return m_regnum; } + +lldb::RegisterKind RegisterNumber::GetRegisterKind() const { return m_kind; } + +const char *RegisterNumber::GetName() { return m_name; } diff --git a/contrib/llvm/tools/lldb/source/Target/SectionLoadHistory.cpp b/contrib/llvm/tools/lldb/source/Target/SectionLoadHistory.cpp index 49a7cef..740f48b 100644 --- a/contrib/llvm/tools/lldb/source/Target/SectionLoadHistory.cpp +++ b/contrib/llvm/tools/lldb/source/Target/SectionLoadHistory.cpp @@ -13,8 +13,8 @@ // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/Core/Stream.h" #include "lldb/Target/SectionLoadList.h" +#include "lldb/Utility/Stream.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Target/SectionLoadList.cpp b/contrib/llvm/tools/lldb/source/Target/SectionLoadList.cpp index a3599dd..31ccf17 100644 --- a/contrib/llvm/tools/lldb/source/Target/SectionLoadList.cpp +++ b/contrib/llvm/tools/lldb/source/Target/SectionLoadList.cpp @@ -13,13 +13,13 @@ // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/Section.h" -#include "lldb/Core/Stream.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Stream.h" using namespace lldb; using namespace lldb_private; @@ -67,21 +67,13 @@ SectionLoadList::GetSectionLoadAddress(const lldb::SectionSP §ion) const { bool SectionLoadList::SetSectionLoadAddress(const lldb::SectionSP §ion, addr_t load_addr, bool warn_multiple) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER | - LIBLLDB_LOG_VERBOSE)); - + Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); ModuleSP module_sp(section->GetModule()); if (module_sp) { - if (log) { - const FileSpec &module_file_spec(module_sp->GetFileSpec()); - log->Printf("SectionLoadList::%s (section = %p (%s.%s), load_addr = " - "0x%16.16" PRIx64 ") module = %p", - __FUNCTION__, static_cast<void *>(section.get()), - module_file_spec.GetPath().c_str(), - section->GetName().AsCString(), load_addr, - static_cast<void *>(module_sp.get())); - } + LLDB_LOGV(log, "(section = {0} ({1}.{2}), load_addr = {3:x}) module = {4}", + section.get(), module_sp->GetFileSpec(), section->GetName(), + load_addr, module_sp.get()); if (section->GetByteSize() == 0) return false; // No change @@ -147,10 +139,9 @@ size_t SectionLoadList::SetSectionUnloaded(const lldb::SectionSP §ion_sp) { size_t unload_count = 0; if (section_sp) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER | - LIBLLDB_LOG_VERBOSE)); + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); - if (log) { + if (log && log->GetVerbose()) { ModuleSP module_sp = section_sp->GetModule(); std::string module_name("<Unknown>"); if (module_sp) { @@ -183,10 +174,9 @@ size_t SectionLoadList::SetSectionUnloaded(const lldb::SectionSP §ion_sp) { bool SectionLoadList::SetSectionUnloaded(const lldb::SectionSP §ion_sp, addr_t load_addr) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER | - LIBLLDB_LOG_VERBOSE)); + Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); - if (log) { + if (log && log->GetVerbose()) { ModuleSP module_sp = section_sp->GetModule(); std::string module_name("<Unknown>"); if (module_sp) { @@ -217,8 +207,8 @@ bool SectionLoadList::SetSectionUnloaded(const lldb::SectionSP §ion_sp, return erased; } -bool SectionLoadList::ResolveLoadAddress(addr_t load_addr, - Address &so_addr) const { +bool SectionLoadList::ResolveLoadAddress(addr_t load_addr, Address &so_addr, + bool allow_section_end) const { // First find the top level section that this load address exists in std::lock_guard<std::recursive_mutex> guard(m_mutex); if (!m_addr_to_sect.empty()) { @@ -230,10 +220,11 @@ bool SectionLoadList::ResolveLoadAddress(addr_t load_addr, const addr_t pos_load_addr = pos->first; if (load_addr >= pos_load_addr) { addr_t offset = load_addr - pos_load_addr; - if (offset < pos->second->GetByteSize()) { + if (offset < pos->second->GetByteSize() + (allow_section_end ? 1 : 0)) { // We have found the top level section, now we need to find the // deepest child section. - return pos->second->ResolveContainedAddress(offset, so_addr); + return pos->second->ResolveContainedAddress(offset, so_addr, + allow_section_end); } } } else { @@ -243,10 +234,12 @@ bool SectionLoadList::ResolveLoadAddress(addr_t load_addr, m_addr_to_sect.rbegin(); if (load_addr >= rpos->first) { addr_t offset = load_addr - rpos->first; - if (offset < rpos->second->GetByteSize()) { + if (offset < + rpos->second->GetByteSize() + (allow_section_end ? 1 : 0)) { // We have found the top level section, now we need to find the // deepest child section. - return rpos->second->ResolveContainedAddress(offset, so_addr); + return rpos->second->ResolveContainedAddress(offset, so_addr, + allow_section_end); } } } diff --git a/contrib/llvm/tools/lldb/source/Target/StackFrame.cpp b/contrib/llvm/tools/lldb/source/Target/StackFrame.cpp index ec30fd6..30fceb1 100644 --- a/contrib/llvm/tools/lldb/source/Target/StackFrame.cpp +++ b/contrib/llvm/tools/lldb/source/Target/StackFrame.cpp @@ -17,6 +17,7 @@ #include "lldb/Core/FormatEntity.h" #include "lldb/Core/Mangled.h" #include "lldb/Core/Module.h" +#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectMemory.h" @@ -190,9 +191,10 @@ const Address &StackFrame::GetFrameCodeAddress() { if (thread_sp) { TargetSP target_sp(thread_sp->CalculateTarget()); if (target_sp) { + const bool allow_section_end = true; if (m_frame_code_addr.SetOpcodeLoadAddress( m_frame_code_addr.GetOffset(), target_sp.get(), - eAddressClassCode)) { + eAddressClassCode, allow_section_end)) { ModuleSP module_sp(m_frame_code_addr.GetModule()); if (module_sp) { m_sc.module_sp = module_sp; @@ -221,18 +223,20 @@ bool StackFrame::ChangePC(addr_t pc) { const char *StackFrame::Disassemble() { std::lock_guard<std::recursive_mutex> guard(m_mutex); - if (m_disassembly.Empty()) - return nullptr; - - ExecutionContext exe_ctx(shared_from_this()); - Target *target = exe_ctx.GetTargetPtr(); - if (target) { - const char *plugin_name = nullptr; - const char *flavor = nullptr; - Disassembler::Disassemble(target->GetDebugger(), target->GetArchitecture(), - plugin_name, flavor, exe_ctx, 0, false, 0, 0, - m_disassembly); + if (m_disassembly.Empty()) { + ExecutionContext exe_ctx(shared_from_this()); + Target *target = exe_ctx.GetTargetPtr(); + if (target) { + const char *plugin_name = nullptr; + const char *flavor = nullptr; + Disassembler::Disassemble(target->GetDebugger(), + target->GetArchitecture(), plugin_name, flavor, + exe_ctx, 0, false, 0, 0, m_disassembly); + } + if (m_disassembly.Empty()) + return nullptr; } + return m_disassembly.GetData(); } @@ -425,7 +429,7 @@ VariableList *StackFrame::GetVariableList(bool get_file_globals) { m_variable_list_sp.reset(new VariableList()); frame_block->AppendBlockVariables(can_create, get_child_variables, stop_if_child_block_is_inlined_function, - [this](Variable *v) { return true; }, + [](Variable *v) { return true; }, m_variable_list_sp.get()); } } @@ -485,7 +489,7 @@ StackFrame::GetInScopeVariableList(bool get_file_globals, ValueObjectSP StackFrame::GetValueForVariableExpressionPath( llvm::StringRef var_expr, DynamicValueType use_dynamic, uint32_t options, - VariableSP &var_sp, Error &error) { + VariableSP &var_sp, Status &error) { llvm::StringRef original_var_expr = var_expr; // We can't fetch variable information for a history stack frame. if (m_is_history_frame) @@ -604,8 +608,10 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( // Calculate the next separator index ahead of time ValueObjectSP child_valobj_sp; const char separator_type = var_expr[0]; + bool expr_is_ptr = false; switch (separator_type) { case '-': + expr_is_ptr = true; if (var_expr.size() >= 2 && var_expr[1] != '>') return ValueObjectSP(); @@ -622,11 +628,32 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( return ValueObjectSP(); } } + + // If we have a non pointer type with a sythetic value then lets check if + // we have an sythetic dereference specified. + if (!valobj_sp->IsPointerType() && valobj_sp->HasSyntheticValue()) { + Status deref_error; + if (valobj_sp->GetCompilerType().IsReferenceType()) { + valobj_sp = valobj_sp->GetSyntheticValue()->Dereference(deref_error); + if (error.Fail()) { + error.SetErrorStringWithFormatv( + "Failed to dereference reference type: %s", deref_error); + return ValueObjectSP(); + } + } + + valobj_sp = valobj_sp->Dereference(deref_error); + if (error.Fail()) { + error.SetErrorStringWithFormatv( + "Failed to dereference sythetic value: %s", deref_error); + return ValueObjectSP(); + } + expr_is_ptr = false; + } + var_expr = var_expr.drop_front(); // Remove the '-' LLVM_FALLTHROUGH; case '.': { - const bool expr_is_ptr = var_expr[0] == '>'; - var_expr = var_expr.drop_front(); // Remove the '.' or '>' separator_idx = var_expr.find_first_of(".-["); ConstString child_name(var_expr.substr(0, var_expr.find_first_of(".-["))); @@ -749,7 +776,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( // what we have is *ptr[low]. the most similar C++ syntax is to deref // ptr and extract bit low out of it. reading array item low would be // done by saying ptr[low], without a deref * sign - Error error; + Status error; ValueObjectSP temp(valobj_sp->Dereference(error)); if (error.Fail()) { valobj_sp->GetExpressionPath(var_expr_path_strm, false); @@ -768,7 +795,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( // (an operation that is equivalent to deref-ing arr) // and extract bit low out of it. reading array item low // would be done by saying arr[low], without a deref * sign - Error error; + Status error; ValueObjectSP temp(valobj_sp->GetChildAtIndex(0, true)); if (error.Fail()) { valobj_sp->GetExpressionPath(var_expr_path_strm, false); @@ -951,7 +978,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( // deref ptr and extract bits low thru high out of it. reading array // items low thru high would be done by saying ptr[low-high], without // a deref * sign - Error error; + Status error; ValueObjectSP temp(valobj_sp->Dereference(error)); if (error.Fail()) { valobj_sp->GetExpressionPath(var_expr_path_strm, false); @@ -968,7 +995,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( // arr[0] (an operation that is equivalent to deref-ing arr) and extract // bits low thru high out of it. reading array items low thru high would // be done by saying arr[low-high], without a deref * sign - Error error; + Status error; ValueObjectSP temp(valobj_sp->GetChildAtIndex(0, true)); if (error.Fail()) { valobj_sp->GetExpressionPath(var_expr_path_strm, false); @@ -1039,7 +1066,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( return valobj_sp; } -bool StackFrame::GetFrameBaseValue(Scalar &frame_base, Error *error_ptr) { +bool StackFrame::GetFrameBaseValue(Scalar &frame_base, Status *error_ptr) { std::lock_guard<std::recursive_mutex> guard(m_mutex); if (!m_cfa_is_valid) { m_frame_base_error.SetErrorString( @@ -1085,7 +1112,7 @@ bool StackFrame::GetFrameBaseValue(Scalar &frame_base, Error *error_ptr) { return m_frame_base_error.Success(); } -DWARFExpression *StackFrame::GetFrameBaseExpression(Error *error_ptr) { +DWARFExpression *StackFrame::GetFrameBaseExpression(Status *error_ptr) { if (!m_sc.function) { if (error_ptr) { error_ptr->SetErrorString("No function in symbol context."); @@ -1186,9 +1213,14 @@ lldb::LanguageType StackFrame::GuessLanguage() { LanguageType lang_type = GetLanguage(); if (lang_type == eLanguageTypeUnknown) { - Function *f = GetSymbolContext(eSymbolContextFunction).function; - if (f) { - lang_type = f->GetMangled().GuessLanguage(); + SymbolContext sc = GetSymbolContext(eSymbolContextFunction + | eSymbolContextSymbol); + if (sc.function) { + lang_type = sc.function->GetMangled().GuessLanguage(); + } + else if (sc.symbol) + { + lang_type = sc.symbol->GetMangled().GuessLanguage(); } } @@ -1289,7 +1321,7 @@ lldb::ValueObjectSP StackFrame::GuessValueForAddress(lldb::addr_t addr) { DisassemblerSP disassembler_sp = Disassembler::DisassembleRange( target_arch, plugin_name, flavor, exe_ctx, pc_range, prefer_file_cache); - if (!disassembler_sp->GetInstructionList().GetSize()) { + if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) { return ValueObjectSP(); } @@ -1395,7 +1427,7 @@ ValueObjectSP GetValueForDereferincingOffset(StackFrame &frame, return ValueObjectSP(); } - Error error; + Status error; ValueObjectSP pointee = base->Dereference(error); if (!pointee) { @@ -1712,7 +1744,7 @@ void StackFrame::CalculateExecutionContext(ExecutionContext &exe_ctx) { exe_ctx.SetContext(shared_from_this()); } -void StackFrame::DumpUsingSettingsFormat(Stream *strm, +void StackFrame::DumpUsingSettingsFormat(Stream *strm, bool show_unique, const char *frame_marker) { if (strm == nullptr) return; @@ -1726,8 +1758,13 @@ void StackFrame::DumpUsingSettingsFormat(Stream *strm, const FormatEntity::Entry *frame_format = nullptr; Target *target = exe_ctx.GetTargetPtr(); - if (target) - frame_format = target->GetDebugger().GetFrameFormat(); + if (target) { + if (show_unique) { + frame_format = target->GetDebugger().GetFrameFormatUnique(); + } else { + frame_format = target->GetDebugger().GetFrameFormat(); + } + } if (frame_format && FormatEntity::Format(*frame_format, s, &m_sc, &exe_ctx, nullptr, nullptr, false, false)) { strm->PutCString(s.GetString()); @@ -1809,11 +1846,10 @@ bool StackFrame::HasCachedData() const { } bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source, - const char *frame_marker) { - + bool show_unique, const char *frame_marker) { if (show_frame_info) { strm.Indent(); - DumpUsingSettingsFormat(&strm, frame_marker); + DumpUsingSettingsFormat(&strm, show_unique, frame_marker); } if (show_source) { diff --git a/contrib/llvm/tools/lldb/source/Target/StackFrameList.cpp b/contrib/llvm/tools/lldb/source/Target/StackFrameList.cpp index 146b2b0..be7fa80 100644 --- a/contrib/llvm/tools/lldb/source/Target/StackFrameList.cpp +++ b/contrib/llvm/tools/lldb/source/Target/StackFrameList.cpp @@ -14,7 +14,6 @@ #include "lldb/Target/StackFrameList.h" #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointLocation.h" -#include "lldb/Core/Log.h" #include "lldb/Core/SourceManager.h" #include "lldb/Core/StreamFile.h" #include "lldb/Symbol/Block.h" @@ -27,6 +26,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/Unwind.h" +#include "lldb/Utility/Log.h" //#define DEBUG_STACK_FRAMES 1 @@ -802,6 +802,7 @@ StackFrameList::GetStackFrameSPForStackFramePtr(StackFrame *stack_frame_ptr) { size_t StackFrameList::GetStatus(Stream &strm, uint32_t first_frame, uint32_t num_frames, bool show_frame_info, uint32_t num_frames_with_source, + bool show_unique, const char *selected_frame_marker) { size_t num_frames_displayed = 0; @@ -842,7 +843,7 @@ size_t StackFrameList::GetStatus(Stream &strm, uint32_t first_frame, if (!frame_sp->GetStatus(strm, show_frame_info, num_frames_with_source > (first_frame - frame_idx), - marker)) + show_unique, marker)) break; ++num_frames_displayed; } diff --git a/contrib/llvm/tools/lldb/source/Target/StackID.cpp b/contrib/llvm/tools/lldb/source/Target/StackID.cpp index 0d215ed..889cf89 100644 --- a/contrib/llvm/tools/lldb/source/Target/StackID.cpp +++ b/contrib/llvm/tools/lldb/source/Target/StackID.cpp @@ -12,10 +12,10 @@ // Other libraries and framework includes // Project includes #include "lldb/Target/StackID.h" -#include "lldb/Core/Stream.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Utility/Stream.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Target/StopInfo.cpp b/contrib/llvm/tools/lldb/source/Target/StopInfo.cpp index 23dea41..6af5ce1 100644 --- a/contrib/llvm/tools/lldb/source/Target/StopInfo.cpp +++ b/contrib/llvm/tools/lldb/source/Target/StopInfo.cpp @@ -18,8 +18,6 @@ #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/StreamString.h" #include "lldb/Core/ValueObject.h" #include "lldb/Expression/UserExpression.h" #include "lldb/Target/Process.h" @@ -28,6 +26,8 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/UnixSignals.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/StreamString.h" using namespace lldb; using namespace lldb_private; @@ -269,6 +269,7 @@ protected: if (!m_should_perform_action) return; m_should_perform_action = false; + bool internal_breakpoint = true; ThreadSP thread_sp(m_thread_wp.lock()); @@ -434,7 +435,7 @@ protected: // shouldn't stop that will win. if (bp_loc_sp->GetConditionText() != nullptr) { - Error condition_error; + Status condition_error; bool condition_says_stop = bp_loc_sp->ConditionSaysStop(exe_ctx, condition_error); @@ -495,6 +496,9 @@ protected: if (callback_says_stop) m_should_stop = true; + if (m_should_stop && !bp_loc_sp->GetBreakpoint().IsInternal()) + internal_breakpoint = false; + // If we are going to stop for this breakpoint, then remove the // breakpoint. if (callback_says_stop && bp_loc_sp && @@ -526,6 +530,20 @@ protected: "Process::%s could not find breakpoint site id: %" PRId64 "...", __FUNCTION__, m_value); } + + if ((m_should_stop == false || internal_breakpoint) + && thread_sp->CompletedPlanOverridesBreakpoint()) { + + // Override should_stop decision when we have + // completed step plan additionally to the breakpoint + m_should_stop = true; + + // Here we clean the preset stop info so the next + // GetStopInfo call will find the appropriate stop info, + // which should be the stop info related to the completed plan + thread_sp->ResetStopInfo(); + } + if (log) log->Printf("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop); @@ -778,7 +796,7 @@ protected: expr_options.SetUnwindOnError(true); expr_options.SetIgnoreBreakpoints(true); ValueObjectSP result_value_sp; - Error error; + Status error; result_code = UserExpression::Evaluate( exe_ctx, expr_options, wp_sp->GetConditionText(), llvm::StringRef(), result_value_sp, error); diff --git a/contrib/llvm/tools/lldb/source/Target/Target.cpp b/contrib/llvm/tools/lldb/source/Target/Target.cpp index 078fa6a..d97f651 100644 --- a/contrib/llvm/tools/lldb/source/Target/Target.cpp +++ b/contrib/llvm/tools/lldb/source/Target/Target.cpp @@ -24,20 +24,17 @@ #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Event.h" -#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/Section.h" #include "lldb/Core/SourceManager.h" #include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Core/Timer.h" #include "lldb/Core/ValueObject.h" #include "lldb/Expression/REPL.h" #include "lldb/Expression/UserExpression.h" -#include "lldb/Host/FileSpec.h" #include "lldb/Host/Host.h" +#include "lldb/Host/PosixApi.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionGroupWatchpoint.h" @@ -57,7 +54,11 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadSpec.h" +#include "lldb/Utility/FileSpec.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/Utility/Timer.h" using namespace lldb; using namespace lldb_private; @@ -182,7 +183,7 @@ const lldb::ProcessSP &Target::CreateProcess(ListenerSP listener_sp, const lldb::ProcessSP &Target::GetProcessSP() const { return m_process_sp; } -lldb::REPLSP Target::GetREPL(Error &err, lldb::LanguageType language, +lldb::REPLSP Target::GetREPL(Status &err, lldb::LanguageType language, const char *repl_options, bool can_create) { if (language == eLanguageTypeUnknown) { std::set<LanguageType> repl_languages; @@ -547,7 +548,7 @@ BreakpointSP Target::CreateFuncRegexBreakpoint( lldb::BreakpointSP Target::CreateExceptionBreakpoint(enum lldb::LanguageType language, bool catch_bp, bool throw_bp, bool internal, - Args *additional_args, Error *error) { + Args *additional_args, Status *error) { BreakpointSP exc_bkpt_sp = LanguageRuntime::CreateExceptionBreakpoint( *this, language, catch_bp, throw_bp, internal); if (exc_bkpt_sp && additional_args) { @@ -604,9 +605,9 @@ bool Target::ProcessIsValid() { return (m_process_sp && m_process_sp->IsAlive()); } -static bool CheckIfWatchpointsExhausted(Target *target, Error &error) { +static bool CheckIfWatchpointsExhausted(Target *target, Status &error) { uint32_t num_supported_hardware_watchpoints; - Error rc = target->GetProcessSP()->GetWatchpointSupportInfo( + Status rc = target->GetProcessSP()->GetWatchpointSupportInfo( num_supported_hardware_watchpoints); if (num_supported_hardware_watchpoints == 0) { error.SetErrorStringWithFormat( @@ -621,7 +622,7 @@ static bool CheckIfWatchpointsExhausted(Target *target, Error &error) { // the OptionGroupWatchpoint::WatchType enum type. WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size, const CompilerType *type, uint32_t kind, - Error &error) { + Status &error) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); if (log) log->Printf("Target::%s (addr = 0x%8.8" PRIx64 " size = %" PRIu64 @@ -797,10 +798,10 @@ bool Target::EnableBreakpointByID(break_id_t break_id) { return false; } -Error Target::SerializeBreakpointsToFile(const FileSpec &file, - const BreakpointIDList &bp_ids, - bool append) { - Error error; +Status Target::SerializeBreakpointsToFile(const FileSpec &file, + const BreakpointIDList &bp_ids, + bool append) { + Status error; if (!file) { error.SetErrorString("Invalid FileSpec."); @@ -891,19 +892,19 @@ Error Target::SerializeBreakpointsToFile(const FileSpec &file, return error; } -Error Target::CreateBreakpointsFromFile(const FileSpec &file, - BreakpointIDList &new_bps) { +Status Target::CreateBreakpointsFromFile(const FileSpec &file, + BreakpointIDList &new_bps) { std::vector<std::string> no_names; return CreateBreakpointsFromFile(file, no_names, new_bps); } -Error Target::CreateBreakpointsFromFile(const FileSpec &file, - std::vector<std::string> &names, - BreakpointIDList &new_bps) { +Status Target::CreateBreakpointsFromFile(const FileSpec &file, + std::vector<std::string> &names, + BreakpointIDList &new_bps) { std::unique_lock<std::recursive_mutex> lock; GetBreakpointList().GetListMutex(lock); - Error error; + Status error; StructuredData::ObjectSP input_data_sp = StructuredData::ParseJSONFromFile(file, error); if (!error.Success()) { @@ -979,7 +980,7 @@ bool Target::RemoveAllWatchpoints(bool end_to_end) { if (!wp_sp) return false; - Error rc = m_process_sp->DisableWatchpoint(wp_sp.get()); + Status rc = m_process_sp->DisableWatchpoint(wp_sp.get()); if (rc.Fail()) return false; } @@ -1011,7 +1012,7 @@ bool Target::DisableAllWatchpoints(bool end_to_end) { if (!wp_sp) return false; - Error rc = m_process_sp->DisableWatchpoint(wp_sp.get()); + Status rc = m_process_sp->DisableWatchpoint(wp_sp.get()); if (rc.Fail()) return false; } @@ -1041,7 +1042,7 @@ bool Target::EnableAllWatchpoints(bool end_to_end) { if (!wp_sp) return false; - Error rc = m_process_sp->EnableWatchpoint(wp_sp.get()); + Status rc = m_process_sp->EnableWatchpoint(wp_sp.get()); if (rc.Fail()) return false; } @@ -1114,7 +1115,7 @@ bool Target::DisableWatchpointByID(lldb::watch_id_t watch_id) { WatchpointSP wp_sp = m_watchpoint_list.FindByID(watch_id); if (wp_sp) { - Error rc = m_process_sp->DisableWatchpoint(wp_sp.get()); + Status rc = m_process_sp->DisableWatchpoint(wp_sp.get()); if (rc.Success()) return true; @@ -1134,7 +1135,7 @@ bool Target::EnableWatchpointByID(lldb::watch_id_t watch_id) { WatchpointSP wp_sp = m_watchpoint_list.FindByID(watch_id); if (wp_sp) { - Error rc = m_process_sp->EnableWatchpoint(wp_sp.get()); + Status rc = m_process_sp->EnableWatchpoint(wp_sp.get()); if (rc.Success()) return true; @@ -1198,7 +1199,7 @@ Module *Target::GetExecutableModulePointer() { static void LoadScriptingResourceForModule(const ModuleSP &module_sp, Target *target) { - Error error; + Status error; StreamString feedback_stream; if (module_sp && !module_sp->LoadScriptingResourceInTarget(target, error, @@ -1235,7 +1236,8 @@ void Target::SetExecutableModule(ModuleSP &executable_sp, ClearModules(false); if (executable_sp) { - Timer scoped_timer(LLVM_PRETTY_FUNCTION, + static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); + Timer scoped_timer(func_cat, "Target::SetExecutableModule (executable = '%s')", executable_sp->GetFileSpec().GetPath().c_str()); @@ -1335,9 +1337,9 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec) { arch_spec.GetArchitectureName(), arch_spec.GetTriple().getTriple().c_str()); ModuleSpec module_spec(executable_sp->GetFileSpec(), other); - Error error = ModuleList::GetSharedModule(module_spec, executable_sp, - &GetExecutableSearchPaths(), - nullptr, nullptr); + Status error = ModuleList::GetSharedModule(module_spec, executable_sp, + &GetExecutableSearchPaths(), + nullptr, nullptr); if (!error.Fail() && executable_sp) { SetExecutableModule(executable_sp, true); @@ -1474,7 +1476,7 @@ bool Target::ModuleIsExcludedForUnconstrainedSearches( } size_t Target::ReadMemoryFromFileCache(const Address &addr, void *dst, - size_t dst_len, Error &error) { + size_t dst_len, Status &error) { SectionSP section_sp(addr.GetSection()); if (section_sp) { // If the contents of this section are encrypted, the on-disk file is @@ -1506,7 +1508,7 @@ size_t Target::ReadMemoryFromFileCache(const Address &addr, void *dst, } size_t Target::ReadMemory(const Address &addr, bool prefer_file_cache, - void *dst, size_t dst_len, Error &error, + void *dst, size_t dst_len, Status &error, lldb::addr_t *load_addr_ptr) { error.Clear(); @@ -1598,7 +1600,7 @@ size_t Target::ReadMemory(const Address &addr, bool prefer_file_cache, } size_t Target::ReadCStringFromMemory(const Address &addr, std::string &out_str, - Error &error) { + Status &error) { char buf[256]; out_str.clear(); addr_t curr_addr = addr.GetLoadAddress(this); @@ -1620,13 +1622,13 @@ size_t Target::ReadCStringFromMemory(const Address &addr, std::string &out_str, } size_t Target::ReadCStringFromMemory(const Address &addr, char *dst, - size_t dst_max_len, Error &result_error) { + size_t dst_max_len, Status &result_error) { size_t total_cstr_len = 0; if (dst && dst_max_len) { result_error.Clear(); // NULL out everything just to be safe memset(dst, 0, dst_max_len); - Error error; + Status error; addr_t curr_addr = addr.GetLoadAddress(this); Address address(addr); @@ -1675,7 +1677,7 @@ size_t Target::ReadCStringFromMemory(const Address &addr, char *dst, size_t Target::ReadScalarIntegerFromMemory(const Address &addr, bool prefer_file_cache, uint32_t byte_size, bool is_signed, - Scalar &scalar, Error &error) { + Scalar &scalar, Status &error) { uint64_t uval; if (byte_size <= sizeof(uval)) { @@ -1705,7 +1707,7 @@ uint64_t Target::ReadUnsignedIntegerFromMemory(const Address &addr, bool prefer_file_cache, size_t integer_byte_size, uint64_t fail_value, - Error &error) { + Status &error) { Scalar scalar; if (ReadScalarIntegerFromMemory(addr, prefer_file_cache, integer_byte_size, false, scalar, error)) @@ -1714,7 +1716,7 @@ uint64_t Target::ReadUnsignedIntegerFromMemory(const Address &addr, } bool Target::ReadPointerFromMemory(const Address &addr, bool prefer_file_cache, - Error &error, Address &pointer_addr) { + Status &error, Address &pointer_addr) { Scalar scalar; if (ReadScalarIntegerFromMemory(addr, prefer_file_cache, m_arch.GetAddressByteSize(), false, scalar, @@ -1744,10 +1746,10 @@ bool Target::ReadPointerFromMemory(const Address &addr, bool prefer_file_cache, } ModuleSP Target::GetSharedModule(const ModuleSpec &module_spec, - Error *error_ptr) { + Status *error_ptr) { ModuleSP module_sp; - Error error; + Status error; // First see if we already have this module in our module list. If we do, // then we're done, we don't need @@ -1870,6 +1872,11 @@ ModuleSP Target::GetSharedModule(const ModuleSpec &module_spec, } } + // Preload symbols outside of any lock, so hopefully we can do this for + // each library in parallel. + if (GetPreloadSymbols()) + module_sp->PreloadSymbols(); + if (old_module_sp && m_images.GetIndexForModule(old_module_sp.get()) != LLDB_INVALID_INDEX32) { @@ -1913,7 +1920,7 @@ void Target::ImageSearchPathsChanged(const PathMappingList &path_list, target->SetExecutableModule(exe_module_sp, true); } -TypeSystem *Target::GetScratchTypeSystemForLanguage(Error *error, +TypeSystem *Target::GetScratchTypeSystemForLanguage(Status *error, lldb::LanguageType language, bool create_on_demand) { if (!m_valid) @@ -1963,8 +1970,8 @@ Target::GetPersistentExpressionStateForLanguage(lldb::LanguageType language) { UserExpression *Target::GetUserExpressionForLanguage( llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language, Expression::ResultType desired_type, - const EvaluateExpressionOptions &options, Error &error) { - Error type_system_error; + const EvaluateExpressionOptions &options, Status &error) { + Status type_system_error; TypeSystem *type_system = GetScratchTypeSystemForLanguage(&type_system_error, language); @@ -1991,8 +1998,8 @@ UserExpression *Target::GetUserExpressionForLanguage( FunctionCaller *Target::GetFunctionCallerForLanguage( lldb::LanguageType language, const CompilerType &return_type, const Address &function_address, const ValueList &arg_value_list, - const char *name, Error &error) { - Error type_system_error; + const char *name, Status &error) { + Status type_system_error; TypeSystem *type_system = GetScratchTypeSystemForLanguage(&type_system_error, language); FunctionCaller *persistent_fn = nullptr; @@ -2018,8 +2025,8 @@ FunctionCaller *Target::GetFunctionCallerForLanguage( UtilityFunction * Target::GetUtilityFunctionForLanguage(const char *text, lldb::LanguageType language, - const char *name, Error &error) { - Error type_system_error; + const char *name, Status &error) { + Status type_system_error; TypeSystem *type_system = GetScratchTypeSystemForLanguage(&type_system_error, language); UtilityFunction *utility_fn = nullptr; @@ -2157,7 +2164,7 @@ ExpressionResults Target::EvaluateExpression( execution_results = eExpressionCompleted; } else { const char *prefix = GetExpressionPrefixContentsAsCString(); - Error error; + Status error; execution_results = UserExpression::Evaluate(exe_ctx, options, expr, prefix, result_valobj_sp, error, 0, // Line Number @@ -2173,7 +2180,7 @@ lldb::ExpressionVariableSP Target::GetPersistentVariable(const ConstString &name) { lldb::ExpressionVariableSP variable_sp; m_scratch_type_system_map.ForEach( - [this, name, &variable_sp](TypeSystem *type_system) -> bool { + [name, &variable_sp](TypeSystem *type_system) -> bool { if (PersistentExpressionState *persistent_state = type_system->GetPersistentExpressionState()) { variable_sp = persistent_state->GetVariable(name); @@ -2190,7 +2197,7 @@ lldb::addr_t Target::GetPersistentSymbol(const ConstString &name) { lldb::addr_t address = LLDB_INVALID_ADDRESS; m_scratch_type_system_map.ForEach( - [this, name, &address](TypeSystem *type_system) -> bool { + [name, &address](TypeSystem *type_system) -> bool { if (PersistentExpressionState *persistent_state = type_system->GetPersistentExpressionState()) { address = persistent_state->LookupSymbol(name); @@ -2648,8 +2655,8 @@ const TargetPropertiesSP &Target::GetGlobalProperties() { return *g_settings_sp_ptr; } -Error Target::Install(ProcessLaunchInfo *launch_info) { - Error error; +Status Target::Install(ProcessLaunchInfo *launch_info) { + Status error; PlatformSP platform_sp(GetPlatform()); if (platform_sp) { if (platform_sp->IsRemote()) { @@ -2779,8 +2786,8 @@ bool Target::SetSectionUnloaded(const lldb::SectionSP §ion_sp, void Target::ClearAllLoadedSections() { m_section_load_history.Clear(); } -Error Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { - Error error; +Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { + Status error; Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET)); if (log) @@ -2928,7 +2935,7 @@ Error Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { error = m_process_sp->PrivateResume(); } if (!error.Success()) { - Error error2; + Status error2; error2.SetErrorStringWithFormat( "process resume at entry point failed: %s", error.AsCString()); error = error2; @@ -2966,7 +2973,7 @@ Error Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { } m_process_sp->RestoreProcessEvents(); } else { - Error error2; + Status error2; error2.SetErrorStringWithFormat("process launch failed: %s", error.AsCString()); error = error2; @@ -2974,15 +2981,15 @@ Error Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { return error; } -Error Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) { +Status Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) { auto state = eStateInvalid; auto process_sp = GetProcessSP(); if (process_sp) { state = process_sp->GetState(); if (process_sp->IsAlive() && state != eStateConnected) { if (state == eStateAttaching) - return Error("process attach is in progress"); - return Error("a process is already being debugged"); + return Status("process attach is in progress"); + return Status("a process is already being debugged"); } } @@ -2996,8 +3003,8 @@ Error Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) { old_exec_module_sp->GetPlatformFileSpec().GetFilename(); if (!attach_info.ProcessInfoSpecified()) { - return Error("no process specified, create a target with a file, or " - "specify the --pid or --name"); + return Status("no process specified, create a target with a file, or " + "specify the --pid or --name"); } } @@ -3011,7 +3018,7 @@ Error Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) { attach_info.SetHijackListener(hijack_listener_sp); } - Error error; + Status error; if (state != eStateConnected && platform_sp != nullptr && platform_sp->CanDebugProcess()) { SetPlatform(platform_sp); @@ -3277,6 +3284,8 @@ static PropertyDefinition g_properties[] = { {"detach-on-error", OptionValue::eTypeBoolean, false, true, nullptr, nullptr, "debugserver will detach (rather than killing) a process if it " "loses connection with lldb."}, + {"preload-symbols", OptionValue::eTypeBoolean, false, true, nullptr, nullptr, + "Enable loading of symbol tables before they are needed."}, {"disable-aslr", OptionValue::eTypeBoolean, false, true, nullptr, nullptr, "Disable Address Space Layout Randomization (ASLR)"}, {"disable-stdio", OptionValue::eTypeBoolean, false, false, nullptr, nullptr, @@ -3379,6 +3388,7 @@ enum { ePropertyOutputPath, ePropertyErrorPath, ePropertyDetachOnError, + ePropertyPreloadSymbols, ePropertyDisableASLR, ePropertyDisableSTDIO, ePropertyInlineStrategy, @@ -3641,6 +3651,17 @@ bool TargetProperties::SetPreferDynamicValue(lldb::DynamicValueType d) { return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx, d); } +bool TargetProperties::GetPreloadSymbols() const { + const uint32_t idx = ePropertyPreloadSymbols; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_properties[idx].default_uint_value != 0); +} + +void TargetProperties::SetPreloadSymbols(bool b) { + const uint32_t idx = ePropertyPreloadSymbols; + m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); +} + bool TargetProperties::GetDisableASLR() const { const uint32_t idx = ePropertyDisableASLR; return m_collection_sp->GetPropertyAtIndexAsBoolean( diff --git a/contrib/llvm/tools/lldb/source/Target/TargetList.cpp b/contrib/llvm/tools/lldb/source/Target/TargetList.cpp index 0637cff..5c652ac 100644 --- a/contrib/llvm/tools/lldb/source/Target/TargetList.cpp +++ b/contrib/llvm/tools/lldb/source/Target/TargetList.cpp @@ -7,19 +7,14 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "llvm/ADT/SmallString.h" - // Project includes +#include "lldb/Target/TargetList.h" #include "lldb/Core/Broadcaster.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Event.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/State.h" -#include "lldb/Core/Timer.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -27,7 +22,12 @@ #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" -#include "lldb/Target/TargetList.h" +#include "lldb/Utility/TildeExpressionResolver.h" +#include "lldb/Utility/Timer.h" + +// Other libraries and framework includes +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/FileSystem.h" using namespace lldb; using namespace lldb_private; @@ -55,33 +55,33 @@ TargetList::~TargetList() { m_target_list.clear(); } -Error TargetList::CreateTarget(Debugger &debugger, - llvm::StringRef user_exe_path, - llvm::StringRef triple_str, - bool get_dependent_files, - const OptionGroupPlatform *platform_options, - TargetSP &target_sp) { +Status TargetList::CreateTarget(Debugger &debugger, + llvm::StringRef user_exe_path, + llvm::StringRef triple_str, + bool get_dependent_files, + const OptionGroupPlatform *platform_options, + TargetSP &target_sp) { return CreateTargetInternal(debugger, user_exe_path, triple_str, get_dependent_files, platform_options, target_sp, false); } -Error TargetList::CreateTarget(Debugger &debugger, - llvm::StringRef user_exe_path, - const ArchSpec &specified_arch, - bool get_dependent_files, - PlatformSP &platform_sp, TargetSP &target_sp) { +Status TargetList::CreateTarget(Debugger &debugger, + llvm::StringRef user_exe_path, + const ArchSpec &specified_arch, + bool get_dependent_files, + PlatformSP &platform_sp, TargetSP &target_sp) { return CreateTargetInternal(debugger, user_exe_path, specified_arch, get_dependent_files, platform_sp, target_sp, false); } -Error TargetList::CreateTargetInternal( +Status TargetList::CreateTargetInternal( Debugger &debugger, llvm::StringRef user_exe_path, llvm::StringRef triple_str, bool get_dependent_files, const OptionGroupPlatform *platform_options, TargetSP &target_sp, bool is_dummy_target) { - Error error; + Status error; PlatformSP platform_sp; // This is purposely left empty unless it is specified by triple_cstr. @@ -302,34 +302,34 @@ lldb::TargetSP TargetList::GetDummyTarget(lldb_private::Debugger &debugger) { ArchSpec arch(Target::GetDefaultArchitecture()); if (!arch.IsValid()) arch = HostInfo::GetArchitecture(); - Error err = CreateDummyTarget( + Status err = CreateDummyTarget( debugger, arch.GetTriple().getTriple().c_str(), m_dummy_target_sp); } return m_dummy_target_sp; } -Error TargetList::CreateDummyTarget(Debugger &debugger, - llvm::StringRef specified_arch_name, - lldb::TargetSP &target_sp) { +Status TargetList::CreateDummyTarget(Debugger &debugger, + llvm::StringRef specified_arch_name, + lldb::TargetSP &target_sp) { PlatformSP host_platform_sp(Platform::GetHostPlatform()); return CreateTargetInternal( debugger, (const char *)nullptr, specified_arch_name, false, (const OptionGroupPlatform *)nullptr, target_sp, true); } -Error TargetList::CreateTargetInternal(Debugger &debugger, - llvm::StringRef user_exe_path, - const ArchSpec &specified_arch, - bool get_dependent_files, - lldb::PlatformSP &platform_sp, - lldb::TargetSP &target_sp, - bool is_dummy_target) { - Timer scoped_timer(LLVM_PRETTY_FUNCTION, - "TargetList::CreateTarget (file = '%s', arch = '%s')", - user_exe_path.str().c_str(), - specified_arch.GetArchitectureName()); - Error error; +Status TargetList::CreateTargetInternal(Debugger &debugger, + llvm::StringRef user_exe_path, + const ArchSpec &specified_arch, + bool get_dependent_files, + lldb::PlatformSP &platform_sp, + lldb::TargetSP &target_sp, + bool is_dummy_target) { + static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); + Timer scoped_timer( + func_cat, "TargetList::CreateTarget (file = '%s', arch = '%s')", + user_exe_path.str().c_str(), specified_arch.GetArchitectureName()); + Status error; ArchSpec arch(specified_arch); @@ -348,10 +348,10 @@ Error TargetList::CreateTargetInternal(Debugger &debugger, FileSpec file(user_exe_path, false); if (!file.Exists() && user_exe_path.startswith("~")) { // we want to expand the tilde but we don't want to resolve any symbolic - // links - // so we can't use the FileSpec constructor's resolve flag - llvm::SmallString<64> unglobbed_path(user_exe_path); - FileSpec::ResolveUsername(unglobbed_path); + // links so we can't use the FileSpec constructor's resolve flag + llvm::SmallString<64> unglobbed_path; + StandardTildeExpressionResolver Resolver; + Resolver.ResolveFullPath(user_exe_path, unglobbed_path); if (unglobbed_path.empty()) file = FileSpec(user_exe_path, false); @@ -363,18 +363,17 @@ Error TargetList::CreateTargetInternal(Debugger &debugger, char resolved_bundle_exe_path[PATH_MAX]; resolved_bundle_exe_path[0] = '\0'; if (file) { - if (file.GetFileType() == FileSpec::eFileTypeDirectory) + if (llvm::sys::fs::is_directory(file.GetPath())) user_exe_path_is_bundle = true; if (file.IsRelative() && !user_exe_path.empty()) { // Ignore paths that start with "./" and "../" if (!user_exe_path.startswith("./") && !user_exe_path.startswith("../")) { - char cwd[PATH_MAX]; - if (getcwd(cwd, sizeof(cwd))) { - std::string cwd_user_exe_path(cwd); - cwd_user_exe_path += '/'; - cwd_user_exe_path += user_exe_path; - FileSpec cwd_file(cwd_user_exe_path, false); + llvm::SmallString<64> cwd; + if (! llvm::sys::fs::current_path(cwd)) { + cwd += '/'; + cwd += user_exe_path; + FileSpec cwd_file(cwd, false); if (cwd_file.Exists()) file = cwd_file; } diff --git a/contrib/llvm/tools/lldb/source/Target/Thread.cpp b/contrib/llvm/tools/lldb/source/Target/Thread.cpp index 5ead590..505d140 100644 --- a/contrib/llvm/tools/lldb/source/Target/Thread.cpp +++ b/contrib/llvm/tools/lldb/source/Target/Thread.cpp @@ -17,12 +17,8 @@ #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/FormatEntity.h" -#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" -#include "lldb/Core/RegularExpression.h" #include "lldb/Core/State.h" -#include "lldb/Core/Stream.h" -#include "lldb/Core/StreamString.h" #include "lldb/Core/ValueObject.h" #include "lldb/Host/Host.h" #include "lldb/Interpreter/OptionValueFileSpecList.h" @@ -51,6 +47,11 @@ #include "lldb/Target/ThreadPlanStepUntil.h" #include "lldb/Target/ThreadSpec.h" #include "lldb/Target/Unwind.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/Stream.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/lldb-enumerations.h" using namespace lldb; using namespace lldb_private; @@ -380,24 +381,32 @@ lldb::StopInfoSP Thread::GetStopInfo() { if (m_destroy_called) return m_stop_info_sp; - ThreadPlanSP plan_sp(GetCompletedPlan()); + ThreadPlanSP completed_plan_sp(GetCompletedPlan()); ProcessSP process_sp(GetProcess()); const uint32_t stop_id = process_sp ? process_sp->GetStopID() : UINT32_MAX; - if (plan_sp && plan_sp->PlanSucceeded()) { - return StopInfo::CreateStopReasonWithPlan(plan_sp, GetReturnValueObject(), - GetExpressionVariable()); + + // Here we select the stop info according to priorirty: + // - m_stop_info_sp (if not trace) - preset value + // - completed plan stop info - new value with plan from completed plan stack + // - m_stop_info_sp (trace stop reason is OK now) + // - ask GetPrivateStopInfo to set stop info + + bool have_valid_stop_info = m_stop_info_sp && + m_stop_info_sp ->IsValid() && + m_stop_info_stop_id == stop_id; + bool have_valid_completed_plan = completed_plan_sp && completed_plan_sp->PlanSucceeded(); + bool plan_overrides_trace = + have_valid_stop_info && have_valid_completed_plan + && (m_stop_info_sp->GetStopReason() == eStopReasonTrace); + + if (have_valid_stop_info && !plan_overrides_trace) { + return m_stop_info_sp; + } else if (have_valid_completed_plan) { + return StopInfo::CreateStopReasonWithPlan( + completed_plan_sp, GetReturnValueObject(), GetExpressionVariable()); } else { - if ((m_stop_info_stop_id == stop_id) || // Stop info is valid, just return - // what we have (even if empty) - (m_stop_info_sp && - m_stop_info_sp - ->IsValid())) // Stop info is valid, just return what we have - { - return m_stop_info_sp; - } else { - GetPrivateStopInfo(); - return m_stop_info_sp; - } + GetPrivateStopInfo(); + return m_stop_info_sp; } } @@ -459,6 +468,12 @@ bool Thread::StopInfoIsUpToDate() const { // date... } +void Thread::ResetStopInfo() { + if (m_stop_info_sp) { + m_stop_info_sp.reset(); + } +} + void Thread::SetStopInfo(const lldb::StopInfoSP &stop_info_sp) { m_stop_info_sp = stop_info_sp; if (m_stop_info_sp) { @@ -526,6 +541,7 @@ bool Thread::CheckpointThreadState(ThreadStateCheckpoint &saved_state) { if (process_sp) saved_state.orig_stop_id = process_sp->GetStopID(); saved_state.current_inlined_depth = GetCurrentInlinedDepth(); + saved_state.m_completed_plan_stack = m_completed_plan_stack; return true; } @@ -559,6 +575,7 @@ bool Thread::RestoreThreadStateFromCheckpoint( SetStopInfo(saved_state.stop_info_sp); GetStackFrameList()->SetCurrentInlinedDepth( saved_state.current_inlined_depth); + m_completed_plan_stack = saved_state.m_completed_plan_stack; return true; } @@ -895,6 +912,9 @@ bool Thread::ShouldStop(Event *event_ptr) { if (should_stop) { ThreadPlan *plan_ptr = GetCurrentPlan(); + + // Discard the stale plans and all plans below them in the stack, + // plus move the completed plans to the completed plan stack while (!PlanIsBasePlan(plan_ptr)) { bool stale = plan_ptr->IsPlanStale(); ThreadPlan *examined_plan = plan_ptr; @@ -905,7 +925,15 @@ bool Thread::ShouldStop(Event *event_ptr) { log->Printf( "Plan %s being discarded in cleanup, it says it is already done.", examined_plan->GetName()); - DiscardThreadPlansUpToPlan(examined_plan); + while (GetCurrentPlan() != examined_plan) { + DiscardPlan(); + } + if (examined_plan->IsPlanComplete()) { + // plan is complete but does not explain the stop (example: step to a line + // with breakpoint), let us move the plan to completed_plan_stack anyway + PopPlan(); + } else + DiscardPlan(); } } } @@ -1133,6 +1161,10 @@ bool Thread::WasThreadPlanDiscarded(ThreadPlan *plan) { return false; } +bool Thread::CompletedPlanOverridesBreakpoint() { + return (!m_completed_plan_stack.empty()) ; +} + ThreadPlan *Thread::GetPreviousPlan(ThreadPlan *current_plan) { if (current_plan == nullptr) return nullptr; @@ -1304,8 +1336,8 @@ bool Thread::PlanIsBasePlan(ThreadPlan *plan_ptr) { return m_plan_stack[0].get() == plan_ptr; } -Error Thread::UnwindInnermostExpression() { - Error error; +Status Thread::UnwindInnermostExpression() { + Status error; int stack_size = m_plan_stack.size(); // If the input plan is nullptr, discard all plans. Otherwise make sure this @@ -1604,11 +1636,11 @@ lldb::StackFrameSP Thread::GetFrameWithConcreteFrameIndex(uint32_t unwind_idx) { return GetStackFrameList()->GetFrameWithConcreteFrameIndex(unwind_idx); } -Error Thread::ReturnFromFrameWithIndex(uint32_t frame_idx, - lldb::ValueObjectSP return_value_sp, - bool broadcast) { +Status Thread::ReturnFromFrameWithIndex(uint32_t frame_idx, + lldb::ValueObjectSP return_value_sp, + bool broadcast) { StackFrameSP frame_sp = GetStackFrameAtIndex(frame_idx); - Error return_error; + Status return_error; if (!frame_sp) { return_error.SetErrorStringWithFormat( @@ -1619,10 +1651,10 @@ Error Thread::ReturnFromFrameWithIndex(uint32_t frame_idx, return ReturnFromFrame(frame_sp, return_value_sp, broadcast); } -Error Thread::ReturnFromFrame(lldb::StackFrameSP frame_sp, - lldb::ValueObjectSP return_value_sp, - bool broadcast) { - Error return_error; +Status Thread::ReturnFromFrame(lldb::StackFrameSP frame_sp, + lldb::ValueObjectSP return_value_sp, + bool broadcast) { + Status return_error; if (!frame_sp) { return_error.SetErrorString("Can't return to a null frame."); @@ -1709,8 +1741,8 @@ static void DumpAddressList(Stream &s, const std::vector<Address> &list, } } -Error Thread::JumpToLine(const FileSpec &file, uint32_t line, - bool can_leave_function, std::string *warnings) { +Status Thread::JumpToLine(const FileSpec &file, uint32_t line, + bool can_leave_function, std::string *warnings) { ExecutionContext exe_ctx(GetStackFrameAtIndex(0)); Target *target = exe_ctx.GetTargetPtr(); TargetSP target_sp = exe_ctx.GetTargetSP(); @@ -1738,16 +1770,16 @@ Error Thread::JumpToLine(const FileSpec &file, uint32_t line, // Check if we got anything. if (candidates.empty()) { if (outside_function.empty()) { - return Error("Cannot locate an address for %s:%i.", - file.GetFilename().AsCString(), line); + return Status("Cannot locate an address for %s:%i.", + file.GetFilename().AsCString(), line); } else if (outside_function.size() == 1) { - return Error("%s:%i is outside the current function.", - file.GetFilename().AsCString(), line); + return Status("%s:%i is outside the current function.", + file.GetFilename().AsCString(), line); } else { StreamString sstr; DumpAddressList(sstr, outside_function, target); - return Error("%s:%i has multiple candidate locations:\n%s", - file.GetFilename().AsCString(), line, sstr.GetData()); + return Status("%s:%i has multiple candidate locations:\n%s", + file.GetFilename().AsCString(), line, sstr.GetData()); } } @@ -1763,9 +1795,9 @@ Error Thread::JumpToLine(const FileSpec &file, uint32_t line, } if (!reg_ctx->SetPC(dest)) - return Error("Cannot change PC to target address."); + return Status("Cannot change PC to target address."); - return Error(); + return Status(); } void Thread::DumpUsingSettingsFormat(Stream &strm, uint32_t frame_idx, @@ -1881,39 +1913,42 @@ const char *Thread::RunModeAsCString(lldb::RunMode mode) { size_t Thread::GetStatus(Stream &strm, uint32_t start_frame, uint32_t num_frames, uint32_t num_frames_with_source, - bool stop_format) { - ExecutionContext exe_ctx(shared_from_this()); - Target *target = exe_ctx.GetTargetPtr(); - Process *process = exe_ctx.GetProcessPtr(); - size_t num_frames_shown = 0; - strm.Indent(); - bool is_selected = false; - if (process) { - if (process->GetThreadList().GetSelectedThread().get() == this) - is_selected = true; - } - strm.Printf("%c ", is_selected ? '*' : ' '); - if (target && target->GetDebugger().GetUseExternalEditor()) { - StackFrameSP frame_sp = GetStackFrameAtIndex(start_frame); - if (frame_sp) { - SymbolContext frame_sc( - frame_sp->GetSymbolContext(eSymbolContextLineEntry)); - if (frame_sc.line_entry.line != 0 && frame_sc.line_entry.file) { - Host::OpenFileInExternalEditor(frame_sc.line_entry.file, - frame_sc.line_entry.line); + bool stop_format, bool only_stacks) { + + if (!only_stacks) { + ExecutionContext exe_ctx(shared_from_this()); + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + strm.Indent(); + bool is_selected = false; + if (process) { + if (process->GetThreadList().GetSelectedThread().get() == this) + is_selected = true; + } + strm.Printf("%c ", is_selected ? '*' : ' '); + if (target && target->GetDebugger().GetUseExternalEditor()) { + StackFrameSP frame_sp = GetStackFrameAtIndex(start_frame); + if (frame_sp) { + SymbolContext frame_sc( + frame_sp->GetSymbolContext(eSymbolContextLineEntry)); + if (frame_sc.line_entry.line != 0 && frame_sc.line_entry.file) { + Host::OpenFileInExternalEditor(frame_sc.line_entry.file, + frame_sc.line_entry.line); + } } } - } - DumpUsingSettingsFormat(strm, start_frame, stop_format); + DumpUsingSettingsFormat(strm, start_frame, stop_format); + } + size_t num_frames_shown = 0; if (num_frames > 0) { strm.IndentMore(); const bool show_frame_info = true; - + const bool show_frame_unique = only_stacks; const char *selected_frame_marker = nullptr; - if (num_frames == 1 || + if (num_frames == 1 || only_stacks || (GetID() != GetProcess()->GetThreadList().GetSelectedThread()->GetID())) strm.IndentMore(); else @@ -1921,7 +1956,7 @@ size_t Thread::GetStatus(Stream &strm, uint32_t start_frame, num_frames_shown = GetStackFrameList()->GetStatus( strm, start_frame, num_frames, show_frame_info, num_frames_with_source, - selected_frame_marker); + show_frame_unique, selected_frame_marker); if (num_frames == 1) strm.IndentLess(); strm.IndentLess(); @@ -1963,22 +1998,20 @@ bool Thread::GetDescription(Stream &strm, lldb::DescriptionLevel level, thread_info->GetObjectForDotSeparatedPath("trace_messages"); bool printed_activity = false; - if (activity && - activity->GetType() == StructuredData::Type::eTypeDictionary) { + if (activity && activity->GetType() == eStructuredDataTypeDictionary) { StructuredData::Dictionary *activity_dict = activity->GetAsDictionary(); StructuredData::ObjectSP id = activity_dict->GetValueForKey("id"); StructuredData::ObjectSP name = activity_dict->GetValueForKey("name"); - if (name && name->GetType() == StructuredData::Type::eTypeString && id && - id->GetType() == StructuredData::Type::eTypeInteger) { - strm.Printf(" Activity '%s', 0x%" PRIx64 "\n", - name->GetAsString()->GetValue().c_str(), + if (name && name->GetType() == eStructuredDataTypeString && id && + id->GetType() == eStructuredDataTypeInteger) { + strm.Format(" Activity '{0}', {1:x}\n", + name->GetAsString()->GetValue(), id->GetAsInteger()->GetValue()); } printed_activity = true; } bool printed_breadcrumb = false; - if (breadcrumb && - breadcrumb->GetType() == StructuredData::Type::eTypeDictionary) { + if (breadcrumb && breadcrumb->GetType() == eStructuredDataTypeDictionary) { if (printed_activity) strm.Printf("\n"); StructuredData::Dictionary *breadcrumb_dict = @@ -1986,13 +2019,13 @@ bool Thread::GetDescription(Stream &strm, lldb::DescriptionLevel level, StructuredData::ObjectSP breadcrumb_text = breadcrumb_dict->GetValueForKey("name"); if (breadcrumb_text && - breadcrumb_text->GetType() == StructuredData::Type::eTypeString) { - strm.Printf(" Current Breadcrumb: %s\n", - breadcrumb_text->GetAsString()->GetValue().c_str()); + breadcrumb_text->GetType() == eStructuredDataTypeString) { + strm.Format(" Current Breadcrumb: {0}\n", + breadcrumb_text->GetAsString()->GetValue()); } printed_breadcrumb = true; } - if (messages && messages->GetType() == StructuredData::Type::eTypeArray) { + if (messages && messages->GetType() == eStructuredDataTypeArray) { if (printed_breadcrumb) strm.Printf("\n"); StructuredData::Array *messages_array = messages->GetAsArray(); @@ -2001,16 +2034,14 @@ bool Thread::GetDescription(Stream &strm, lldb::DescriptionLevel level, strm.Printf(" %zu trace messages:\n", msg_count); for (size_t i = 0; i < msg_count; i++) { StructuredData::ObjectSP message = messages_array->GetItemAtIndex(i); - if (message && - message->GetType() == StructuredData::Type::eTypeDictionary) { + if (message && message->GetType() == eStructuredDataTypeDictionary) { StructuredData::Dictionary *message_dict = message->GetAsDictionary(); StructuredData::ObjectSP message_text = message_dict->GetValueForKey("message"); if (message_text && - message_text->GetType() == StructuredData::Type::eTypeString) { - strm.Printf(" %s\n", - message_text->GetAsString()->GetValue().c_str()); + message_text->GetType() == eStructuredDataTypeString) { + strm.Format(" {0}\n", message_text->GetAsString()->GetValue()); } } } @@ -2086,12 +2117,12 @@ bool Thread::IsStillAtLastBreakpointHit() { return false; } -Error Thread::StepIn(bool source_step, - LazyBool step_in_avoids_code_without_debug_info, - LazyBool step_out_avoids_code_without_debug_info) +Status Thread::StepIn(bool source_step, + LazyBool step_in_avoids_code_without_debug_info, + LazyBool step_out_avoids_code_without_debug_info) { - Error error; + Status error; Process *process = GetProcess().get(); if (StateIsStoppedState(process->GetState(), true)) { StackFrameSP frame_sp = GetStackFrameAtIndex(0); @@ -2122,9 +2153,9 @@ Error Thread::StepIn(bool source_step, return error; } -Error Thread::StepOver(bool source_step, - LazyBool step_out_avoids_code_without_debug_info) { - Error error; +Status Thread::StepOver(bool source_step, + LazyBool step_out_avoids_code_without_debug_info) { + Status error; Process *process = GetProcess().get(); if (StateIsStoppedState(process->GetState(), true)) { StackFrameSP frame_sp = GetStackFrameAtIndex(0); @@ -2155,8 +2186,8 @@ Error Thread::StepOver(bool source_step, return error; } -Error Thread::StepOut() { - Error error; +Status Thread::StepOut() { + Status error; Process *process = GetProcess().get(); if (StateIsStoppedState(process->GetState(), true)) { const bool first_instruction = false; diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadList.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadList.cpp index 1e47451..4cf8f90 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadList.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadList.cpp @@ -15,15 +15,14 @@ // Other libraries and framework includes // Project includes -#include "lldb/Core/Log.h" #include "lldb/Core/State.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadList.h" #include "lldb/Target/ThreadPlan.h" -#include "lldb/Utility/ConvertEnum.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/Log.h" using namespace lldb; using namespace lldb_private; @@ -384,18 +383,14 @@ Vote ThreadList::ShouldReportStop(Event *event_ptr) { if (result == eVoteNoOpinion) { result = eVoteNo; } else { - if (log) - log->Printf("ThreadList::%s thread 0x%4.4" PRIx64 - ": voted %s, but lost out because result was %s", - __FUNCTION__, thread_sp->GetID(), GetVoteAsCString(vote), - GetVoteAsCString(result)); + LLDB_LOG(log, + "Thread {0:x} voted {1}, but lost out because result was {2}", + thread_sp->GetID(), vote, result); } break; } } - if (log) - log->Printf("ThreadList::%s returning %s", __FUNCTION__, - GetVoteAsCString(result)); + LLDB_LOG(log, "Returning {0}", result); return result; } diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlan.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlan.cpp index 6b99747..27c9e2a 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlan.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlan.cpp @@ -13,13 +13,12 @@ // Project includes #include "lldb/Target/ThreadPlan.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/Log.h" #include "lldb/Core/State.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" -#include "lldb/Utility/ConvertEnum.h" +#include "lldb/Utility/Log.h" using namespace lldb; using namespace lldb_private; @@ -77,16 +76,11 @@ Vote ThreadPlan::ShouldReportStop(Event *event_ptr) { ThreadPlan *prev_plan = GetPreviousPlan(); if (prev_plan) { Vote prev_vote = prev_plan->ShouldReportStop(event_ptr); - if (log) - log->Printf("ThreadPlan::ShouldReportStop() returning previous thread " - "plan vote: %s", - GetVoteAsCString(prev_vote)); + LLDB_LOG(log, "returning previous thread plan vote: {0}", prev_vote); return prev_vote; } } - if (log) - log->Printf("ThreadPlan::ShouldReportStop() returning vote: %s", - GetVoteAsCString(m_stop_vote)); + LLDB_LOG(log, "Returning vote: {0}", m_stop_vote); return m_stop_vote; } diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanBase.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanBase.cpp index f290483..d1c2f6d 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanBase.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanBase.cpp @@ -18,11 +18,11 @@ #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/BreakpointSite.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/Stream.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StopInfo.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Stream.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallFunction.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallFunction.cpp index 68fd503..e3b9ae1 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallFunction.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallFunction.cpp @@ -15,9 +15,7 @@ #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Address.h" -#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" -#include "lldb/Core/Stream.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/ABI.h" #include "lldb/Target/LanguageRuntime.h" @@ -27,6 +25,8 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlanRunToAddress.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Stream.h" using namespace lldb; using namespace lldb_private; @@ -58,7 +58,7 @@ bool ThreadPlanCallFunction::ConstructorSetup( // If we can't read memory at the point of the process where we are planning // to put our function, we're // not going to get any further... - Error error; + Status error; process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error); if (!error.Success()) { m_constructor_errors.Printf( @@ -174,9 +174,8 @@ ThreadPlanCallFunction::~ThreadPlanCallFunction() { } void ThreadPlanCallFunction::ReportRegisterState(const char *message) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP | - LIBLLDB_LOG_VERBOSE)); - if (log) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + if (log && log->GetVerbose()) { StreamString strm; RegisterContext *reg_ctx = m_thread.GetRegisterContext().get(); diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallFunctionUsingABI.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallFunctionUsingABI.cpp index 6c59695..b90fd9e 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallFunctionUsingABI.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallFunctionUsingABI.cpp @@ -13,12 +13,12 @@ // Project includes #include "lldb/Target/ThreadPlanCallFunctionUsingABI.h" #include "lldb/Core/Address.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/Stream.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Stream.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallUserExpression.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallUserExpression.cpp index 260118c..15cbd0b 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallUserExpression.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallUserExpression.cpp @@ -17,8 +17,6 @@ #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Address.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/Stream.h" #include "lldb/Expression/DiagnosticManager.h" #include "lldb/Expression/IRDynamicChecks.h" #include "lldb/Expression/UserExpression.h" @@ -30,6 +28,8 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlanRunToAddress.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Stream.h" using namespace lldb; using namespace lldb_private; @@ -60,6 +60,12 @@ void ThreadPlanCallUserExpression::GetDescription( ThreadPlanCallFunction::GetDescription(s, level); } +void ThreadPlanCallUserExpression::DidPush() { + ThreadPlanCallFunction::DidPush(); + if (m_user_expression_sp) + m_user_expression_sp->WillStartExecuting(); +} + void ThreadPlanCallUserExpression::WillPop() { ThreadPlanCallFunction::WillPop(); if (m_user_expression_sp) @@ -113,3 +119,8 @@ StopInfoSP ThreadPlanCallUserExpression::GetRealStopInfo() { return stop_info_sp; } + +void ThreadPlanCallUserExpression::DoTakedown(bool success) { + ThreadPlanCallFunction::DoTakedown(success); + m_user_expression_sp->DidFinishExecuting(); +} diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanPython.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanPython.cpp index 180586a..af5c765 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanPython.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanPython.cpp @@ -14,7 +14,6 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/Debugger.h" -#include "lldb/Core/Log.h" #include "lldb/Core/State.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/ScriptInterpreter.h" @@ -24,6 +23,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/ThreadPlanPython.h" +#include "lldb/Utility/Log.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanRunToAddress.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanRunToAddress.cpp index 6f31db0..44de724 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanRunToAddress.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanRunToAddress.cpp @@ -12,12 +12,12 @@ // Other libraries and framework includes // Project includes #include "lldb/Target/ThreadPlanRunToAddress.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/Stream.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Stream.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanShouldStopHere.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanShouldStopHere.cpp index 408650d..42aaa42 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanShouldStopHere.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanShouldStopHere.cpp @@ -11,11 +11,11 @@ // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/Target/Thread.h" -#include "lldb/Core/Log.h" +#include "lldb/Target/ThreadPlanShouldStopHere.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/RegisterContext.h" -#include "lldb/Target/ThreadPlanShouldStopHere.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/Log.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInRange.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInRange.cpp index 03f6679..caaaffe 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInRange.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInRange.cpp @@ -12,10 +12,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Target/ThreadPlanStepInRange.h" -#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" -#include "lldb/Core/RegularExpression.h" -#include "lldb/Core/Stream.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/Process.h" @@ -24,6 +21,9 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlanStepOut.h" #include "lldb/Target/ThreadPlanStepThrough.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/Stream.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInstruction.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInstruction.cpp index 6ad6a23..ca45960 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInstruction.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInstruction.cpp @@ -12,13 +12,13 @@ // Other libraries and framework includes // Project includes #include "lldb/Target/ThreadPlanStepInstruction.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/Stream.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Stream.h" using namespace lldb; using namespace lldb_private; @@ -94,6 +94,15 @@ bool ThreadPlanStepInstruction::IsPlanStale() { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); StackID cur_frame_id = m_thread.GetStackFrameAtIndex(0)->GetStackID(); if (cur_frame_id == m_stack_id) { + // Set plan Complete when we reach next instruction + uint64_t pc = m_thread.GetRegisterContext()->GetPC(0); + uint32_t max_opcode_size = m_thread.CalculateTarget() + ->GetArchitecture().GetMaximumOpcodeByteSize(); + bool next_instruction_reached = (pc > m_instruction_addr) && + (pc <= m_instruction_addr + max_opcode_size); + if (next_instruction_reached) { + SetPlanComplete(); + } return (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr); } else if (cur_frame_id < m_stack_id) { // If the current frame is younger than the start frame and we are stepping diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOut.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOut.cpp index b8d6e6d..6b6ed06 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOut.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOut.cpp @@ -13,7 +13,6 @@ // Project includes #include "lldb/Target/ThreadPlanStepOut.h" #include "lldb/Breakpoint/Breakpoint.h" -#include "lldb/Core/Log.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Symbol/Block.h" @@ -27,6 +26,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/ThreadPlanStepOverRange.h" #include "lldb/Target/ThreadPlanStepThrough.h" +#include "lldb/Utility/Log.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp index 39641a0..3896a0b 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp @@ -13,10 +13,10 @@ // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/Core/Log.h" -#include "lldb/Core/Stream.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Stream.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOverRange.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOverRange.cpp index 48c7ff8..d5778fb 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOverRange.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOverRange.cpp @@ -12,8 +12,6 @@ // Other libraries and framework includes // Project includes #include "lldb/Target/ThreadPlanStepOverRange.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/Stream.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" @@ -24,6 +22,8 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlanStepOut.h" #include "lldb/Target/ThreadPlanStepThrough.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Stream.h" using namespace lldb_private; using namespace lldb; diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepRange.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepRange.cpp index dcee82e..09e606f 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepRange.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepRange.cpp @@ -15,8 +15,6 @@ #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/BreakpointSite.h" #include "lldb/Core/Disassembler.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/Stream.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/ExecutionContext.h" @@ -26,6 +24,8 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlanRunToAddress.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Stream.h" using namespace lldb; using namespace lldb_private; @@ -461,6 +461,16 @@ bool ThreadPlanStepRange::IsPlanStale() { // One tricky bit here is that some stubs don't push a frame, so we should. // check that we are in the same symbol. if (!InRange()) { + // Set plan Complete when we reach next instruction just after the range + lldb::addr_t addr = m_thread.GetRegisterContext()->GetPC() - 1; + size_t num_ranges = m_address_ranges.size(); + for (size_t i = 0; i < num_ranges; i++) { + bool in_range = m_address_ranges[i].ContainsLoadAddress( + addr, m_thread.CalculateTarget().get()); + if (in_range) { + SetPlanComplete(); + } + } return true; } } diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepThrough.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepThrough.cpp index b975161..46aadb0 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepThrough.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepThrough.cpp @@ -13,13 +13,13 @@ // Project includes #include "lldb/Target/ThreadPlanStepThrough.h" #include "lldb/Breakpoint/Breakpoint.h" -#include "lldb/Core/Log.h" -#include "lldb/Core/Stream.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Stream.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepUntil.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepUntil.cpp index a10e2f4..01f5f94 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepUntil.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepUntil.cpp @@ -12,12 +12,14 @@ // Other libraries and framework includes // Project includes #include "lldb/Target/ThreadPlanStepUntil.h" + #include "lldb/Breakpoint/Breakpoint.h" -#include "lldb/Core/Log.h" +#include "lldb/Symbol/SymbolContextScope.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/Log.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanTracer.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanTracer.cpp index 7fbd664..014c7fd 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanTracer.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanTracer.cpp @@ -14,11 +14,8 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/ArchSpec.h" -#include "lldb/Core/DataBufferHeap.h" -#include "lldb/Core/DataExtractor.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Disassembler.h" -#include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" @@ -32,6 +29,9 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Log.h" using namespace lldb; using namespace lldb_private; @@ -145,7 +145,7 @@ void ThreadPlanAssemblyTracer::Log() { Disassembler *disassembler = GetDisassembler(); if (disassembler) { - Error err; + Status err; process_sp->ReadMemory(pc, buffer, sizeof(buffer), err); if (err.Success()) { diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadSpec.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadSpec.cpp index c7eec07..444a5a5 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadSpec.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadSpec.cpp @@ -11,9 +11,9 @@ // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/Target/Thread.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Target/ThreadSpec.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/StructuredData.h" using namespace lldb; using namespace lldb_private; @@ -39,11 +39,11 @@ const ThreadSpec &ThreadSpec::operator=(const ThreadSpec &rhs) { } std::unique_ptr<ThreadSpec> ThreadSpec::CreateFromStructuredData( - const StructuredData::Dictionary &spec_dict, Error &error) { + const StructuredData::Dictionary &spec_dict, Status &error) { uint32_t index = UINT32_MAX; lldb::tid_t tid = LLDB_INVALID_THREAD_ID; - std::string name; - std::string queue_name; + llvm::StringRef name; + llvm::StringRef queue_name; std::unique_ptr<ThreadSpec> thread_spec_up(new ThreadSpec()); bool success = spec_dict.GetValueForKeyAsInteger( @@ -59,12 +59,12 @@ std::unique_ptr<ThreadSpec> ThreadSpec::CreateFromStructuredData( success = spec_dict.GetValueForKeyAsString(GetKey(OptionNames::ThreadName), name); if (success) - thread_spec_up->SetName(name.c_str()); + thread_spec_up->SetName(name); success = spec_dict.GetValueForKeyAsString(GetKey(OptionNames::ThreadName), queue_name); if (success) - thread_spec_up->SetQueueName(queue_name.c_str()); + thread_spec_up->SetQueueName(queue_name); return thread_spec_up; } diff --git a/contrib/llvm/tools/lldb/source/Target/UnixSignals.cpp b/contrib/llvm/tools/lldb/source/Target/UnixSignals.cpp index cee69bf..a4ec32b 100644 --- a/contrib/llvm/tools/lldb/source/Target/UnixSignals.cpp +++ b/contrib/llvm/tools/lldb/source/Target/UnixSignals.cpp @@ -123,12 +123,14 @@ void UnixSignals::AddSignal(int signo, const char *name, bool default_suppress, Signal new_signal(name, default_suppress, default_stop, default_notify, description, alias); m_signals.insert(std::make_pair(signo, new_signal)); + ++m_version; } void UnixSignals::RemoveSignal(int signo) { collection::iterator pos = m_signals.find(signo); if (pos != m_signals.end()) m_signals.erase(pos); + ++m_version; } const char *UnixSignals::GetSignalAsCString(int signo) const { @@ -217,6 +219,7 @@ bool UnixSignals::SetShouldSuppress(int signo, bool value) { collection::iterator pos = m_signals.find(signo); if (pos != m_signals.end()) { pos->second.m_suppress = value; + ++m_version; return true; } return false; @@ -240,6 +243,7 @@ bool UnixSignals::SetShouldStop(int signo, bool value) { collection::iterator pos = m_signals.find(signo); if (pos != m_signals.end()) { pos->second.m_stop = value; + ++m_version; return true; } return false; @@ -263,6 +267,7 @@ bool UnixSignals::SetShouldNotify(int signo, bool value) { collection::iterator pos = m_signals.find(signo); if (pos != m_signals.end()) { pos->second.m_notify = value; + ++m_version; return true; } return false; @@ -284,3 +289,37 @@ int32_t UnixSignals::GetSignalAtIndex(int32_t index) const { std::advance(it, index); return it->first; } + +uint64_t UnixSignals::GetVersion() const { return m_version; } + +std::vector<int32_t> +UnixSignals::GetFilteredSignals(llvm::Optional<bool> should_suppress, + llvm::Optional<bool> should_stop, + llvm::Optional<bool> should_notify) { + std::vector<int32_t> result; + for (int32_t signo = GetFirstSignalNumber(); + signo != LLDB_INVALID_SIGNAL_NUMBER; + signo = GetNextSignalNumber(signo)) { + + bool signal_suppress = false; + bool signal_stop = false; + bool signal_notify = false; + GetSignalInfo(signo, signal_suppress, signal_stop, signal_notify); + + // If any of filtering conditions are not met, + // we move on to the next signal. + if (should_suppress.hasValue() && + signal_suppress != should_suppress.getValue()) + continue; + + if (should_stop.hasValue() && signal_stop != should_stop.getValue()) + continue; + + if (should_notify.hasValue() && signal_notify != should_notify.getValue()) + continue; + + result.push_back(signo); + } + + return result; +} |