llvm / llvm/llvm-project

[dsymutil] `--linker=parallel` causes self-recurring typedef in DIE for `std::string`

Open
#162,954 22 comments 0 reactions 0 assignees View on GitHub
debuginfo lldb
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

# TL;DR

When running `dsymutil --linker=parallel`, the generated dSYM contains a DIE (see below), which is a typedef of itself (the address of the `DW_TAG_typedef` is identical to that of the `DW_AT_type`).
```
0x00004cb1: DW_TAG_typedef
DW_AT_type (0x00004cb1 "string")
DW_AT_name ("string")
DW_AT_decl_line (45)
DW_AT_decl_file ("/Applications/Xcode_26.0.0_17A324_fb.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/v1/__fwd/string.h")
```

Notes:
* This happens on macOS. Not sure if it happens on other OS.
* This causes LLDB to enter infinite recursion when trying to understand this type. See [stack trace](https://gist.github.com/royitaqi/873a57af77c956902bfe30701c7bd294). See "Step 2" below.
* `dsymutil --verify-dwarf=all` doesn't report this issue.
* This issue doesn't happen **without** `--linker=parallel`. See "Step 3" below.

# Repro steps on macOS

**Step 1: Create the following `main.cpp`:**

```
#include
#include

int main() {
std::string f = "Hello World";
std::cout << f << std::endl;
}
```

**Step 2: Run `dsymutil` WITH `--linker=parallel` to repro the issue:**

```
xcrun clang++ -g -O0 -c main.cpp
xcrun clang++ -g -O0 main.o
~/public_llvm/build/bin/dsymutil --verify-dwarf=all --linker=parallel -o a.out.dSYM a.out
dwarfdump a.out.dSYM --name=string
lldb a.out -o "b main.cpp:6" -o "r" -o "p f"
```

I see these output: https://gist.github.com/royitaqi/1afb74beccfcd011021e339e1dc76e0d

Observe:
* The DIE contains a "string" which is a typedef of itself.
* The `--verify-dwarf=all` doesn't catch this issue.
* If you attach an lldb to the above lldb, you will see the above call stack.

**(optional) Step 3: Run `dsymutil` WITHOUT `--linker=parallel` as a comparison:**

```
xcrun clang++ -g -O0 -c main.cpp
xcrun clang++ -g -O0 main.o
~/public_llvm/build/bin/dsymutil --verify-dwarf=all -o a.out.dSYM a.out
dwarfdump a.out.dSYM --name=string
lldb a.out -o "b main.cpp:6" -o "r" -o "p f"
```

I see these output: https://gist.github.com/royitaqi/e83bb8b986fef3556f2e268e8c7a6eee

Observe:
* The DIE contains one "string" which is a typedef of another "string", which is the actual `std::basic_string`.
* The "string" type is understood and is printed correctly by lldb.

--

cc @clayborg

Contributor guide

Open the contributing guide

Research direction

Reproduce the issue with the provided macOS commands, then inspect dsymutil's --linker=parallel path and compare its DWARF output with the serial linker path. Use dwarfdump and LLDB to verify that the generated std::string DIE is no longer self-recursive and that --verify-dwarf=all behavior is considered.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.