This is an archive of the discontinued LLVM Phabricator instance.

lld-link: Use /pdbsourcepath: for more places when present.
ClosedPublic

Authored by thakis on Oct 9 2018, 6:49 AM.

Details

Summary

/pdbsourcepath: was added in https://reviews.llvm.org/D48882 to make it
possible to have relative paths in the debug info that clang-cl writes.
lld-link then makes the paths absolute at link time, which debuggers require.
This way, clang-cl's output is independent of the absolute path of the build
directory, which is useful for cacheability in distcc-like systems.

This patch extends /pdbsourcepath: (if passed) to also be used for:

  1. The "cwd" stored in the env block in the pdb is /pdbsourcepath: if present
  2. The "exe" stored in the env block in the pdb is made absolute relative to /pdbsourcepath: instead of the cwd
  3. The "pdb" stored in the env block in the pdb is made absolute relative to /pdbsourcepath: instead of the cwd
  4. For making absolute paths to .obj files referenced from the pdb

/pdbsourcepath: is now useful in three scenarios (the first one already working
before this change):

  1. When building with full debug info, passing the real build dir to /pdbsourcepath: allows having clang-cl's output to be independent of the build directory path. This patch effectively doesn't change behavior for this use case (assuming the cwd is the build dir).
  1. When building without compile-time debug info but linking with /debug, a fake fixed /pdbsourcepath: can be passed to get symbolized stacks while making the pdb and exe independent of the current build dir. For this two work, lld-link needs to be invoked with relative paths for the lld-link invocation itself (for "exe"), for the pdb output name, the exe output name (for "pdb"), and the obj input files, and no absolute path must appear on the link command (for "cmd" in the pdb's env block). Since no full debug info is present, it doesn't matter that the absolute path doesn't exist on disk -- we only get symbols in stacks.
  1. When building production builds with full debug info that don't have local changes, and that get source indexed and their pdbs get uploaded to a symbol server. /pdbsourcepath: again makes the build output independent of the current directory, and the fixed path passed to /pdbsourcepath: can be given the source indexing transform so that it gets mapped to a repository path. This has the same requirements as 2.

This patch also makes it possible to create PDB files containing Windows-style
absolute paths when cross-compiling on a POSIX system.

Diff Detail

Repository
rL LLVM

Event Timeline

thakis created this revision.Oct 9 2018, 6:49 AM
ruiu added inline comments.Oct 9 2018, 7:05 AM
COFF/PDB.cpp
87 ↗(On Diff #168789)

pdbMakeAbsolute

Add static?

88 ↗(On Diff #168789)

You are checking if this variable is empty both in this function and before calling this function. Is that necessary?

92 ↗(On Diff #168789)

I'd flip the condition and return early.

thakis updated this revision to Diff 168797.Oct 9 2018, 7:30 AM
thakis marked 2 inline comments as done.

address comments

thakis added a comment.Oct 9 2018, 7:30 AM

Thanks for the fast review! All done.

COFF/PDB.cpp
87 ↗(On Diff #168789)

Renamed. It was in a unnamed namespace already -- moved it out and down to all the static helper functions and made it static.

88 ↗(On Diff #168789)

I check in one calling place, to maintain the old behavior. For symbols in debug info, we would only prepend /pdbsourcepath: if it was present, but not call make_absolute() if it wasn't and the path was relative; the check before calling maintains that behavior.

I'm guessing changing the behavior for simpler code should be safe though: The only way to get relative symbols in the compiler output is with -Xclang flags which kind of force you to use /pdbsourcepath: to get a functional pdb already. So, done.

Oh, looks like it made a test fail:

FAIL: lld :: COFF/pdb-file-static.test (183 of 1897)
******************** TEST 'lld :: COFF/pdb-file-static.test' FAILED ********************
Script:
--
: 'RUN: at line 1';   /Users/thakis/src/llvm-build-goma/bin/yaml2obj /Users/thakis/src/llvm-rw/tools/lld/test/COFF/Inputs/pdb-file-statics-a.yaml > /Users/thakis/src/llvm-build-goma/tools/lld/test/COFF/Output/pdb-file-static.test.tmp.a.obj
: 'RUN: at line 2';   /Users/thakis/src/llvm-build-goma/bin/yaml2obj /Users/thakis/src/llvm-rw/tools/lld/test/COFF/Inputs/pdb-file-statics-b.yaml > /Users/thakis/src/llvm-build-goma/tools/lld/test/COFF/Output/pdb-file-static.test.tmp.b.obj
: 'RUN: at line 3';   /Users/thakis/src/llvm-build-goma/bin/lld-link /Users/thakis/src/llvm-build-goma/tools/lld/test/COFF/Output/pdb-file-static.test.tmp.a.obj /Users/thakis/src/llvm-build-goma/tools/lld/test/COFF/Output/pdb-file-static.test.tmp.b.obj /nodefaultlib /entry:main /debug /pdb:/Users/thakis/src/llvm-build-goma/tools/lld/test/COFF/Output/pdb-file-static.test.tmp.pdb
: 'RUN: at line 4';   /Users/thakis/src/llvm-build-goma/bin/llvm-pdbutil dump -symbols /Users/thakis/src/llvm-build-goma/tools/lld/test/COFF/Output/pdb-file-static.test.tmp.pdb | /Users/thakis/src/llvm-build-goma/bin/FileCheck /Users/thakis/src/llvm-rw/tools/lld/test/COFF/pdb-file-static.test
--
Exit Code: 1

Command Output (stderr):
--
/Users/thakis/src/llvm-rw/tools/lld/test/COFF/pdb-file-static.test:49:15: error: CHECK-NEXT: expected string not found in input
# CHECK-NEXT: type = 0x0074 (int), file name = 74 (D:\src\llvmbuild\cl\Debug\x64\b.obj), flags = enreg global | enreg static
              ^
<stdin>:103:2: note: scanning from here
 type = 0x0074 (int), file name = 128 (D:\src\llvmbuild\cl\Debug\x64\b.obj), flags = enreg global | enreg static
 ^

--

********************
Testing Time: 21.75s
********************
Failing Tests (1):
    lld :: COFF/pdb-file-static.test

It's because of this:

$ /Users/thakis/src/llvm-build-goma/bin/llvm-pdbutil pdb2yaml -string-table /Users/thakis/src/llvm-build-goma/tools/lld/test/COFF/Output/pdb-file-static.test.tmp.pdb 
---
MSF:             
  SuperBlock:      
    BlockSize:       4096
    FreeBlockMap:    2
    NumBlocks:       20
    NumDirectoryBytes: 128
    Unknown1:        0
    BlockMapAddr:    3
  NumDirectoryBlocks: 1
  DirectoryBlocks: [ 19 ]
  NumStreams:      0
  FileSize:        81920
StringTable:     
  - 'D:\src\llvmbuild\cl\Debug\x64\b.obj'
  - '/Users/thakis/src/llvm-build-goma/tools/lld/test/COFF/d:\src\llvmbuild\cl\debug\x64\b.cpp'
  - 'D:\src\llvmbuild\cl\Debug\x64\a.obj'
  - '/Users/thakis/src/llvm-build-goma/tools/lld/test/COFF/d:\src\llvmbuild\cl\debug\x64\a.cpp'

Note the weird posix/win mixed path. Looks like make_absolute() doesn't have a style parameter. I can mostly work around this by explicitly passing style to is_absolute and checking that first in the function, so did that and added a FIXME.

thakis added inline comments.Oct 9 2018, 7:37 AM
COFF/PDB.cpp
226 ↗(On Diff #168797)

Hm, thinking about this a bit more it's not clear what passing a style to make_absolute() should do I suppose :-) .pdb files should contain Windows paths. PDBs created on a non-Windows host without passing /pdbsourcepath: don't, but it's not clear what else we could do -- cwd on a non-Windows host is a non-Windows base path. Maybe I should update the comment that this is just weird in cross builds and that people should pass /pdbsourcepath: there.

thakis updated this revision to Diff 168798.Oct 9 2018, 7:49 AM

update comments

ruiu added a comment.Oct 9 2018, 10:13 AM

Personally, I found that the way how Go handles pathnames is better than other languages and libraries. In Go, pathname separator is always "/" even on Windows. That means you have to convert from/to native Windows paths by replacing "\" with "/" when you do IO, but having one internal representation makes coding much easier. For example, concatenating a directory name and a filename is as easy as Dir + "/" + Filename; you don't need anything like sys::path::append. Unfortunately, that's not how we handle pathnames in LLVM, though. I'm just saying.

COFF/PDB.cpp
221 ↗(On Diff #168798)

Can you write a justification as a function comment as to why we want to embed a full path to a PDB?

thakis updated this revision to Diff 168828.Oct 9 2018, 10:26 AM

add requested comment

thakis marked an inline comment as done.Oct 9 2018, 10:30 AM
zturner added inline comments.Oct 9 2018, 10:30 AM
COFF/PDB.cpp
226 ↗(On Diff #168797)

Sounds reasonable. Just yesterday for example I uploaded a patch that relies on generating PDBs that contain UNIX paths. So I guess we should remove all Windows-isms from this and other places.

ruiu accepted this revision.Oct 9 2018, 10:43 AM

LGTM

This revision is now accepted and ready to land.Oct 9 2018, 10:43 AM
This revision was automatically updated to reflect the committed changes.