Skip to content

Commit 27df2d9

Browse files
committed
[lldb] Don't process symlinks deep inside DWARFUnit
Summary: This code is handling debug info paths starting with /proc/self/cwd, which is one of the mechanisms people use to obtain "relocatable" debug info (the idea being that one starts the debugger with an appropriate cwd and things "just work"). Instead of resolving the symlinks inside DWARFUnit, we can do the same thing more elegantly by hooking into the existing Module path remapping code. Since llvm::DWARFUnit does not support any similar functionality, doing things this way is also a step towards unifying llvm and lldb dwarf parsers. Reviewers: JDevlieghere, aprantl, clayborg, jdoerfert Subscribers: lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D71770
1 parent 9a3ff47 commit 27df2d9

File tree

11 files changed

+54
-56
lines changed

11 files changed

+54
-56
lines changed

lldb/include/lldb/Core/Module.h

+5-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define liblldb_Module_h_
1111

1212
#include "lldb/Core/Address.h"
13+
#include "lldb/Core/ModuleList.h"
1314
#include "lldb/Core/ModuleSpec.h"
1415
#include "lldb/Symbol/ObjectFile.h"
1516
#include "lldb/Symbol/SymbolContextScope.h"
@@ -966,10 +967,10 @@ class Module : public std::enable_shared_from_this<Module>,
966967
///references to them
967968
TypeSystemMap m_type_system_map; ///< A map of any type systems associated
968969
///with this module
969-
PathMappingList m_source_mappings; ///< Module specific source remappings for
970-
///when you have debug info for a module
971-
///that doesn't match where the sources
972-
///currently are
970+
/// Module specific source remappings for when you have debug info for a
971+
/// module that doesn't match where the sources currently are.
972+
PathMappingList m_source_mappings =
973+
ModuleList::GetGlobalModuleListProperties().GetSymlinkMappings();
973974
lldb::SectionListUP m_sections_up; ///< Unified section list for module that
974975
/// is used by the ObjectFile and and
975976
/// ObjectFile instances for the debug info

lldb/include/lldb/Core/ModuleList.h

+8
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "lldb/lldb-types.h"
2121

2222
#include "llvm/ADT/DenseSet.h"
23+
#include "llvm/Support/RWMutex.h"
2324

2425
#include <functional>
2526
#include <list>
@@ -46,13 +47,20 @@ class UUID;
4647
class VariableList;
4748

4849
class ModuleListProperties : public Properties {
50+
mutable llvm::sys::RWMutex m_symlink_paths_mutex;
51+
PathMappingList m_symlink_paths;
52+
53+
void UpdateSymlinkMappings();
54+
4955
public:
5056
ModuleListProperties();
5157

5258
FileSpec GetClangModulesCachePath() const;
5359
bool SetClangModulesCachePath(llvm::StringRef path);
5460
bool GetEnableExternalLookup() const;
5561
bool SetEnableExternalLookup(bool new_value);
62+
63+
PathMappingList GetSymlinkMappings() const;
5664
};
5765

5866
/// \class ModuleList ModuleList.h "lldb/Core/ModuleList.h"

lldb/packages/Python/lldbsuite/test/functionalities/breakpoint/comp_dir_symlink/TestCompDirSymLink.py

+9-12
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
_EXE_NAME = 'CompDirSymLink' # Must match Makefile
1414
_SRC_FILE = 'relative.cpp'
15-
_COMP_DIR_SYM_LINK_PROP = 'plugin.symbol-file.dwarf.comp-dir-symlink-paths'
15+
_COMP_DIR_SYM_LINK_PROP = 'symbols.debug-info-symlink-paths'
1616

1717

1818
class CompDirSymLinkTestCase(TestBase):
@@ -30,21 +30,15 @@ def setUp(self):
3030
@skipIf(hostoslist=["windows"])
3131
def test_symlink_paths_set(self):
3232
pwd_symlink = self.create_src_symlink()
33-
self.doBuild(pwd_symlink)
34-
self.runCmd(
35-
"settings set %s %s" %
36-
(_COMP_DIR_SYM_LINK_PROP, pwd_symlink))
33+
self.doBuild(pwd_symlink, pwd_symlink)
3734
src_path = self.getBuildArtifact(_SRC_FILE)
3835
lldbutil.run_break_set_by_file_and_line(self, src_path, self.line)
3936

4037
@skipIf(hostoslist=no_match(["linux"]))
4138
def test_symlink_paths_set_procselfcwd(self):
4239
os.chdir(self.getBuildDir())
4340
pwd_symlink = '/proc/self/cwd'
44-
self.doBuild(pwd_symlink)
45-
self.runCmd(
46-
"settings set %s %s" %
47-
(_COMP_DIR_SYM_LINK_PROP, pwd_symlink))
41+
self.doBuild(pwd_symlink, pwd_symlink)
4842
src_path = self.getBuildArtifact(_SRC_FILE)
4943
# /proc/self/cwd points to a realpath form of current directory.
5044
src_path = os.path.realpath(src_path)
@@ -53,8 +47,7 @@ def test_symlink_paths_set_procselfcwd(self):
5347
@skipIf(hostoslist=["windows"])
5448
def test_symlink_paths_unset(self):
5549
pwd_symlink = self.create_src_symlink()
56-
self.doBuild(pwd_symlink)
57-
self.runCmd('settings clear ' + _COMP_DIR_SYM_LINK_PROP)
50+
self.doBuild(pwd_symlink, "")
5851
src_path = self.getBuildArtifact(_SRC_FILE)
5952
self.assertRaises(
6053
AssertionError,
@@ -71,8 +64,12 @@ def create_src_symlink(self):
7164
self.addTearDownHook(lambda: os.remove(pwd_symlink))
7265
return pwd_symlink
7366

74-
def doBuild(self, pwd_symlink):
67+
def doBuild(self, pwd_symlink, setting_value):
7568
self.build(None, None, {'PWD': pwd_symlink})
7669

70+
self.runCmd(
71+
"settings set %s '%s'" %
72+
(_COMP_DIR_SYM_LINK_PROP, setting_value))
73+
7774
exe = self.getBuildArtifact(_EXE_NAME)
7875
self.runCmd('file ' + exe, CURRENT_EXECUTABLE_SET)

lldb/source/Core/CoreProperties.td

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ let Definition = "modulelist" in {
99
Global,
1010
DefaultStringValue<"">,
1111
Desc<"The path to the clang modules cache directory (-fmodules-cache-path).">;
12+
def SymLinkPaths: Property<"debug-info-symlink-paths", "FileSpecList">,
13+
Global,
14+
DefaultStringValue<"">,
15+
Desc<"Debug info path which should be resolved while parsing, relative to the host filesystem.">;
1216
}
1317

1418
let Definition = "debugger" in {

lldb/source/Core/ModuleList.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "lldb/Core/ModuleSpec.h"
1313
#include "lldb/Host/FileSystem.h"
1414
#include "lldb/Interpreter/OptionValueFileSpec.h"
15+
#include "lldb/Interpreter/OptionValueFileSpecList.h"
1516
#include "lldb/Interpreter/OptionValueProperties.h"
1617
#include "lldb/Interpreter/Property.h"
1718
#include "lldb/Symbol/LocateSymbolFile.h"
@@ -77,6 +78,8 @@ ModuleListProperties::ModuleListProperties() {
7778
m_collection_sp =
7879
std::make_shared<OptionValueProperties>(ConstString("symbols"));
7980
m_collection_sp->Initialize(g_modulelist_properties);
81+
m_collection_sp->SetValueChangedCallback(ePropertySymLinkPaths,
82+
[this] { UpdateSymlinkMappings(); });
8083

8184
llvm::SmallString<128> path;
8285
clang::driver::Driver::getDefaultModuleCachePath(path);
@@ -106,6 +109,28 @@ bool ModuleListProperties::SetClangModulesCachePath(llvm::StringRef path) {
106109
nullptr, ePropertyClangModulesCachePath, path);
107110
}
108111

112+
void ModuleListProperties::UpdateSymlinkMappings() {
113+
FileSpecList list = m_collection_sp
114+
->GetPropertyAtIndexAsOptionValueFileSpecList(
115+
nullptr, false, ePropertySymLinkPaths)
116+
->GetCurrentValue();
117+
llvm::sys::ScopedWriter lock(m_symlink_paths_mutex);
118+
const bool notify = false;
119+
m_symlink_paths.Clear(notify);
120+
for (FileSpec symlink : list) {
121+
FileSpec resolved;
122+
Status status = FileSystem::Instance().Readlink(symlink, resolved);
123+
if (status.Success())
124+
m_symlink_paths.Append(ConstString(symlink.GetPath()),
125+
ConstString(resolved.GetPath()), notify);
126+
}
127+
}
128+
129+
PathMappingList ModuleListProperties::GetSymlinkMappings() const {
130+
llvm::sys::ScopedReader lock(m_symlink_paths_mutex);
131+
return m_symlink_paths;
132+
}
133+
109134
ModuleList::ModuleList()
110135
: m_modules(), m_modules_mutex(), m_notifier(nullptr) {}
111136

lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ static void SetupModuleHeaderPaths(CompilerInstance *compiler,
253253
}
254254

255255
llvm::SmallString<128> module_cache;
256-
auto props = ModuleList::GetGlobalModuleListProperties();
256+
const auto &props = ModuleList::GetGlobalModuleListProperties();
257257
props.GetClangModulesCachePath().GetPath(module_cache);
258258
search_opts.ModuleCachePath = module_cache.str();
259259
LLDB_LOG(log, "Using module cache path: {0}", module_cache.c_str());

lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ ClangModulesDeclVendor::Create(Target &target) {
601601

602602
{
603603
llvm::SmallString<128> path;
604-
auto props = ModuleList::GetGlobalModuleListProperties();
604+
const auto &props = ModuleList::GetGlobalModuleListProperties();
605605
props.GetClangModulesCachePath().GetPath(path);
606606
std::string module_cache_argument("-fmodules-cache-path=");
607607
module_cache_argument.append(path.str());

lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp

+1-20
Original file line numberDiff line numberDiff line change
@@ -738,25 +738,6 @@ removeHostnameFromPathname(llvm::StringRef path_from_dwarf) {
738738
return path;
739739
}
740740

741-
static FileSpec resolveCompDir(const FileSpec &path) {
742-
bool is_symlink = SymbolFileDWARF::GetSymlinkPaths().FindFileIndex(
743-
0, path, /*full*/ true) != UINT32_MAX;
744-
745-
if (!is_symlink)
746-
return path;
747-
748-
namespace fs = llvm::sys::fs;
749-
if (fs::get_file_type(path.GetPath(), false) != fs::file_type::symlink_file)
750-
return path;
751-
752-
FileSpec resolved_symlink;
753-
const auto error = FileSystem::Instance().Readlink(path, resolved_symlink);
754-
if (error.Success())
755-
return resolved_symlink;
756-
757-
return path;
758-
}
759-
760741
void DWARFUnit::ComputeCompDirAndGuessPathStyle() {
761742
m_comp_dir = FileSpec();
762743
const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
@@ -768,7 +749,7 @@ void DWARFUnit::ComputeCompDirAndGuessPathStyle() {
768749
if (!comp_dir.empty()) {
769750
FileSpec::Style comp_dir_style =
770751
FileSpec::GuessPathStyle(comp_dir).getValueOr(FileSpec::Style::native);
771-
m_comp_dir = resolveCompDir(FileSpec(comp_dir, comp_dir_style));
752+
m_comp_dir = FileSpec(comp_dir, comp_dir_style);
772753
} else {
773754
// Try to detect the style based on the DW_AT_name attribute, but just store
774755
// the detected style in the m_comp_dir field.

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

-12
Original file line numberDiff line numberDiff line change
@@ -135,14 +135,6 @@ class PluginProperties : public Properties {
135135
m_collection_sp->Initialize(g_symbolfiledwarf_properties);
136136
}
137137

138-
FileSpecList GetSymLinkPaths() {
139-
const OptionValueFileSpecList *option_value =
140-
m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(
141-
nullptr, true, ePropertySymLinkPaths);
142-
assert(option_value);
143-
return option_value->GetCurrentValue();
144-
}
145-
146138
bool IgnoreFileIndexes() const {
147139
return m_collection_sp->GetPropertyAtIndexAsBoolean(
148140
nullptr, ePropertyIgnoreIndexes, false);
@@ -227,10 +219,6 @@ ParseSupportFilesFromPrologue(const lldb::ModuleSP &module,
227219
return support_files;
228220
}
229221

230-
FileSpecList SymbolFileDWARF::GetSymlinkPaths() {
231-
return GetGlobalPluginProperties()->GetSymLinkPaths();
232-
}
233-
234222
void SymbolFileDWARF::Initialize() {
235223
LogChannelDWARF::Initialize();
236224
PluginManager::RegisterPlugin(GetPluginNameStatic(),

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h

-2
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,6 @@ class SymbolFileDWARF : public lldb_private::SymbolFile,
9090
static lldb_private::SymbolFile *
9191
CreateInstance(lldb::ObjectFileSP objfile_sp);
9292

93-
static lldb_private::FileSpecList GetSymlinkPaths();
94-
9593
// Constructors and Destructors
9694

9795
SymbolFileDWARF(lldb::ObjectFileSP objfile_sp,

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFProperties.td

-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
include "../../../../include/lldb/Core/PropertiesBase.td"
22

33
let Definition = "symbolfiledwarf" in {
4-
def SymLinkPaths: Property<"comp-dir-symlink-paths", "FileSpecList">,
5-
Global,
6-
DefaultStringValue<"">,
7-
Desc<"If the DW_AT_comp_dir matches any of these paths the symbolic links will be resolved at DWARF parse time.">;
84
def IgnoreIndexes: Property<"ignore-file-indexes", "Boolean">,
95
Global,
106
DefaultFalse,

0 commit comments

Comments
 (0)