diff options
Diffstat (limited to 'source/Utility')
-rw-r--r-- | source/Utility/ConvertEnum.cpp | 2 | ||||
-rw-r--r-- | source/Utility/JSON.cpp | 1 | ||||
-rw-r--r-- | source/Utility/Makefile | 15 | ||||
-rw-r--r-- | source/Utility/ModuleCache.cpp | 24 | ||||
-rw-r--r-- | source/Utility/SharingPtr.cpp | 8 | ||||
-rw-r--r-- | source/Utility/StringExtractor.cpp | 3 | ||||
-rw-r--r-- | source/Utility/StringExtractorGDBRemote.cpp | 133 | ||||
-rw-r--r-- | source/Utility/StringExtractorGDBRemote.h | 32 | ||||
-rw-r--r-- | source/Utility/TaskPool.cpp | 5 |
9 files changed, 192 insertions, 31 deletions
diff --git a/source/Utility/ConvertEnum.cpp b/source/Utility/ConvertEnum.cpp index 3231397a05e3b..99515631db250 100644 --- a/source/Utility/ConvertEnum.cpp +++ b/source/Utility/ConvertEnum.cpp @@ -115,6 +115,8 @@ lldb_private::GetSectionTypeAsCString(lldb::SectionType sect_type) return "compact-unwind"; case eSectionTypeGoSymtab: return "go-symtab"; + case eSectionTypeAbsoluteAddress: + return "absolute"; case eSectionTypeOther: return "regular"; } diff --git a/source/Utility/JSON.cpp b/source/Utility/JSON.cpp index 8b96a06e08e82..7ad3232c564d8 100644 --- a/source/Utility/JSON.cpp +++ b/source/Utility/JSON.cpp @@ -445,6 +445,7 @@ JSONParser::GetToken (std::string &value) value = std::move(error.GetString()); return Token::Error; } + break; default: done = true; diff --git a/source/Utility/Makefile b/source/Utility/Makefile deleted file mode 100644 index 13bcd8376c2df..0000000000000 --- a/source/Utility/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -##===- source/Utility/Makefile -----------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLDB_LEVEL := ../.. -LIBRARYNAME := lldbUtility -BUILD_ARCHIVE = 1 -NO_PEDANTIC = 1 - -include $(LLDB_LEVEL)/Makefile diff --git a/source/Utility/ModuleCache.cpp b/source/Utility/ModuleCache.cpp index 7c57d0baeccdc..92520f768b3f3 100644 --- a/source/Utility/ModuleCache.cpp +++ b/source/Utility/ModuleCache.cpp @@ -33,6 +33,21 @@ 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) +{ + 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 { @@ -280,8 +295,9 @@ ModuleCache::GetAndPut (const FileSpec &root_dir_spec, 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, hostname, module_spec, cached_module_sp, did_create_ptr); + error = Get (root_dir_spec, escaped_hostname.c_str(), module_spec, cached_module_sp, did_create_ptr); if (error.Success ()) return error; @@ -292,12 +308,12 @@ ModuleCache::GetAndPut (const FileSpec &root_dir_spec, return Error("Failed to download module: %s", error.AsCString ()); // Put downloaded file into local module cache. - error = Put (root_dir_spec, hostname, module_spec, tmp_download_file_spec, module_spec.GetFileSpec ()); + 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, hostname, module_spec, cached_module_sp, did_create_ptr); + error = Get (root_dir_spec, escaped_hostname.c_str(), module_spec, cached_module_sp, did_create_ptr); if (error.Fail ()) return error; @@ -310,7 +326,7 @@ ModuleCache::GetAndPut (const FileSpec &root_dir_spec, // contain the neccessary symbols and the debugging is also possible without a symfile. return Error (); - error = Put (root_dir_spec, hostname, module_spec, tmp_download_sym_file_spec, GetSymbolFileSpec(module_spec.GetFileSpec ())); + 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 ()); diff --git a/source/Utility/SharingPtr.cpp b/source/Utility/SharingPtr.cpp index 7f1278567ff11..7eedeb08afd1f 100644 --- a/source/Utility/SharingPtr.cpp +++ b/source/Utility/SharingPtr.cpp @@ -14,12 +14,12 @@ // If ENABLE_SP_LOGGING is defined, then log all shared pointer assignments // and allow them to be queried using a pointer by a call to: #include <execinfo.h> -#include <map> #include <assert.h> -#include "lldb/Host/Mutex.h" #include "llvm/ADT/STLExtras.h" +#include <map> +#include <mutex> #include <vector> class Backtrace @@ -70,8 +70,8 @@ extern "C" void track_sp (void *sp_this, void *ptr, long use_count) { typedef std::pair<void *, Backtrace> PtrBacktracePair; typedef std::map<void *, PtrBacktracePair> PtrToBacktraceMap; - static lldb_private::Mutex g_mutex(lldb_private::Mutex::eMutexTypeNormal); - lldb_private::Mutex::Locker locker (g_mutex); + static std::mutex g_mutex; + std::lock_guard<std::mutex> guard(g_mutex); static PtrToBacktraceMap g_map; if (sp_this) diff --git a/source/Utility/StringExtractor.cpp b/source/Utility/StringExtractor.cpp index ae92704668fc7..4c0029a0649b4 100644 --- a/source/Utility/StringExtractor.cpp +++ b/source/Utility/StringExtractor.cpp @@ -104,6 +104,7 @@ StringExtractor::GetChar (char fail_value) int StringExtractor::DecodeHexU8() { + SkipSpaces(); if (GetBytesLeft() < 2) { return -1; @@ -230,6 +231,7 @@ StringExtractor::GetHexMaxU32 (bool little_endian, uint32_t fail_value) uint32_t result = 0; uint32_t nibble_count = 0; + SkipSpaces(); if (little_endian) { uint32_t shift_amount = 0; @@ -292,6 +294,7 @@ StringExtractor::GetHexMaxU64 (bool little_endian, uint64_t fail_value) uint64_t result = 0; uint32_t nibble_count = 0; + SkipSpaces(); if (little_endian) { uint32_t shift_amount = 0; diff --git a/source/Utility/StringExtractorGDBRemote.cpp b/source/Utility/StringExtractorGDBRemote.cpp index 56df0be21edf3..d2619afd5bfa3 100644 --- a/source/Utility/StringExtractorGDBRemote.cpp +++ b/source/Utility/StringExtractorGDBRemote.cpp @@ -15,8 +15,6 @@ // Project includes #include "Utility/StringExtractorGDBRemote.h" - - StringExtractorGDBRemote::ResponseType StringExtractorGDBRemote::GetResponseType () const { @@ -227,7 +225,7 @@ StringExtractorGDBRemote::GetServerPacketType () const case 'j': if (PACKET_MATCHES("jSignalsInfo")) return eServerPacketType_jSignalsInfo; if (PACKET_MATCHES("jThreadsInfo")) return eServerPacketType_jThreadsInfo; - + break; case 'v': if (PACKET_STARTS_WITH("vFile:")) @@ -391,3 +389,132 @@ StringExtractorGDBRemote::GetEscapedBinaryData (std::string &str) return str.size(); } +static bool +OKErrorNotSupportedResponseValidator(void *, const StringExtractorGDBRemote &response) +{ + switch (response.GetResponseType()) + { + case StringExtractorGDBRemote::eOK: + case StringExtractorGDBRemote::eError: + case StringExtractorGDBRemote::eUnsupported: + return true; + + case StringExtractorGDBRemote::eAck: + case StringExtractorGDBRemote::eNack: + case StringExtractorGDBRemote::eResponse: + break; + } + return false; +} + +static bool +JSONResponseValidator(void *, const StringExtractorGDBRemote &response) +{ + switch (response.GetResponseType()) + { + case StringExtractorGDBRemote::eUnsupported: + case StringExtractorGDBRemote::eError: + return true; // Accept unsupported or EXX as valid responses + + case StringExtractorGDBRemote::eOK: + case StringExtractorGDBRemote::eAck: + case StringExtractorGDBRemote::eNack: + break; + + case StringExtractorGDBRemote::eResponse: + // JSON that is returned in from JSON query packets is currently always + // either a dictionary which starts with a '{', or an array which + // starts with a '['. This is a quick validator to just make sure the + // response could be valid JSON without having to validate all of the + // JSON content. + switch (response.GetStringRef()[0]) + { + case '{': return true; + case '[': return true; + default: + break; + } + break; + } + return false; +} + +static bool +ASCIIHexBytesResponseValidator(void *, const StringExtractorGDBRemote &response) +{ + switch (response.GetResponseType()) + { + case StringExtractorGDBRemote::eUnsupported: + case StringExtractorGDBRemote::eError: + return true; // Accept unsupported or EXX as valid responses + + case StringExtractorGDBRemote::eOK: + case StringExtractorGDBRemote::eAck: + case StringExtractorGDBRemote::eNack: + break; + + case StringExtractorGDBRemote::eResponse: + { + uint32_t valid_count = 0; + for (const char ch : response.GetStringRef()) + { + if (!isxdigit(ch)) + { + return false; + } + if (++valid_count >= 16) + break; // Don't validate all the characters in case the packet is very large + } + return true; + } + break; + } + return false; +} + +void +StringExtractorGDBRemote::CopyResponseValidator(const StringExtractorGDBRemote& rhs) +{ + m_validator = rhs.m_validator; + m_validator_baton = rhs.m_validator_baton; +} + +void +StringExtractorGDBRemote::SetResponseValidator(ResponseValidatorCallback callback, void *baton) +{ + m_validator = callback; + m_validator_baton = baton; +} + +void +StringExtractorGDBRemote::SetResponseValidatorToOKErrorNotSupported() +{ + m_validator = OKErrorNotSupportedResponseValidator; + m_validator_baton = nullptr; +} + +void +StringExtractorGDBRemote::SetResponseValidatorToASCIIHexBytes() +{ + m_validator = ASCIIHexBytesResponseValidator; + m_validator_baton = nullptr; +} + +void +StringExtractorGDBRemote::SetResponseValidatorToJSON() +{ + m_validator = JSONResponseValidator; + m_validator_baton = nullptr; +} + +bool +StringExtractorGDBRemote::ValidateResponse() const +{ + // If we have a validator callback, try to validate the callback + if (m_validator) + return m_validator(m_validator_baton, *this); + else + return true; // No validator, so response is valid +} + + diff --git a/source/Utility/StringExtractorGDBRemote.h b/source/Utility/StringExtractorGDBRemote.h index 7e2f1e7c69625..ade0edbbb7aed 100644 --- a/source/Utility/StringExtractorGDBRemote.h +++ b/source/Utility/StringExtractorGDBRemote.h @@ -20,18 +20,23 @@ class StringExtractorGDBRemote : public StringExtractor { public: + typedef bool (*ResponseValidatorCallback)(void * baton, const StringExtractorGDBRemote &response); StringExtractorGDBRemote() : - StringExtractor () + StringExtractor(), + m_validator(nullptr) { } StringExtractorGDBRemote(const char *cstr) : - StringExtractor (cstr) + StringExtractor(cstr), + m_validator(nullptr) { } + StringExtractorGDBRemote(const StringExtractorGDBRemote& rhs) : - StringExtractor (rhs) + StringExtractor(rhs), + m_validator(rhs.m_validator) { } @@ -39,6 +44,24 @@ public: { } + bool + ValidateResponse() const; + + void + CopyResponseValidator(const StringExtractorGDBRemote& rhs); + + void + SetResponseValidator(ResponseValidatorCallback callback, void *baton); + + void + SetResponseValidatorToOKErrorNotSupported(); + + void + SetResponseValidatorToASCIIHexBytes(); + + void + SetResponseValidatorToJSON(); + enum ServerPacketType { eServerPacketType_nack = 0, @@ -192,6 +215,9 @@ public: size_t GetEscapedBinaryData (std::string &str); +protected: + ResponseValidatorCallback m_validator; + void *m_validator_baton; }; #endif // utility_StringExtractorGDBRemote_h_ diff --git a/source/Utility/TaskPool.cpp b/source/Utility/TaskPool.cpp index 75fe59d1e7110..c5c63a20cebca 100644 --- a/source/Utility/TaskPool.cpp +++ b/source/Utility/TaskPool.cpp @@ -61,8 +61,9 @@ TaskPoolImpl::AddTask(std::function<void()>&& task_fn) if (m_thread_count < max_threads) { m_thread_count++; - lock.unlock(); - + // Note that this detach call needs to happen with the m_tasks_mutex held. This prevents the thread + // from exiting prematurely and triggering a linux libc bug + // (https://sourceware.org/bugzilla/show_bug.cgi?id=19951). std::thread (Worker, this).detach(); } } |