Skip to content
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

[SR-15267] -debug-prefix-map incorrectly maps a path #57589

Closed
swift-ci opened this issue Oct 1, 2021 · 6 comments
Closed

[SR-15267] -debug-prefix-map incorrectly maps a path #57589

swift-ci opened this issue Oct 1, 2021 · 6 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Oct 1, 2021

Previous ID SR-15267
Radar None
Original Reporter qyang (JIRA User)
Type Bug
Status Closed
Resolution Done
Environment

Xcode 13, Swift 5.5

Additional Detail from JIRA
Votes 2
Component/s Compiler
Labels Bug
Assignee @keith
Priority Medium

md5: 7304f0d90e95e19cdda106e650400afb

Issue Description:

The swift compiler flag `-debug-prefix-map` incorrectly maps a path when the working directory is different than the to-be-mapped path.

Here are steps to repro the problem.

$ mkdir -p ios/Sources
$ echo "func foo() {}" > ios/Sources/foo.swift
$ cd ios/Sources
$ pwd 
/Users/qingyang/Projects/ios/Sources
$ xcrun swiftc -c -g -o foo.o -debug-prefix-map /Users/qingyang/Projects=. /Users/qingyang/Projects/ios/Sources/foo.swift
$  dwarfdump foo.o | grep foo.swift
DW_AT_name  ("./ios/Sources/foo.swift")
DW_AT_decl_file ("./ios/Sources/./ios/Sources/foo.swift")
DW_AT_decl_file ("./ios/Sources/ios/Sources/foo.swift")

The paths in `DW_AT_decl_file` are clearly wrong. This causes breakpoints won't be hit even with `target.source-map` set.

In above example, the working directory is `/Users/qingyang/Projects/ios/Sources` while the to-be-mapped path is `/Users/qingyang/Projects`. In a real case scenario, we want to map the repo root and Xcode always cd into $SRCROOT of each projects to compile, which makes those two paths different.

This problem is new to Swift 5.5. Swift 5.4 behaves the same 🙁

@swift-ci
Copy link
Collaborator Author

swift-ci commented Oct 4, 2021

Comment by Qing Yang (JIRA)

This bug involves using absolute path of the source file and mapping to dot (".").

# Using relative source file path works as expected.
$ xcrun swiftc -c -g -o foo.o foo.swift -debug-prefix-map /Users/qingyang/Projects=.
$ dwarfdump foo.o | grep foo.swift
DW_AT_name ("foo.swift")
DW_AT_decl_file ("./ios/Sources/foo.swift")                  
DW_AT_decl_file ("./ios/Sources/foo.swift")

# Mapping to another absolute path also works as expected.
$ xcrun swiftc -c -g -o foo.o /Users/qingyang/Projects/ios/Sources/foo.swift -debug-prefix-map /Users/qingyang/Projects=/something
$ dwarfdump foo.o | grep foo.swift
DW_AT_name ("/something/ios/Sources/foo.swift")
DW_AT_decl_file ("/something/ios/Sources/foo.swift")
DW_AT_decl_file ("/something/ios/Sources/foo.swift")

@keith
Copy link
Collaborator

keith commented Oct 4, 2021

Clang also exhibits this behavior

@keith
Copy link
Collaborator

keith commented Oct 5, 2021

I debugged this a bit and it appears swift contains a mostly copy pasted block of code from clang that causes the issue:

std::string RemappedFileString = DebugPrefixMap.remapPath(FileName);
SmallString<128> RemappedFile = StringRef(RemappedFileString);
llvm::sys::path::remove_dots(RemappedFile);
std::string CurDir = DebugPrefixMap.remapPath(Opts.DebugCompilationDir);

https://github.com/llvm/llvm-project/blob/e420164f40a907643db40e65fff51a6041d40090/clang/lib/CodeGen/CGDebugInfo.cpp

The issue here is in the case where you remap a path to another absolute path everything is fine, because you hit the if statement that removes the shared components from the directory, but in the else case, when the remapped file path results in a relative path, both the remapped directory path, as well as the remapped file path are used literally, and the shared path component is not removed. This results in the llvm IR having:

!DIFile(filename: "./ios/Sources/bar.c", directory: "./ios/Sources")

when it should be:

!DIFile(filename: "bar.c", directory: "./ios/Sources")

The logic for the fix isn't super clear to me, I don't think you can safely remove shared components after the paths are relative since technically they might be able to refer to different directories with the same name?

@keith
Copy link
Collaborator

keith commented Oct 7, 2021

Here's a potential clang change https://reviews.llvm.org/D111352

@keith
Copy link
Collaborator

keith commented Oct 12, 2021

Here's a potential swift fix #39695

@keith
Copy link
Collaborator

keith commented Nov 8, 2021

@adrian-prantl fixed in #40039

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself
Projects
None yet
Development

No branches or pull requests

2 participants