diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:04:10 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:04:10 +0000 |
commit | 74a628f776edb588bff8f8f5cc16eac947c9d631 (patch) | |
tree | dc32e010ac4902621e5a279bfeb48628f7f0e166 /source/Target | |
parent | afed7be32164a598f8172282c249af7266c48b46 (diff) | |
download | src-74a628f776edb588bff8f8f5cc16eac947c9d631.tar.gz src-74a628f776edb588bff8f8f5cc16eac947c9d631.zip |
Vendor import of lldb trunk r300422:vendor/lldb/lldb-trunk-r300422
Notes
Notes:
svn path=/vendor/lldb/dist/; revision=317027
svn path=/vendor/lldb/lldb-trunk-r300422/; revision=317028; tag=vendor/lldb/lldb-trunk-r300422
Diffstat (limited to 'source/Target')
43 files changed, 918 insertions, 408 deletions
diff --git a/source/Target/CMakeLists.txt b/source/Target/CMakeLists.txt index cdb047a66400..1d858ae584d9 100644 --- a/source/Target/CMakeLists.txt +++ b/source/Target/CMakeLists.txt @@ -13,6 +13,7 @@ add_lldb_library(lldbTarget LanguageRuntime.cpp Memory.cpp MemoryHistory.cpp + ModuleCache.cpp ObjCLanguageRuntime.cpp OperatingSystem.cpp PathMappingList.cpp @@ -24,6 +25,7 @@ add_lldb_library(lldbTarget QueueItem.cpp QueueList.cpp RegisterContext.cpp + RegisterNumber.cpp SectionLoadHistory.cpp SectionLoadList.cpp StackFrame.cpp @@ -58,4 +60,19 @@ add_lldb_library(lldbTarget ThreadSpec.cpp UnixSignals.cpp UnwindAssembly.cpp + + LINK_LIBS + lldbBreakpoint + lldbCore + lldbExpression + lldbHost + lldbInterpreter + lldbSymbol + lldbUtility + lldbPluginExpressionParserClang + lldbPluginObjCLanguage + lldbPluginProcessUtility + + LINK_COMPONENTS + Support ) diff --git a/source/Target/FileAction.cpp b/source/Target/FileAction.cpp index 7c2567ebea2d..c9cc325b5a53 100644 --- a/source/Target/FileAction.cpp +++ b/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/source/Target/InstrumentationRuntime.cpp b/source/Target/InstrumentationRuntime.cpp index f3bc145f8b4e..ac8b5dfe4599 100644 --- a/source/Target/InstrumentationRuntime.cpp +++ b/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/source/Target/Language.cpp b/source/Target/Language.cpp index 938d80ac1758..8fef32a3b186 100644 --- a/source/Target/Language.cpp +++ b/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 }); diff --git a/source/Target/LanguageRuntime.cpp b/source/Target/LanguageRuntime.cpp index cacb491392f7..d0018b6df114 100644 --- a/source/Target/LanguageRuntime.cpp +++ b/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" diff --git a/source/Target/Memory.cpp b/source/Target/Memory.cpp index 775d0b305f26..c78bd7ad7b34 100644 --- a/source/Target/Memory.cpp +++ b/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; @@ -252,146 +252,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; } diff --git a/source/Target/ModuleCache.cpp b/source/Target/ModuleCache.cpp new file mode 100644 index 000000000000..a4aa26a0e480 --- /dev/null +++ b/source/Target/ModuleCache.cpp @@ -0,0 +1,331 @@ +//===--------------------- 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, Error &error); + void Delete(); +}; + +static FileSpec JoinPath(const FileSpec &path1, const char *path2) { + FileSpec result_spec(path1); + result_spec.AppendPathComponent(path2); + return result_spec; +} + +static Error 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; + + Error 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()); +} + +Error 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 Error(); + + 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, + Error &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()); +} + +///////////////////////////////////////////////////////////////////////// + +Error 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 Error("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 Error("Failed to create link to %s: %s", + module_file_path.GetPath().c_str(), error.AsCString()); + return Error(); +} + +Error 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 Error(); + 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 Error("Module %s not found", module_file_path.GetPath().c_str()); + if (module_file_path.GetByteSize() != module_spec.GetObjectSize()) + return Error("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 Error("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 Error(); +} + +Error 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 Error("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 Error("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 Error("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 Error(); + + error = Put(root_dir_spec, escaped_hostname.c_str(), module_spec, + tmp_download_sym_file_spec, + GetSymbolFileSpec(module_spec.GetFileSpec())); + if (error.Fail()) + return Error("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 Error(); +} diff --git a/source/Target/ObjCLanguageRuntime.cpp b/source/Target/ObjCLanguageRuntime.cpp index 3ee4dd3ad57a..6aeb4c46df48 100644 --- a/source/Target/ObjCLanguageRuntime.cpp +++ b/source/Target/ObjCLanguageRuntime.cpp @@ -8,7 +8,6 @@ //===----------------------------------------------------------------------===// #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" @@ -21,6 +20,7 @@ #include "lldb/Symbol/TypeList.h" #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/Log.h" #include "llvm/ADT/StringRef.h" diff --git a/source/Target/PathMappingList.cpp b/source/Target/PathMappingList.cpp index 90fff57d59bd..4fbaee98da61 100644 --- a/source/Target/PathMappingList.cpp +++ b/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/Error.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/Stream.h" using namespace lldb; using namespace lldb_private; diff --git a/source/Target/Platform.cpp b/source/Target/Platform.cpp index d8db53663f14..fd909075a240 100644 --- a/source/Target/Platform.cpp +++ b/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/Error.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/Log.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. @@ -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(); @@ -542,17 +544,18 @@ struct RecurseCopyBaton { }; 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()) @@ -582,7 +585,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,7 +607,7 @@ 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()) @@ -617,15 +620,13 @@ 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) { @@ -693,10 +694,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; @@ -714,29 +715,25 @@ Error Platform::Install(const FileSpec &src, const FileSpec &dst) { } } 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,14 +745,12 @@ 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); @@ -764,7 +759,7 @@ bool Platform::SetWorkingDirectory(const FileSpec &file_spec) { Error 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; error.SetErrorStringWithFormat("remote platform %s doesn't support %s", @@ -776,9 +771,12 @@ 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 { + if (IsHost()) { + auto Value = llvm::sys::fs::getPermissions(file_spec.GetPath()); + if (Value) + file_permissions = Value.get(); + return Error(Value.getError()); + } else { Error error; error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), @@ -789,9 +787,10 @@ 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 { + if (IsHost()) { + auto Perms = static_cast<llvm::sys::fs::perms>(file_permissions); + return llvm::sys::fs::setPermissions(file_spec.GetPath(), Perms); + } else { Error error; error.SetErrorStringWithFormat("remote platform %s doesn't support %s", GetPluginName().GetCString(), @@ -1239,7 +1238,8 @@ Error Platform::PutFile(const FileSpec &source, const FileSpec &destination, 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); @@ -1344,10 +1344,13 @@ lldb_private::Error Platform::RunShellCommand( 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) { @@ -1643,8 +1646,9 @@ Error Platform::DownloadModuleSlice(const FileSpec &src_file_spec, const FileSpec &dst_file_spec) { Error 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; diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp index c72662e4e343..0bc58f073bf1 100644 --- a/source/Target/Process.cpp +++ b/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" @@ -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( @@ -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; @@ -2798,7 +2776,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 @@ -2862,7 +2845,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. @@ -3046,7 +3031,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 +3190,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()); @@ -3276,6 +3262,10 @@ Error Process::PrivateResume() { m_mod_id.GetStopID(), StateAsCString(m_public_state.GetValue()), StateAsCString(m_private_state.GetValue())); + // If signals handing status changed we might want to update + // our signal filters before resuming. + UpdateAutomaticSignalFiltering(); + Error error(WillResume()); // Tell the process it is about to resume before the thread list if (error.Success()) { @@ -3754,8 +3744,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) @@ -5248,15 +5238,9 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx, 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) { + ThreadPlanSP plan = thread->GetCompletedPlan(); + if (plan == thread_plan_sp && plan->PlanSucceeded()) { + if (log) log->PutCString("Process::RunThreadPlan(): execution " "completed successfully."); @@ -5267,9 +5251,11 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx, return_value = eExpressionCompleted; } else { + StopInfoSP stop_info_sp = thread_sp->GetStopInfo(); // Something restarted the target, so just wait for it to // stop for real. - if (stop_reason == eStopReasonBreakpoint) { + if (stop_info_sp && + stop_info_sp->GetStopReason() == eStopReasonBreakpoint) { if (log) log->Printf("Process::RunThreadPlan() stopped for " "breakpoint: %s.", @@ -5348,19 +5334,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 @@ -6245,3 +6228,9 @@ bool Process::RouteAsyncStructuredData( find_it->second->HandleArrivalOfStructuredData(*this, type_name, object_sp); return true; } + +Error Process::UpdateAutomaticSignalFiltering() { + // Default implementation does nothign. + // No automatic signal filtering to speak of. + return Error(); +} diff --git a/source/Target/ProcessInfo.cpp b/source/Target/ProcessInfo.cpp index 5c4b2f07e426..0d986bc76914 100644 --- a/source/Target/ProcessInfo.cpp +++ b/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/source/Target/ProcessLaunchInfo.cpp b/source/Target/ProcessLaunchInfo.cpp index 92d9371b541f..7de55f2fdcf9 100644 --- a/source/Target/ProcessLaunchInfo.cpp +++ b/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> @@ -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/source/Target/RegisterContext.cpp b/source/Target/RegisterContext.cpp index 4cce4dd6bccc..6cbfb04a6e9a 100644 --- a/source/Target/RegisterContext.cpp +++ b/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; diff --git a/source/Target/RegisterNumber.cpp b/source/Target/RegisterNumber.cpp new file mode 100644 index 000000000000..d1bb8adf56e1 --- /dev/null +++ b/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/source/Target/SectionLoadHistory.cpp b/source/Target/SectionLoadHistory.cpp index 49a7cef8e39d..740f48bc829c 100644 --- a/source/Target/SectionLoadHistory.cpp +++ b/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/source/Target/SectionLoadList.cpp b/source/Target/SectionLoadList.cpp index a3599dd10e5e..7f12c262f47e 100644 --- a/source/Target/SectionLoadList.cpp +++ b/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) { diff --git a/source/Target/StackFrame.cpp b/source/Target/StackFrame.cpp index ec30fd62618a..7b7b596c9773 100644 --- a/source/Target/StackFrame.cpp +++ b/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" @@ -221,18 +222,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 +428,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()); } } @@ -604,8 +607,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 +627,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()) { + Error 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(".-["))); @@ -1186,9 +1212,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 +1320,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(); } diff --git a/source/Target/StackFrameList.cpp b/source/Target/StackFrameList.cpp index 146b2b05dbd7..044f860ba32b 100644 --- a/source/Target/StackFrameList.cpp +++ b/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 diff --git a/source/Target/StackID.cpp b/source/Target/StackID.cpp index 0d215ed5c9c3..889cf89b9be7 100644 --- a/source/Target/StackID.cpp +++ b/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/source/Target/StopInfo.cpp b/source/Target/StopInfo.cpp index 23dea41f61fb..8d40c7678b96 100644 --- a/source/Target/StopInfo.cpp +++ b/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()); @@ -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); diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp index 078fa6a7ff04..df021e3953bc 100644 --- a/source/Target/Target.cpp +++ b/source/Target/Target.cpp @@ -24,19 +24,16 @@ #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/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" @@ -57,7 +54,10 @@ #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" using namespace lldb; using namespace lldb_private; @@ -2173,7 +2173,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 +2190,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); diff --git a/source/Target/TargetList.cpp b/source/Target/TargetList.cpp index 0637cffddcc1..0849c18b89e0 100644 --- a/source/Target/TargetList.cpp +++ b/source/Target/TargetList.cpp @@ -7,12 +7,8 @@ // //===----------------------------------------------------------------------===// -// 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" @@ -27,7 +23,11 @@ #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" + +// Other libraries and framework includes +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/FileSystem.h" using namespace lldb; using namespace lldb_private; @@ -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/source/Target/Thread.cpp b/source/Target/Thread.cpp index 5ead59052856..4b21382ff86f 100644 --- a/source/Target/Thread.cpp +++ b/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,10 @@ #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" using namespace lldb; using namespace lldb_private; @@ -380,24 +380,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 +467,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,7 +540,8 @@ 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 +574,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 +911,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 +924,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 +1160,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; diff --git a/source/Target/ThreadList.cpp b/source/Target/ThreadList.cpp index 1e474518aace..4cf8f9061a89 100644 --- a/source/Target/ThreadList.cpp +++ b/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/source/Target/ThreadPlan.cpp b/source/Target/ThreadPlan.cpp index 6b997476d92f..27c9e2aa9c00 100644 --- a/source/Target/ThreadPlan.cpp +++ b/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/source/Target/ThreadPlanBase.cpp b/source/Target/ThreadPlanBase.cpp index f290483e904d..d1c2f6dd1206 100644 --- a/source/Target/ThreadPlanBase.cpp +++ b/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/source/Target/ThreadPlanCallFunction.cpp b/source/Target/ThreadPlanCallFunction.cpp index 68fd50390e64..2c630d59e84c 100644 --- a/source/Target/ThreadPlanCallFunction.cpp +++ b/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; @@ -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/source/Target/ThreadPlanCallFunctionUsingABI.cpp b/source/Target/ThreadPlanCallFunctionUsingABI.cpp index 6c5969577a90..b90fd9edd766 100644 --- a/source/Target/ThreadPlanCallFunctionUsingABI.cpp +++ b/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/source/Target/ThreadPlanCallUserExpression.cpp b/source/Target/ThreadPlanCallUserExpression.cpp index 260118c31e11..679040d09a02 100644 --- a/source/Target/ThreadPlanCallUserExpression.cpp +++ b/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; diff --git a/source/Target/ThreadPlanPython.cpp b/source/Target/ThreadPlanPython.cpp index 180586ae0f2c..af5c76518382 100644 --- a/source/Target/ThreadPlanPython.cpp +++ b/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/source/Target/ThreadPlanRunToAddress.cpp b/source/Target/ThreadPlanRunToAddress.cpp index 6f31db0d93a2..44de724b608c 100644 --- a/source/Target/ThreadPlanRunToAddress.cpp +++ b/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/source/Target/ThreadPlanShouldStopHere.cpp b/source/Target/ThreadPlanShouldStopHere.cpp index 408650d75f0b..42aaa4227cf9 100644 --- a/source/Target/ThreadPlanShouldStopHere.cpp +++ b/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/source/Target/ThreadPlanStepInRange.cpp b/source/Target/ThreadPlanStepInRange.cpp index 03f6679ae322..caaaffea8e8a 100644 --- a/source/Target/ThreadPlanStepInRange.cpp +++ b/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/source/Target/ThreadPlanStepInstruction.cpp b/source/Target/ThreadPlanStepInstruction.cpp index 6ad6a2343a5e..ca45960e1ed5 100644 --- a/source/Target/ThreadPlanStepInstruction.cpp +++ b/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/source/Target/ThreadPlanStepOut.cpp b/source/Target/ThreadPlanStepOut.cpp index b8d6e6dcba9d..6b6ed06e9b37 100644 --- a/source/Target/ThreadPlanStepOut.cpp +++ b/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/source/Target/ThreadPlanStepOverBreakpoint.cpp b/source/Target/ThreadPlanStepOverBreakpoint.cpp index 39641a065482..3896a0b24714 100644 --- a/source/Target/ThreadPlanStepOverBreakpoint.cpp +++ b/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/source/Target/ThreadPlanStepOverRange.cpp b/source/Target/ThreadPlanStepOverRange.cpp index 48c7ff8be454..d5778fb5e8d7 100644 --- a/source/Target/ThreadPlanStepOverRange.cpp +++ b/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/source/Target/ThreadPlanStepRange.cpp b/source/Target/ThreadPlanStepRange.cpp index dcee82ea32a5..09e606f490a6 100644 --- a/source/Target/ThreadPlanStepRange.cpp +++ b/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/source/Target/ThreadPlanStepThrough.cpp b/source/Target/ThreadPlanStepThrough.cpp index b9751614a52c..46aadb00f2ab 100644 --- a/source/Target/ThreadPlanStepThrough.cpp +++ b/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/source/Target/ThreadPlanStepUntil.cpp b/source/Target/ThreadPlanStepUntil.cpp index a10e2f47c90d..01f5f948a28c 100644 --- a/source/Target/ThreadPlanStepUntil.cpp +++ b/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/source/Target/ThreadPlanTracer.cpp b/source/Target/ThreadPlanTracer.cpp index 7fbd664233b6..f8368123a0c7 100644 --- a/source/Target/ThreadPlanTracer.cpp +++ b/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; diff --git a/source/Target/UnixSignals.cpp b/source/Target/UnixSignals.cpp index cee69bf67db1..a4ec32bd0075 100644 --- a/source/Target/UnixSignals.cpp +++ b/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; +} |