Author: jmolenda Date: Fri Jul 29 01:24:03 2016 New Revision: 277123 URL: http://llvm.org/viewvc/llvm-project?rev=277123&view=rev Log: PlatformDarwinKernel maintains a list of kexts and kernels that it finds on the local computer in "well known" locations when we start up the darwin-kernel platform. It did not distinguish between kexts/kernels with dSYMs from others - when it needed a kernel/kext with a given UUID, it would grab the first one it finds.
This change separates these into two vectors -- a collection of kexts and kernels with dSYMs next t othem, and a collection of kexts and kernels without dSYMs. When we have a bundle ID and uuid to search for, we first try the collections with dSYMs, and if that fails, then we try the collections that did not have dSYMs next to them. Often times we'll have a situation where a kext will be installed in multiple locations on a system, but only one of them will have a dSYM next to it, where the dev just copied it to a local directory. This fixes that problem, giving precedence to those binaries with debug information. Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp?rev=277123&r1=277122&r2=277123&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp (original) +++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp Fri Jul 29 01:24:03 2016 @@ -285,9 +285,11 @@ PlatformDarwinKernel::DebuggerInitialize //------------------------------------------------------------------ PlatformDarwinKernel::PlatformDarwinKernel (lldb_private::LazyBool is_ios_debug_session) : PlatformDarwin (false), // This is a remote platform - m_name_to_kext_path_map(), + m_name_to_kext_path_map_with_dsyms(), + m_name_to_kext_path_map_without_dsyms(), m_search_directories(), - m_kernel_binaries(), + m_kernel_binaries_with_dsyms(), + m_kernel_binaries_without_dsyms(), m_ios_debug_session(is_ios_debug_session) { @@ -327,7 +329,10 @@ PlatformDarwinKernel::GetStatus (Stream const FileSpec &kext_dir = m_search_directories[i]; strm.Printf (" Kext directories: [%2u] \"%s\"\n", i, kext_dir.GetPath().c_str()); } - strm.Printf (" Total number of kexts indexed: %d\n", (int) m_name_to_kext_path_map.size()); + strm.Printf (" Number of kexts with dSYMs indexed: %d\n", (int) m_name_to_kext_path_map_with_dsyms.size()); + strm.Printf (" Number of kexts without dSYMs indexed: %d\n", (int) m_name_to_kext_path_map_without_dsyms.size()); + strm.Printf (" Number of Kernel binaries with dSYMs indexed: %d\n", (int) m_kernel_binaries_with_dsyms.size()); + strm.Printf (" Number of Kernel binaries without dSYMs indexed: %d\n", (int) m_kernel_binaries_without_dsyms.size()); } // Populate the m_search_directories vector with directories we should search @@ -703,6 +708,65 @@ PlatformDarwinKernel::GetKextDirectories return FileSpec::eEnumerateDirectoryResultNext; } +// Given a FileSpec of /dir/dir/foo.kext +// Return true if any of these exist: +// /dir/dir/foo.kext.dSYM +// /dir/dir/foo.kext/Contents/MacOS/foo.dSYM +// /dir/dir/foo.kext/foo.dSYM +bool +PlatformDarwinKernel::KextHasdSYMSibling (const FileSpec &kext_bundle_filepath) +{ + FileSpec dsym_fspec = kext_bundle_filepath; + std::string filename = dsym_fspec.GetFilename().AsCString(); + filename += ".dSYM"; + dsym_fspec.GetFilename() = ConstString (filename); + if (dsym_fspec.Exists() && dsym_fspec.IsDirectory()) + { + return true; + } + // Should probably get the CFBundleExecutable here or call CFBundleCopyExecutableURL + + // Look for a deep bundle foramt + ConstString executable_name = kext_bundle_filepath.GetFileNameStrippingExtension(); + std::string deep_bundle_str = kext_bundle_filepath.GetPath() + "/Contents/MacOS/"; + deep_bundle_str += executable_name.AsCString(); + deep_bundle_str += ".dSYM"; + dsym_fspec.SetFile (deep_bundle_str, true); + if (dsym_fspec.Exists() && dsym_fspec.IsDirectory()) + { + return true; + } + + // look for a shallow bundle format + // + std::string shallow_bundle_str = kext_bundle_filepath.GetPath() + "/"; + shallow_bundle_str += executable_name.AsCString(); + shallow_bundle_str += ".dSYM"; + dsym_fspec.SetFile (shallow_bundle_str, true); + if (dsym_fspec.Exists() && dsym_fspec.IsDirectory()) + { + return true; + } + return false; +} + +// Given a FileSpec of /dir/dir/mach.development.t7004 +// Return true if a dSYM exists next to it: +// /dir/dir/mach.development.t7004.dSYM +bool +PlatformDarwinKernel::KernelHasdSYMSibling (const FileSpec &kernel_binary) +{ + FileSpec kernel_dsym = kernel_binary; + std::string filename = kernel_binary.GetFilename().AsCString(); + filename += ".dSYM"; + kernel_dsym.GetFilename() = ConstString (filename); + if (kernel_dsym.Exists() && kernel_dsym.IsDirectory()) + { + return true; + } + return false; +} + void PlatformDarwinKernel::IndexKextsInDirectories () { @@ -735,7 +799,10 @@ PlatformDarwinKernel::IndexKextsInDirect if (CFStringGetCString (bundle_id, bundle_id_buf, sizeof (bundle_id_buf), kCFStringEncodingUTF8)) { ConstString bundle_conststr(bundle_id_buf); - m_name_to_kext_path_map.insert(std::pair<ConstString, FileSpec>(bundle_conststr, kext)); + if (KextHasdSYMSibling (kext)) + m_name_to_kext_path_map_with_dsyms.insert(std::pair<ConstString, FileSpec>(bundle_conststr, kext)); + else + m_name_to_kext_path_map_without_dsyms.insert(std::pair<ConstString, FileSpec>(bundle_conststr, kext)); } } } @@ -806,13 +873,22 @@ PlatformDarwinKernel::IndexKernelsInDire find_files, find_other, GetKernelsInDirectory, - &m_kernel_binaries); + &kernels); + } + + size_t kernels_size = kernels.size(); + for (size_t i = 0; i < kernels_size; i++) + { + if (KernelHasdSYMSibling (kernels[i])) + m_kernel_binaries_with_dsyms.push_back (kernels[i]); + else + m_kernel_binaries_without_dsyms.push_back (kernels[i]); } } // Callback for FileSpec::EnumerateDirectory(). // Step through the entries in a directory like /System/Library/Kernels/, find kernel binaries, -// add them to m_kernel_binaries. +// add them to m_kernel_binaries_with_dsyms and m_kernel_binaries_without_dsyms. // We're only doing a filename match here. We won't try opening the file to see if it's really // a kernel or not until we need to find a kernel of a given UUID. There's no cheap way to find @@ -830,7 +906,6 @@ PlatformDarwinKernel::GetKernelsInDirect if (strncmp (filename.GetCString(), "kernel", 6) == 0 || strncmp (filename.GetCString(), "mach", 4) == 0) { - // This is m_kernel_binaries but we're in a class method here ((std::vector<lldb_private::FileSpec> *)baton)->push_back(file_spec); } } @@ -855,9 +930,27 @@ PlatformDarwinKernel::GetSharedModule (c if (!kext_bundle_id.empty()) { ConstString kext_bundle_cs(kext_bundle_id.c_str()); - if (m_name_to_kext_path_map.count(kext_bundle_cs) > 0) + + // First look through the kext bundles that had a dsym next to them + if (m_name_to_kext_path_map_with_dsyms.count(kext_bundle_cs) > 0) + { + for (BundleIDToKextIterator it = m_name_to_kext_path_map_with_dsyms.begin (); it != m_name_to_kext_path_map_with_dsyms.end (); ++it) + { + if (it->first == kext_bundle_cs) + { + error = ExamineKextForMatchingUUID (it->second, module_spec.GetUUID(), module_spec.GetArchitecture(), module_sp); + if (module_sp.get()) + { + return error; + } + } + } + } + + // Second look through the kext binarys without dSYMs + if (m_name_to_kext_path_map_without_dsyms.count(kext_bundle_cs) > 0) { - for (BundleIDToKextIterator it = m_name_to_kext_path_map.begin (); it != m_name_to_kext_path_map.end (); ++it) + for (BundleIDToKextIterator it = m_name_to_kext_path_map_without_dsyms.begin (); it != m_name_to_kext_path_map_without_dsyms.end (); ++it) { if (it->first == kext_bundle_cs) { @@ -869,11 +962,44 @@ PlatformDarwinKernel::GetSharedModule (c } } } + } if (kext_bundle_id.compare("mach_kernel") == 0 && module_spec.GetUUID().IsValid()) { - for (auto possible_kernel : m_kernel_binaries) + // First try all kernel binaries that have a dSYM next to them + for (auto possible_kernel : m_kernel_binaries_with_dsyms) + { + if (possible_kernel.Exists()) + { + ModuleSpec kern_spec (possible_kernel); + kern_spec.GetUUID() = module_spec.GetUUID(); + ModuleSP module_sp (new Module (kern_spec)); + if (module_sp && module_sp->GetObjectFile() && module_sp->MatchesModuleSpec (kern_spec)) + { + // module_sp is an actual kernel binary we want to add. + if (process) + { + process->GetTarget().GetImages().AppendIfNeeded (module_sp); + error.Clear(); + return error; + } + else + { + error = ModuleList::GetSharedModule (kern_spec, module_sp, NULL, NULL, NULL); + if (module_sp + && module_sp->GetObjectFile() + && module_sp->GetObjectFile()->GetType() != ObjectFile::Type::eTypeCoreFile) + { + return error; + } + module_sp.reset(); + } + } + } + } + // Second try all kernel binaries that don't have a dSYM + for (auto possible_kernel : m_kernel_binaries_without_dsyms) { if (possible_kernel.Exists()) { Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h?rev=277123&r1=277122&r2=277123&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h (original) +++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.h Fri Jul 29 01:24:03 2016 @@ -177,6 +177,14 @@ protected: void SearchSDKsForKextDirectories (std::vector<lldb_private::FileSpec> sdk_dirs, std::vector<lldb_private::FileSpec> &kext_dirs); + // Returns true if there is a .dSYM bundle next to the kext, or next to the binary inside the kext. + bool + KextHasdSYMSibling (const lldb_private::FileSpec &kext_bundle_filepath); + + // Returns true if there is a .dSYM bundle next to the kernel + bool + KernelHasdSYMSibling (const lldb_private::FileSpec &kext_bundle_filepath); + // Search through all of the directories passed in, find all .kext bundles in those directories, // get the CFBundleIDs out of the Info.plists and add the bundle ID and kext path to m_name_to_kext_path_map. void @@ -198,9 +206,11 @@ protected: private: - BundleIDToKextMap m_name_to_kext_path_map; // multimap of CFBundleID to FileSpec on local filesystem + BundleIDToKextMap m_name_to_kext_path_map_with_dsyms; // multimap of CFBundleID to FileSpec on local filesystem, kexts with dSYMs next to them + BundleIDToKextMap m_name_to_kext_path_map_without_dsyms; // multimap of CFBundleID to FileSpec on local filesystem, kexts without dSYMs next to them DirectoriesSearchedCollection m_search_directories; // list of directories we search for kexts/kernels - KernelBinaryCollection m_kernel_binaries; // list of kernel binaries we found on local filesystem + KernelBinaryCollection m_kernel_binaries_with_dsyms; // list of kernel binaries we found on local filesystem, without dSYMs next to them + KernelBinaryCollection m_kernel_binaries_without_dsyms; // list of kernel binaries we found on local filesystem, with dSYMs next to them lldb_private::LazyBool m_ios_debug_session; DISALLOW_COPY_AND_ASSIGN (PlatformDarwinKernel); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits