-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Support finding pdb files from outputpath #94153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-lld-coff @llvm/pr-subscribers-lld Author: None (GkvJwa) ChangesFixes #94152 Full diff: https://github.com/llvm/llvm-project/pull/94153.diff 1 Files Affected:
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index 037fae45242c6..01e47dc45fe9a 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -735,8 +735,8 @@ void ObjFile::initializeFlags() {
(cs.Flags & CompileSym3Flags::HotPatch) != CompileSym3Flags::None;
}
if (sym->kind() == SymbolKind::S_OBJNAME) {
- auto objName = cantFail(SymbolDeserializer::deserializeAs<ObjNameSym>(
- sym.get()));
+ auto objName =
+ cantFail(SymbolDeserializer::deserializeAs<ObjNameSym>(sym.get()));
if (objName.Signature)
pchSignature = objName.Signature;
}
@@ -818,11 +818,8 @@ void ObjFile::initializeDependencies() {
debugTypesObj = makeTpiSource(ctx, this);
}
-// Make a PDB path assuming the PDB is in the same folder as the OBJ
-static std::string getPdbBaseName(ObjFile *file, StringRef tSPath) {
- StringRef localPath =
- !file->parentName.empty() ? file->parentName : file->getName();
- SmallString<128> path = sys::path::parent_path(localPath);
+static std::string appendPdbPath(StringRef filePath, StringRef tSPath) {
+ SmallString<128> path = sys::path::parent_path(filePath);
// Currently, type server PDBs are only created by MSVC cl, which only runs
// on Windows, so we can assume type server paths are Windows style.
@@ -831,6 +828,20 @@ static std::string getPdbBaseName(ObjFile *file, StringRef tSPath) {
return std::string(path);
}
+// Make a PDB path assuming the PDB is in the same folder as the OBJ
+static std::string getPdbBaseNameFromObj(ObjFile *file, StringRef tSPath) {
+ StringRef localPath =
+ !file->parentName.empty() ? file->parentName : file->getName();
+
+ return appendPdbPath(localPath, tSPath);
+}
+
+// Make a PDB path assuming the PDB is in the same folder as the OutputFilePath
+static std::string getPdbBaseNameFromOutput(StringRef outputFilePath,
+ StringRef tSPath) {
+ return appendPdbPath(outputFilePath, tSPath);
+}
+
// The casing of the PDB path stamped in the OBJ can differ from the actual path
// on disk. With this, we ensure to always use lowercase as a key for the
// pdbInputFileInstances map, at least on Windows.
@@ -843,15 +854,18 @@ static std::string normalizePdbPath(StringRef path) {
}
// If existing, return the actual PDB path on disk.
-static std::optional<std::string> findPdbPath(StringRef pdbPath,
- ObjFile *dependentFile) {
+static std::optional<std::string>
+findPdbPath(StringRef pdbPath, ObjFile *dependentFile, StringRef outputFile) {
// Ensure the file exists before anything else. In some cases, if the path
// points to a removable device, Driver::enqueuePath() would fail with an
// error (EAGAIN, "resource unavailable try again") which we want to skip
// silently.
if (llvm::sys::fs::exists(pdbPath))
return normalizePdbPath(pdbPath);
- std::string ret = getPdbBaseName(dependentFile, pdbPath);
+ std::string ret = getPdbBaseNameFromObj(dependentFile, pdbPath);
+ if (llvm::sys::fs::exists(ret))
+ return normalizePdbPath(ret);
+ ret = getPdbBaseNameFromOutput(outputFile, pdbPath);
if (llvm::sys::fs::exists(ret))
return normalizePdbPath(ret);
return std::nullopt;
@@ -865,7 +879,7 @@ PDBInputFile::~PDBInputFile() = default;
PDBInputFile *PDBInputFile::findFromRecordPath(const COFFLinkerContext &ctx,
StringRef path,
ObjFile *fromFile) {
- auto p = findPdbPath(path.str(), fromFile);
+ auto p = findPdbPath(path.str(), fromFile, ctx.config.outputFile);
if (!p)
return nullptr;
auto it = ctx.pdbInputFileInstances.find(*p);
@@ -931,7 +945,7 @@ std::optional<DILineInfo> ObjFile::getDILineInfo(uint32_t offset,
}
void ObjFile::enqueuePdbFile(StringRef path, ObjFile *fromFile) {
- auto p = findPdbPath(path.str(), fromFile);
+ auto p = findPdbPath(path.str(), fromFile, ctx.config.outputFile);
if (!p)
return;
auto it = ctx.pdbInputFileInstances.emplace(*p, nullptr);
|
@llvm/pr-subscribers-platform-windows Author: None (GkvJwa) ChangesFixes #94152 Full diff: https://github.com/llvm/llvm-project/pull/94153.diff 1 Files Affected:
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index 037fae45242c6..01e47dc45fe9a 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -735,8 +735,8 @@ void ObjFile::initializeFlags() {
(cs.Flags & CompileSym3Flags::HotPatch) != CompileSym3Flags::None;
}
if (sym->kind() == SymbolKind::S_OBJNAME) {
- auto objName = cantFail(SymbolDeserializer::deserializeAs<ObjNameSym>(
- sym.get()));
+ auto objName =
+ cantFail(SymbolDeserializer::deserializeAs<ObjNameSym>(sym.get()));
if (objName.Signature)
pchSignature = objName.Signature;
}
@@ -818,11 +818,8 @@ void ObjFile::initializeDependencies() {
debugTypesObj = makeTpiSource(ctx, this);
}
-// Make a PDB path assuming the PDB is in the same folder as the OBJ
-static std::string getPdbBaseName(ObjFile *file, StringRef tSPath) {
- StringRef localPath =
- !file->parentName.empty() ? file->parentName : file->getName();
- SmallString<128> path = sys::path::parent_path(localPath);
+static std::string appendPdbPath(StringRef filePath, StringRef tSPath) {
+ SmallString<128> path = sys::path::parent_path(filePath);
// Currently, type server PDBs are only created by MSVC cl, which only runs
// on Windows, so we can assume type server paths are Windows style.
@@ -831,6 +828,20 @@ static std::string getPdbBaseName(ObjFile *file, StringRef tSPath) {
return std::string(path);
}
+// Make a PDB path assuming the PDB is in the same folder as the OBJ
+static std::string getPdbBaseNameFromObj(ObjFile *file, StringRef tSPath) {
+ StringRef localPath =
+ !file->parentName.empty() ? file->parentName : file->getName();
+
+ return appendPdbPath(localPath, tSPath);
+}
+
+// Make a PDB path assuming the PDB is in the same folder as the OutputFilePath
+static std::string getPdbBaseNameFromOutput(StringRef outputFilePath,
+ StringRef tSPath) {
+ return appendPdbPath(outputFilePath, tSPath);
+}
+
// The casing of the PDB path stamped in the OBJ can differ from the actual path
// on disk. With this, we ensure to always use lowercase as a key for the
// pdbInputFileInstances map, at least on Windows.
@@ -843,15 +854,18 @@ static std::string normalizePdbPath(StringRef path) {
}
// If existing, return the actual PDB path on disk.
-static std::optional<std::string> findPdbPath(StringRef pdbPath,
- ObjFile *dependentFile) {
+static std::optional<std::string>
+findPdbPath(StringRef pdbPath, ObjFile *dependentFile, StringRef outputFile) {
// Ensure the file exists before anything else. In some cases, if the path
// points to a removable device, Driver::enqueuePath() would fail with an
// error (EAGAIN, "resource unavailable try again") which we want to skip
// silently.
if (llvm::sys::fs::exists(pdbPath))
return normalizePdbPath(pdbPath);
- std::string ret = getPdbBaseName(dependentFile, pdbPath);
+ std::string ret = getPdbBaseNameFromObj(dependentFile, pdbPath);
+ if (llvm::sys::fs::exists(ret))
+ return normalizePdbPath(ret);
+ ret = getPdbBaseNameFromOutput(outputFile, pdbPath);
if (llvm::sys::fs::exists(ret))
return normalizePdbPath(ret);
return std::nullopt;
@@ -865,7 +879,7 @@ PDBInputFile::~PDBInputFile() = default;
PDBInputFile *PDBInputFile::findFromRecordPath(const COFFLinkerContext &ctx,
StringRef path,
ObjFile *fromFile) {
- auto p = findPdbPath(path.str(), fromFile);
+ auto p = findPdbPath(path.str(), fromFile, ctx.config.outputFile);
if (!p)
return nullptr;
auto it = ctx.pdbInputFileInstances.find(*p);
@@ -931,7 +945,7 @@ std::optional<DILineInfo> ObjFile::getDILineInfo(uint32_t offset,
}
void ObjFile::enqueuePdbFile(StringRef path, ObjFile *fromFile) {
- auto p = findPdbPath(path.str(), fromFile);
+ auto p = findPdbPath(path.str(), fromFile, ctx.config.outputFile);
if (!p)
return;
auto it = ctx.pdbInputFileInstances.emplace(*p, nullptr);
|
Hello @rnk, can you help me review it when you have time |
You are going to have to add a test for this as well. I think it's fine to always match the behaviour of link.exe for things like this. |
Add test(Use the added pdb and obj files to compare before and after) llvm-pdbutil dump -l t.pdb:
|
RUN: yaml2obj %S/Inputs/pdb-type-server-simple-b.yaml -o lib/b.obj | ||
RUN: llvm-pdbutil yaml2pdb %S/Inputs/pdb-type-server-simple-ts.yaml -pdb ts.pdb | ||
|
||
RUN: lld-link lib/a.obj lib/b.obj -debug -entry:main -nodefaultlib -out:t.exe |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you rather extend the other test, pdb-type-server-simple.test
? I think you could just cp
the files where you need them in the %t
folder. Also what you want to check here is the absence of warnings, FileCheck -check-prefix=OUTPUT
and then OUTPUT-NOT: failed to load reference
. The point is that you should run the test without your fix, and make sure it fails first. Then it should suceed with your fix applied.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point is that you should run the test without your fix, and make sure it fails first. Then it should suceed with your fix applied.
Oh, so how to run two different lld-links in the test code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I mean you should revert your code changes from your local git branch, and only keep the test. Compil & run, the test should fail. Then unstash or reapply your code changes, compil & run, the test should now pass.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move to pdb-type-server-simple.test
, use yaml2obj
to generate an additional pdb, which can be modified to cp
if necessary
Use existing checks to compare(the Summary is different)
no such file or directory:
lld-link: Tpi record count: 0
lld-link: Ipi record count: 0
lld-link: warning: Cannot use debug info for 'lib/a.obj' [LNK4099]
>>> failed to load reference 'C:\src\llvm-project\build\ts.pdb': no such file or directory
lld-link: warning: Cannot use debug info for 'lib/b.obj' [LNK4099]
>>> failed to load reference 'C:\src\llvm-project\build\ts.pdb': no such file or directory
Summary
--------------------------------------------------------------------------------
2 Input OBJ files (expanded from all cmd-line inputs)
0 PDB type server dependencies
0 Precomp OBJ dependencies
0 Input type records
0 Input type records bytes
0 Merged TPI records
0 Merged IPI records
1 Output PDB strings
0 Global symbol records
0 Module symbol records
2 Public symbol records
find pdb:
lld-link: Tpi record count: 9
lld-link: Ipi record count: 16
Summary
--------------------------------------------------------------------------------
2 Input OBJ files (expanded from all cmd-line inputs)
1 PDB type server dependencies
0 Precomp OBJ dependencies
25 Input type records
868 Input type records bytes
9 Merged TPI records
16 Merged IPI records
3 Output PDB strings
4 Global symbol records
14 Module symbol records
2 Public symbol records
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you rather leave the existing test unmodified and add another block after to run your test? I think you could create a %t2 folder and %t2/lib and cp the .obj and the .pdb files from the previous step? Then add another line with lld-link ...
and FileCheck -check-prefix=OUTPUT
and then OUTPUT-NOT: failed to load reference
. You can take inspiration from other tests, such as pdb-natvis.test
. Except that in your case you could pack all these steps together (mkdir(s), cp, lld-link and the OUTPUT line)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As suggested by comments, I made changes and reviewed again
Apart from that, code changes look good, thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks again! Let's give it few days before merging, in case anyone has any further comments.
Thank you for your help, too |
Hello, can you help me merge it recently |
Merged, thanks! |
Fixes #94152