Index: include/lldb/Breakpoint/BreakpointLocationCollection.h =================================================================== --- include/lldb/Breakpoint/BreakpointLocationCollection.h +++ include/lldb/Breakpoint/BreakpointLocationCollection.h @@ -13,6 +13,8 @@ // C Includes // C++ Includes #include +#include + // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" @@ -201,7 +203,8 @@ collection::const_iterator GetIDPairConstIterator(lldb::break_id_t break_id, lldb::break_id_t break_loc_id) const; - collection m_break_loc_collection; + collection m_break_loc_collection; + mutable std::mutex m_collection_mutex; public: typedef AdaptedIterable BreakpointLocationCollectionIterable; Index: include/lldb/Core/Logging.h =================================================================== --- include/lldb/Core/Logging.h +++ include/lldb/Core/Logging.h @@ -49,6 +49,7 @@ #define LIBLLDB_LOG_JIT_LOADER (1u << 27) #define LIBLLDB_LOG_LANGUAGE (1u << 28) #define LIBLLDB_LOG_DATAFORMATTERS (1u << 29) +#define LIBLLDB_LOG_DEMANGLE (1u << 30) #define LIBLLDB_LOG_ALL (UINT32_MAX) #define LIBLLDB_LOG_DEFAULT (LIBLLDB_LOG_PROCESS |\ LIBLLDB_LOG_THREAD |\ Index: source/Breakpoint/BreakpointLocationCollection.cpp =================================================================== --- source/Breakpoint/BreakpointLocationCollection.cpp +++ source/Breakpoint/BreakpointLocationCollection.cpp @@ -26,7 +26,8 @@ // BreakpointLocationCollection constructor //---------------------------------------------------------------------- BreakpointLocationCollection::BreakpointLocationCollection() : - m_break_loc_collection() + m_break_loc_collection(), + m_collection_mutex() { } @@ -40,6 +41,7 @@ void BreakpointLocationCollection::Add(const BreakpointLocationSP &bp_loc) { + std::lock_guard guard(m_collection_mutex); BreakpointLocationSP old_bp_loc = FindByIDPair (bp_loc->GetBreakpoint().GetID(), bp_loc->GetID()); if (!old_bp_loc.get()) m_break_loc_collection.push_back(bp_loc); @@ -48,6 +50,7 @@ bool BreakpointLocationCollection::Remove (lldb::break_id_t bp_id, lldb::break_id_t bp_loc_id) { + std::lock_guard guard(m_collection_mutex); collection::iterator pos = GetIDPairIterator(bp_id, bp_loc_id); // Predicate if (pos != m_break_loc_collection.end()) { @@ -117,6 +120,7 @@ BreakpointLocationSP BreakpointLocationCollection::GetByIndex (size_t i) { + std::lock_guard guard(m_collection_mutex); BreakpointLocationSP stop_sp; if (i < m_break_loc_collection.size()) stop_sp = m_break_loc_collection[i]; @@ -127,6 +131,7 @@ const BreakpointLocationSP BreakpointLocationCollection::GetByIndex (size_t i) const { + std::lock_guard guard(m_collection_mutex); BreakpointLocationSP stop_sp; if (i < m_break_loc_collection.size()) stop_sp = m_break_loc_collection[i]; @@ -156,6 +161,7 @@ bool BreakpointLocationCollection::ValidForThisThread (Thread *thread) { + std::lock_guard guard(m_collection_mutex); collection::iterator pos, begin = m_break_loc_collection.begin(), end = m_break_loc_collection.end(); @@ -171,6 +177,7 @@ bool BreakpointLocationCollection::IsInternal () const { + std::lock_guard guard(m_collection_mutex); collection::const_iterator pos, begin = m_break_loc_collection.begin(), end = m_break_loc_collection.end(); @@ -191,6 +198,7 @@ void BreakpointLocationCollection::GetDescription (Stream *s, lldb::DescriptionLevel level) { + std::lock_guard guard(m_collection_mutex); collection::iterator pos, begin = m_break_loc_collection.begin(), end = m_break_loc_collection.end(); Index: source/Core/Logging.cpp =================================================================== --- source/Core/Logging.cpp +++ source/Core/Logging.cpp @@ -150,6 +150,7 @@ else if (0 == ::strcasecmp(arg, "jit")) flag_bits &= ~LIBLLDB_LOG_JIT_LOADER; else if (0 == ::strcasecmp(arg, "language")) flag_bits &= ~LIBLLDB_LOG_LANGUAGE; else if (0 == ::strncasecmp(arg, "formatters", 10)) flag_bits &= ~LIBLLDB_LOG_DATAFORMATTERS; + else if (0 == ::strncasecmp(arg, "demangle", 8)) flag_bits &= ~LIBLLDB_LOG_DEMANGLE; else { feedback_strm->Printf ("error: unrecognized log category '%s'\n", arg); @@ -225,6 +226,7 @@ else if (0 == ::strcasecmp(arg, "jit")) flag_bits |= LIBLLDB_LOG_JIT_LOADER; else if (0 == ::strcasecmp(arg, "language")) flag_bits |= LIBLLDB_LOG_LANGUAGE; else if (0 == ::strncasecmp(arg, "formatters", 10)) flag_bits |= LIBLLDB_LOG_DATAFORMATTERS; + else if (0 == ::strncasecmp(arg, "demangle", 8)) flag_bits |= LIBLLDB_LOG_DEMANGLE; else { feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); @@ -251,6 +253,7 @@ " communication - log communication activities\n" " connection - log connection details\n" " default - enable the default set of logging categories for liblldb\n" + " demangle - log mangled names to catch demangler crashes\n" " dyld - log shared library related activities\n" " events - log broadcaster, listener and event queue activities\n" " expr - log expressions\n" Index: source/Core/Mangled.cpp =================================================================== --- source/Core/Mangled.cpp +++ source/Core/Mangled.cpp @@ -34,6 +34,8 @@ #include "llvm/ADT/DenseMap.h" #include "lldb/Core/ConstString.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Logging.h" #include "lldb/Core/Mangled.h" #include "lldb/Core/RegularExpression.h" #include "lldb/Core/Stream.h" @@ -271,6 +273,8 @@ "Mangled::GetDemangledName (m_mangled = %s)", m_mangled.GetCString()); + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DEMANGLE); + // Don't bother running anything that isn't mangled const char *mangled_name = m_mangled.GetCString(); ManglingScheme mangling_scheme{cstring_mangling_scheme(mangled_name)}; @@ -285,6 +289,8 @@ case eManglingSchemeMSVC: { #if defined(_MSC_VER) + if (log) + log->Printf("demangle msvc: %s", mangled_name); const size_t demangled_length = 2048; demangled_name = static_cast(::malloc(demangled_length)); ::ZeroMemory(demangled_name, demangled_length); @@ -295,6 +301,14 @@ UNDNAME_NO_MEMBER_TYPE | // Strip virtual, static, etc specifiers UNDNAME_NO_MS_KEYWORDS // Strip all MS extension keywords ); + if (log) + { + if (demangled_name && demangled_name[0]) + log->Printf("demangled msvc: %s -> \"%s\"", mangled_name, demangled_name); + else + log->Printf("demangled msvc: %s -> error: 0x%" PRIx64, mangled_name, result); + } + if (result == 0) { free(demangled_name); @@ -306,6 +320,8 @@ case eManglingSchemeItanium: { #ifdef LLDB_USE_BUILTIN_DEMANGLER + if (log) + log->Printf("demangle itanium: %s", mangled_name); // Try to use the fast-path demangler first for the // performance win, falling back to the full demangler only // when necessary @@ -315,6 +331,13 @@ #else demangled_name = abi::__cxa_demangle(mangled_name, NULL, NULL, NULL); #endif + if (log) + { + if (demangled_name) + log->Printf("demangled itanium: %s -> \"%s\"", mangled_name, demangled_name); + else + log->Printf("demangled itanium: %s -> error: failed to demangle", mangled_name); + } break; } case eManglingSchemeNone: Index: source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h =================================================================== --- source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h +++ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h @@ -65,7 +65,6 @@ private: static const char *g_lookup_implementation_function_name; - static const char *g_lookup_implementation_function_code; static const char *g_lookup_implementation_with_stret_function_code; static const char *g_lookup_implementation_no_stret_function_code; @@ -195,6 +194,7 @@ MsgsendMap m_msgSend_map; lldb::ProcessWP m_process_wp; lldb::ModuleSP m_objc_module_sp; + const char *m_lookup_implementation_function_code; std::unique_ptr m_impl_code; std::mutex m_impl_function_mutex; lldb::addr_t m_impl_fn_addr; Index: source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp =================================================================== --- source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp +++ source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp @@ -44,7 +44,6 @@ using namespace lldb_private; const char *AppleObjCTrampolineHandler::g_lookup_implementation_function_name = "__lldb_objc_find_implementation_for_selector"; -const char *AppleObjCTrampolineHandler::g_lookup_implementation_function_code = NULL; const char *AppleObjCTrampolineHandler::g_lookup_implementation_with_stret_function_code = " \n\ extern \"C\" \n\ { \n\ @@ -658,6 +657,7 @@ const ModuleSP &objc_module_sp) : m_process_wp (), m_objc_module_sp (objc_module_sp), + m_lookup_implementation_function_code(nullptr), m_impl_fn_addr (LLDB_INVALID_ADDRESS), m_impl_stret_fn_addr (LLDB_INVALID_ADDRESS), m_msg_forward_addr (LLDB_INVALID_ADDRESS) @@ -704,11 +704,11 @@ // It there is no stret return lookup function, assume that it is the same as the straight lookup: m_impl_stret_fn_addr = m_impl_fn_addr; // Also we will use the version of the lookup code that doesn't rely on the stret version of the function. - g_lookup_implementation_function_code = g_lookup_implementation_no_stret_function_code; + m_lookup_implementation_function_code = g_lookup_implementation_no_stret_function_code; } else { - g_lookup_implementation_function_code = g_lookup_implementation_with_stret_function_code; + m_lookup_implementation_function_code = g_lookup_implementation_with_stret_function_code; } // Look up the addresses for the objc dispatch functions and cache them. For now I'm inspecting the symbol @@ -757,10 +757,10 @@ if (!m_impl_code.get()) { - if (g_lookup_implementation_function_code != NULL) + if (m_lookup_implementation_function_code != NULL) { Error error; - m_impl_code.reset (exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage (g_lookup_implementation_function_code, + m_impl_code.reset (exe_ctx.GetTargetRef().GetUtilityFunctionForLanguage (m_lookup_implementation_function_code, eLanguageTypeObjC, g_lookup_implementation_function_name, error)); Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp @@ -132,7 +132,10 @@ assert(ok); std::ostringstream url; + // debugserver does not accept the URL scheme prefix. +#if !defined(__APPLE__) url << m_socket_scheme << "://"; +#endif uint16_t* port_ptr = &port; if (m_socket_protocol == Socket::ProtocolTcp) url << platform_ip << ":" << port; Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -896,8 +896,16 @@ if (die.HasChildren() == false) { // No children for this struct/union/class, lets finish it - ClangASTContext::StartTagDeclarationDefinition (clang_type); - ClangASTContext::CompleteTagDeclarationDefinition (clang_type); + if (ClangASTContext::StartTagDeclarationDefinition (clang_type)) + { + ClangASTContext::CompleteTagDeclarationDefinition (clang_type); + } + else + { + dwarf->GetObjectFile()->GetModule()->ReportError("DWARF DIE at 0x%8.8x named \"%s\" was not able to start its definition.\nPlease file a bug and attach the file at the start of this error message", + die.GetOffset(), + type_name_cstr); + } if (tag == DW_TAG_structure_type) // this only applies in C { @@ -1085,15 +1093,23 @@ clang_type, Type::eResolveStateForward)); - ClangASTContext::StartTagDeclarationDefinition (clang_type); - if (die.HasChildren()) + if (ClangASTContext::StartTagDeclarationDefinition (clang_type)) { - SymbolContext cu_sc(die.GetLLDBCompileUnit()); - bool is_signed = false; - enumerator_clang_type.IsIntegerType(is_signed); - ParseChildEnumerators(cu_sc, clang_type, is_signed, type_sp->GetByteSize(), die); + if (die.HasChildren()) + { + SymbolContext cu_sc(die.GetLLDBCompileUnit()); + bool is_signed = false; + enumerator_clang_type.IsIntegerType(is_signed); + ParseChildEnumerators(cu_sc, clang_type, is_signed, type_sp->GetByteSize(), die); + } + ClangASTContext::CompleteTagDeclarationDefinition (clang_type); + } + else + { + dwarf->GetObjectFile()->GetModule()->ReportError("DWARF DIE at 0x%8.8x named \"%s\" was not able to start its definition.\nPlease file a bug and attach the file at the start of this error message", + die.GetOffset(), + type_name_cstr); } - ClangASTContext::CompleteTagDeclarationDefinition (clang_type); } } break; @@ -1735,8 +1751,16 @@ // to layout the class. Since we provide layout assistance, all // ivars in this class and other classes will be fine, this is // the best we can do short of crashing. - ClangASTContext::StartTagDeclarationDefinition(array_element_type); - ClangASTContext::CompleteTagDeclarationDefinition(array_element_type); + if (ClangASTContext::StartTagDeclarationDefinition(array_element_type)) + { + ClangASTContext::CompleteTagDeclarationDefinition(array_element_type); + } + else + { + module_sp->ReportError ("DWARF DIE at 0x%8.8x was not able to start its definition.\nPlease file a bug and attach the file at the start of this error message", + type_die_ref.die_offset, + type_name_cstr); + } } uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride; @@ -2242,8 +2266,10 @@ // below. Since we provide layout assistance, all ivars in this // class and other classes will be fine, this is the best we can do // short of crashing. - ClangASTContext::StartTagDeclarationDefinition (base_class_type); - ClangASTContext::CompleteTagDeclarationDefinition (base_class_type); + if (ClangASTContext::StartTagDeclarationDefinition (base_class_type)) + { + ClangASTContext::CompleteTagDeclarationDefinition (base_class_type); + } } } } @@ -2339,15 +2365,17 @@ return (bool)clang_type; case DW_TAG_enumeration_type: - ClangASTContext::StartTagDeclarationDefinition (clang_type); - if (die.HasChildren()) + if (ClangASTContext::StartTagDeclarationDefinition (clang_type)) { - SymbolContext sc(die.GetLLDBCompileUnit()); - bool is_signed = false; - clang_type.IsIntegerType(is_signed); - ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(), die); + if (die.HasChildren()) + { + SymbolContext sc(die.GetLLDBCompileUnit()); + bool is_signed = false; + clang_type.IsIntegerType(is_signed); + ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(), die); + } + ClangASTContext::CompleteTagDeclarationDefinition (clang_type); } - ClangASTContext::CompleteTagDeclarationDefinition (clang_type); return (bool)clang_type; default: @@ -3089,8 +3117,18 @@ // to layout the class. Since we provide layout assistance, all // ivars in this class and other classes will be fine, this is // the best we can do short of crashing. - ClangASTContext::StartTagDeclarationDefinition(member_clang_type); - ClangASTContext::CompleteTagDeclarationDefinition(member_clang_type); + if (ClangASTContext::StartTagDeclarationDefinition(member_clang_type)) + { + ClangASTContext::CompleteTagDeclarationDefinition(member_clang_type); + } + else + { + module_sp->ReportError ("DWARF DIE at 0x%8.8x (class %s) has a member variable 0x%8.8x (%s) whose type claims to be a C++ class but we were not able to start its definition.\nPlease file a bug and attach the file at the start of this error message", + parent_die.GetOffset(), + parent_die.GetName(), + die.GetOffset(), + name); + } } field_decl = ClangASTContext::AddFieldToRecordType (class_clang_type, Index: source/Symbol/ClangASTContext.cpp =================================================================== --- source/Symbol/ClangASTContext.cpp +++ source/Symbol/ClangASTContext.cpp @@ -2013,10 +2013,33 @@ bool is_variadic, unsigned type_quals) { - assert (ast != nullptr); + if (ast == nullptr) + return CompilerType(); // invalid AST + + if (!result_type || !ClangUtil::IsClangType(result_type)) + return CompilerType(); // invalid return type + std::vector qual_type_args; + if (num_args > 0 && args == nullptr) + return CompilerType(); // invalid argument array passed in + + // Verify that all arguments are valid and the right type for (unsigned i=0; igetAsCXXRecordDecl(); - - if (cxx_record_decl) + // Make sure we use the same methodology as ClangASTContext::StartTagDeclarationDefinition() + // as to how we start/end the definition. Previously we were calling + const clang::TagType *tag_type = qual_type->getAs(); + if (tag_type) { - if (!cxx_record_decl->isCompleteDefinition()) - cxx_record_decl->completeDefinition(); - cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true); - cxx_record_decl->setHasExternalLexicalStorage (false); - cxx_record_decl->setHasExternalVisibleStorage (false); - return true; + clang::TagDecl *tag_decl = tag_type->getDecl(); + if (tag_decl) + { + clang::CXXRecordDecl *cxx_record_decl = llvm::dyn_cast_or_null(tag_decl); + + if (cxx_record_decl) + { + if (!cxx_record_decl->isCompleteDefinition()) + cxx_record_decl->completeDefinition(); + cxx_record_decl->setHasLoadedFieldsFromExternalStorage(true); + cxx_record_decl->setHasExternalLexicalStorage (false); + cxx_record_decl->setHasExternalVisibleStorage (false); + return true; + } + } } - + const clang::EnumType *enutype = qual_type->getAs(); if (enutype) Index: source/Target/ProcessInfo.cpp =================================================================== --- source/Target/ProcessInfo.cpp +++ source/Target/ProcessInfo.cpp @@ -69,19 +69,15 @@ void ProcessInfo::Dump (Stream &s, Platform *platform) const { - // Print executable name. - s << "ProcessInfo\nExecutable:\n\t" << GetName() << "\n\n"; - - // Triple. + s << "Executable: " << GetName() << "\n"; s << "Triple: "; m_arch.DumpTriple(s); + s << "\n"; - // Print arguments - s << "\nArguments:\n"; + s << "Arguments:\n"; m_arguments.Dump(&s); - // Print environment. - s << "\nEnvironment:\n"; + s << "Environment:\n"; m_environment.Dump(&s, "env"); }