[Lldb-commits] [lldb] 38ddb49 - [lldb/Reproducers] Always collect the whole dSYM in the reproducer
Jonas Devlieghere via lldb-commits
lldb-commits at lists.llvm.org
Mon Mar 30 15:17:04 PDT 2020
Author: Jonas Devlieghere
Date: 2020-03-30T15:16:50-07:00
New Revision: 38ddb49e5242920e44a982cff7bbe2e86bd23a69
URL: https://github.com/llvm/llvm-project/commit/38ddb49e5242920e44a982cff7bbe2e86bd23a69
DIFF: https://github.com/llvm/llvm-project/commit/38ddb49e5242920e44a982cff7bbe2e86bd23a69.diff
LOG: [lldb/Reproducers] Always collect the whole dSYM in the reproducer
The FileCollector in LLDB collects every files that's used during a
debug session when capture is enabled. This ensures that the reproducer
only contains the files necessary to reproduce. This approach is not a
good fit for the dSYM bundle, which is a directory on disk, but should
be treated as a single unit.
On macOS LLDB have automatically find the matching dSYM for a binary by
its UUID. Having a incomplete dSYM in a reproducer can break debugging
even when reproducers are disabled.
This patch adds a was to specify a directory of interest to the
reproducers. It is called from SymbolVendorMacOSX with the path of the
dSYMs used by LLDB.
Differential revision: https://reviews.llvm.org/D76672
Added:
lldb/test/Shell/Reproducer/TestDSYM.test
Modified:
lldb/include/lldb/Utility/Reproducer.h
lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
lldb/source/Utility/Reproducer.cpp
Removed:
################################################################################
diff --git a/lldb/include/lldb/Utility/Reproducer.h b/lldb/include/lldb/Utility/Reproducer.h
index bffb0f7c0647..b8b897d02ea2 100644
--- a/lldb/include/lldb/Utility/Reproducer.h
+++ b/lldb/include/lldb/Utility/Reproducer.h
@@ -98,6 +98,8 @@ class FileProvider : public Provider<FileProvider> {
return m_collector;
}
+ void recordInterestingDirectory(const llvm::Twine &dir);
+
void Keep() override {
auto mapping = GetRoot().CopyByAppendingPathComponent(Info::file);
// Temporary files that are removed during execution can cause copy errors.
diff --git a/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp b/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
index 2b67fee70617..e819c342c6ec 100644
--- a/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
+++ b/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
@@ -20,6 +20,7 @@
#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/Reproducer.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
@@ -145,6 +146,11 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
}
if (dsym_fspec) {
+ // Compute dSYM root.
+ std::string dsym_root = dsym_fspec.GetPath();
+ const size_t pos = dsym_root.find("/Contents/Resources/");
+ dsym_root = pos != std::string::npos ? dsym_root.substr(0, pos) : "";
+
DataBufferSP dsym_file_data_sp;
lldb::offset_t dsym_file_data_offset = 0;
dsym_objfile_sp =
@@ -154,136 +160,132 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
if (UUIDsMatch(module_sp.get(), dsym_objfile_sp.get(), feedback_strm)) {
// We need a XML parser if we hope to parse a plist...
if (XMLDocument::XMLEnabled()) {
- char dsym_path[PATH_MAX];
- if (module_sp->GetSourceMappingList().IsEmpty() &&
- dsym_fspec.GetPath(dsym_path, sizeof(dsym_path))) {
+ if (module_sp->GetSourceMappingList().IsEmpty()) {
lldb_private::UUID dsym_uuid = dsym_objfile_sp->GetUUID();
if (dsym_uuid) {
std::string uuid_str = dsym_uuid.GetAsString();
- if (!uuid_str.empty()) {
- char *resources = strstr(dsym_path, "/Contents/Resources/");
- if (resources) {
- char dsym_uuid_plist_path[PATH_MAX];
- resources[strlen("/Contents/Resources/")] = '\0';
- snprintf(dsym_uuid_plist_path, sizeof(dsym_uuid_plist_path),
- "%s%s.plist", dsym_path, uuid_str.c_str());
- FileSpec dsym_uuid_plist_spec(dsym_uuid_plist_path);
- if (FileSystem::Instance().Exists(dsym_uuid_plist_spec)) {
- ApplePropertyList plist(dsym_uuid_plist_path);
- if (plist) {
- std::string DBGBuildSourcePath;
- std::string DBGSourcePath;
-
- // DBGSourcePathRemapping is a dictionary in the plist
- // with keys which are DBGBuildSourcePath file paths and
- // values which are DBGSourcePath file paths
-
- StructuredData::ObjectSP plist_sp =
- plist.GetStructuredData();
- if (plist_sp.get() && plist_sp->GetAsDictionary() &&
- plist_sp->GetAsDictionary()->HasKey(
- "DBGSourcePathRemapping") &&
- plist_sp->GetAsDictionary()
- ->GetValueForKey("DBGSourcePathRemapping")
- ->GetAsDictionary()) {
-
- // If DBGVersion 1 or DBGVersion missing, ignore DBGSourcePathRemapping.
- // If DBGVersion 2, strip last two components of path remappings from
- // entries to fix an issue with a specific set of
- // DBGSourcePathRemapping entries that lldb worked
- // with.
- // If DBGVersion 3, trust & use the source path remappings as-is.
- //
-
- bool new_style_source_remapping_dictionary = false;
- bool do_truncate_remapping_names = false;
- std::string original_DBGSourcePath_value =
- DBGSourcePath;
- if (plist_sp->GetAsDictionary()->HasKey("DBGVersion")) {
- std::string version_string =
- std::string(plist_sp->GetAsDictionary()
- ->GetValueForKey("DBGVersion")
- ->GetStringValue(""));
- if (!version_string.empty() &&
- isdigit(version_string[0])) {
- int version_number = atoi(version_string.c_str());
- if (version_number > 1) {
- new_style_source_remapping_dictionary = true;
- }
- if (version_number == 2) {
- do_truncate_remapping_names = true;
- }
+ if (!uuid_str.empty() && !dsym_root.empty()) {
+ char dsym_uuid_plist_path[PATH_MAX];
+ snprintf(dsym_uuid_plist_path, sizeof(dsym_uuid_plist_path),
+ "%s/Contents/Resources/%s.plist", dsym_root.c_str(),
+ uuid_str.c_str());
+ FileSpec dsym_uuid_plist_spec(dsym_uuid_plist_path);
+ if (FileSystem::Instance().Exists(dsym_uuid_plist_spec)) {
+ ApplePropertyList plist(dsym_uuid_plist_path);
+ if (plist) {
+ std::string DBGBuildSourcePath;
+ std::string DBGSourcePath;
+
+ // DBGSourcePathRemapping is a dictionary in the plist
+ // with keys which are DBGBuildSourcePath file paths and
+ // values which are DBGSourcePath file paths
+
+ StructuredData::ObjectSP plist_sp =
+ plist.GetStructuredData();
+ if (plist_sp.get() && plist_sp->GetAsDictionary() &&
+ plist_sp->GetAsDictionary()->HasKey(
+ "DBGSourcePathRemapping") &&
+ plist_sp->GetAsDictionary()
+ ->GetValueForKey("DBGSourcePathRemapping")
+ ->GetAsDictionary()) {
+
+ // If DBGVersion 1 or DBGVersion missing, ignore
+ // DBGSourcePathRemapping. If DBGVersion 2, strip last two
+ // components of path remappings from
+ // entries to fix an issue with a
+ // specific set of DBGSourcePathRemapping
+ // entries that lldb worked with.
+ // If DBGVersion 3, trust & use the source path remappings
+ // as-is.
+ //
+
+ bool new_style_source_remapping_dictionary = false;
+ bool do_truncate_remapping_names = false;
+ std::string original_DBGSourcePath_value = DBGSourcePath;
+ if (plist_sp->GetAsDictionary()->HasKey("DBGVersion")) {
+ std::string version_string =
+ std::string(plist_sp->GetAsDictionary()
+ ->GetValueForKey("DBGVersion")
+ ->GetStringValue(""));
+ if (!version_string.empty() &&
+ isdigit(version_string[0])) {
+ int version_number = atoi(version_string.c_str());
+ if (version_number > 1) {
+ new_style_source_remapping_dictionary = true;
+ }
+ if (version_number == 2) {
+ do_truncate_remapping_names = true;
}
}
+ }
- StructuredData::Dictionary *remappings_dict =
- plist_sp->GetAsDictionary()
- ->GetValueForKey("DBGSourcePathRemapping")
- ->GetAsDictionary();
- remappings_dict->ForEach(
- [&module_sp, new_style_source_remapping_dictionary,
- original_DBGSourcePath_value, do_truncate_remapping_names](
- ConstString key,
- StructuredData::Object *object) -> bool {
- if (object && object->GetAsString()) {
-
- // key is DBGBuildSourcePath
- // object is DBGSourcePath
- std::string DBGSourcePath =
- std::string(object->GetStringValue());
- if (!new_style_source_remapping_dictionary &&
- !original_DBGSourcePath_value.empty()) {
- DBGSourcePath = original_DBGSourcePath_value;
- }
- if (DBGSourcePath[0] == '~') {
- FileSpec resolved_source_path(
- DBGSourcePath.c_str());
- FileSystem::Instance().Resolve(
- resolved_source_path);
- DBGSourcePath =
- resolved_source_path.GetPath();
- }
+ StructuredData::Dictionary *remappings_dict =
+ plist_sp->GetAsDictionary()
+ ->GetValueForKey("DBGSourcePathRemapping")
+ ->GetAsDictionary();
+ remappings_dict->ForEach(
+ [&module_sp, new_style_source_remapping_dictionary,
+ original_DBGSourcePath_value,
+ do_truncate_remapping_names](
+ ConstString key,
+ StructuredData::Object *object) -> bool {
+ if (object && object->GetAsString()) {
+
+ // key is DBGBuildSourcePath
+ // object is DBGSourcePath
+ std::string DBGSourcePath =
+ std::string(object->GetStringValue());
+ if (!new_style_source_remapping_dictionary &&
+ !original_DBGSourcePath_value.empty()) {
+ DBGSourcePath = original_DBGSourcePath_value;
+ }
+ if (DBGSourcePath[0] == '~') {
+ FileSpec resolved_source_path(
+ DBGSourcePath.c_str());
+ FileSystem::Instance().Resolve(
+ resolved_source_path);
+ DBGSourcePath = resolved_source_path.GetPath();
+ }
+ module_sp->GetSourceMappingList().Append(
+ key, ConstString(DBGSourcePath), true);
+ // With version 2 of DBGSourcePathRemapping, we
+ // can chop off the last two filename parts
+ // from the source remapping and get a more
+ // general source remapping that still works.
+ // Add this as another option in addition to
+ // the full source path remap.
+ if (do_truncate_remapping_names) {
+ FileSpec build_path(key.AsCString());
+ FileSpec source_path(DBGSourcePath.c_str());
+ build_path.RemoveLastPathComponent();
+ build_path.RemoveLastPathComponent();
+ source_path.RemoveLastPathComponent();
+ source_path.RemoveLastPathComponent();
module_sp->GetSourceMappingList().Append(
- key, ConstString(DBGSourcePath), true);
- // With version 2 of DBGSourcePathRemapping, we
- // can chop off the last two filename parts
- // from the source remapping and get a more
- // general source remapping that still works.
- // Add this as another option in addition to
- // the full source path remap.
- if (do_truncate_remapping_names) {
- FileSpec build_path(key.AsCString());
- FileSpec source_path(DBGSourcePath.c_str());
- build_path.RemoveLastPathComponent();
- build_path.RemoveLastPathComponent();
- source_path.RemoveLastPathComponent();
- source_path.RemoveLastPathComponent();
- module_sp->GetSourceMappingList().Append(
- ConstString(build_path.GetPath().c_str()),
- ConstString(source_path.GetPath().c_str()), true);
- }
+ ConstString(build_path.GetPath().c_str()),
+ ConstString(source_path.GetPath().c_str()),
+ true);
}
- return true;
- });
- }
+ }
+ return true;
+ });
+ }
- // If we have a DBGBuildSourcePath + DBGSourcePath pair,
- // append those to the source path remappings.
-
- plist.GetValueAsString("DBGBuildSourcePath",
- DBGBuildSourcePath);
- plist.GetValueAsString("DBGSourcePath", DBGSourcePath);
- if (!DBGBuildSourcePath.empty() &&
- !DBGSourcePath.empty()) {
- if (DBGSourcePath[0] == '~') {
- FileSpec resolved_source_path(DBGSourcePath.c_str());
- FileSystem::Instance().Resolve(resolved_source_path);
- DBGSourcePath = resolved_source_path.GetPath();
- }
- module_sp->GetSourceMappingList().Append(
- ConstString(DBGBuildSourcePath),
- ConstString(DBGSourcePath), true);
+ // If we have a DBGBuildSourcePath + DBGSourcePath pair,
+ // append those to the source path remappings.
+
+ plist.GetValueAsString("DBGBuildSourcePath",
+ DBGBuildSourcePath);
+ plist.GetValueAsString("DBGSourcePath", DBGSourcePath);
+ if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
+ if (DBGSourcePath[0] == '~') {
+ FileSpec resolved_source_path(DBGSourcePath.c_str());
+ FileSystem::Instance().Resolve(resolved_source_path);
+ DBGSourcePath = resolved_source_path.GetPath();
}
+ module_sp->GetSourceMappingList().Append(
+ ConstString(DBGBuildSourcePath),
+ ConstString(DBGSourcePath), true);
}
}
}
@@ -293,6 +295,11 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
}
symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
+ if (repro::Generator *g =
+ repro::Reproducer::Instance().GetGenerator()) {
+ repro::FileProvider &fp = g->GetOrCreate<repro::FileProvider>();
+ fp.recordInterestingDirectory(dsym_root);
+ }
return symbol_vendor;
}
}
diff --git a/lldb/source/Utility/Reproducer.cpp b/lldb/source/Utility/Reproducer.cpp
index 8daa3216f7b1..bbf399e599bf 100644
--- a/lldb/source/Utility/Reproducer.cpp
+++ b/lldb/source/Utility/Reproducer.cpp
@@ -321,6 +321,11 @@ void WorkingDirectoryProvider::Keep() {
os << m_cwd << "\n";
}
+void FileProvider::recordInterestingDirectory(const llvm::Twine &dir) {
+ if (m_collector)
+ m_collector->addDirectory(dir);
+}
+
void ProviderBase::anchor() {}
char CommandProvider::ID = 0;
char FileProvider::ID = 0;
diff --git a/lldb/test/Shell/Reproducer/TestDSYM.test b/lldb/test/Shell/Reproducer/TestDSYM.test
new file mode 100644
index 000000000000..bddacda3242f
--- /dev/null
+++ b/lldb/test/Shell/Reproducer/TestDSYM.test
@@ -0,0 +1,11 @@
+# REQUIRES: system-darwin
+# Ensure that the reproducers captures the whole dSYM bundle.
+
+# RUN: rm -rf %t.repro
+# RUN: %clang_host %S/Inputs/simple.c -g -o %t.out
+# RUN: touch %t.out.dSYM/foo.bar
+
+# RUN: %lldb -x -b --capture --capture-path %t.repro %t.out -o 'b main' -o 'run' -o 'reproducer generate'
+
+# RUN: %lldb -b -o 'reproducer dump -p files -f %t.repro' | FileCheck %s --check-prefix FILES
+# FILES: foo.bar
More information about the lldb-commits
mailing list