DWARF line table rows with line 0 are dropped, so code gets attributed to the wrong line
Les mainteneurs répondent en général sous 1 jour
Évaluation
- Difficulté
- 3/5
- Temps estimé
- 1-2 jours
- Accessibilité débutants
- 76/100
Piste de recherche
Start in src/wasm/wasm-debug.cpp at LineState::needToEmit and review the DWARF line-table handling. Run the clang, wasm-ld, wasm-opt, and llvm-dwarfdump reproduction from the issue, then verify that line 0 rows remain mapped and llvm-dwarfdump --lookup=0x0b reports line 0 after wasm-opt -g.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
While working on some debugger related fixes in TinyGo, I discovered what I think is an issue, and also a possible fix. The following is an edited version of the automated analysis.
Thank you for looking it over.
Analysis
When wasm-opt rewrites the DWARF line table, it drops every row that has line 0, even when no passes run. In DWARF, line 0 means the code has no source line, for example code LLVM merged from two places. Once the line 0 row is gone, the previous row covers that code, so debuggers and profilers attribute it to the wrong line.
The check is in LineState::needToEmit (wasm-debug.cpp):
bool needToEmit() {
// Zero values imply we can ignore this line.
// https://github.com/WebAssembly/debugging/issues/9#issuecomment-567720872
return line != 0 && addr != 0;
}
The linked comment explains why address 0 is reserved for dead code removed by the linker. It does not mention line 0. The code is the same on main.
Repro
t.c:
int g(int);
int f(int x) {
int r = 0;
if (x > 10)
r = g(x);
else
r = g(x + 1);
return r * 3;
}
clang --target=wasm32 -O2 -g -c t.c -o t.o
wasm-ld --no-entry --export=f --allow-undefined t.o -o t.wasm
wasm-opt -g t.wasm -o out.wasm
llvm-dwarfdump --debug-line t.wasm
llvm-dwarfdump --debug-line out.wasm
LLVM merges the two calls to g and marks the call with line 0. Input line table:
Address Line Column File ISA Discriminator OpIndex Flags
0x0000000000000002 3 0 1 0 0 0 is_stmt
0x0000000000000007 5 9 1 0 0 0 is_stmt prologue_end
0x0000000000000008 5 7 1 0 0 0
0x000000000000000b 0 0 1 0 0 0
0x0000000000000013 9 12 1 0 0 0 is_stmt
0x0000000000000014 9 3 1 0 0 0
0x0000000000000015 9 3 1 0 0 0 end_sequence
Output line table after wasm-opt -g with no passes:
Address Line Column File ISA Discriminator OpIndex Flags
0x0000000000000002 3 0 1 0 0 0 is_stmt
0x0000000000000007 5 9 1 0 0 0 is_stmt prologue_end
0x0000000000000008 5 7 1 0 0 0
0x000000000000000f 9 12 1 0 0 0 is_stmt
0x0000000000000010 9 3 1 0 0 0
0x0000000000000011 9 3 1 0 0 0 end_sequence
The call is at 0x0b in both files. llvm-dwarfdump --lookup=0x0b gives line 0 for t.wasm and line 5, column 7 (the if condition) for out.wasm.
Tested with wasm-opt version 133 and clang 18.1.2 from wasi-sdk.
Impact
We found this in TinyGo, where a no-op round trip through wasm-opt -g removes all 21,756 line 0 rows from a small program. It gets worse with --asyncify, since code it adds in the middle of a function also ends up under the previous source line. See https://github.com/tinygo-org/tinygo/issues/5736.
Possible fix
Keep line 0 rows and only skip rows with address 0. Line 0 rows would still need their address mapped like any other row.
- Langage dominant
- WebAssembly
- Étoiles
- 8.7k
- Forks
- 900
- Merge moyen
- 2 j 5 h
- PR mergées (30 j)
- 93
Préparer son environnement
- Aucun Dockerfile ni fichier Docker Compose
- Aucun modèle de pull request
- Lire le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de WebAssembly/binaryen
-
Difficulté 1/5 Moins d'une heure Accessibilité débutants 88/100
WebAssembly/binaryen#9135 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 Une demi-journée Accessibilité débutants 76/100
WebAssembly/binaryen#9018 · 3 commentaires ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 4/5 3-5 jours Accessibilité débutants 45/100
WebAssembly/binaryen#9307 · 2 commentaires ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 3/5 1-2 jours Accessibilité débutants 76/100
WebAssembly/binaryen#9291 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 3/5 1-2 jours Accessibilité débutants 62/100
WebAssembly/binaryen#9257 · 2 commentaires ·
Les mainteneurs répondent en général sous 1 jour
Toutes les issues de WebAssembly/binaryen
Issues similaires
-
Difficulté 2/5 1-3 heures Accessibilité débutants 77/100
manuscript-lang/manuscript#1604 ·
Les mainteneurs répondent en général sous 1 jour
-
rust testing
Difficulté 2/5 1-3 heures Accessibilité débutants 79/100
NekomyaDev/nudge#275 ·
Les mainteneurs répondent en général sous 1 jour
-
crash lld:COFF
Difficulté 2/5 1-3 heures Accessibilité débutants 77/100
llvm/llvm-project#235970 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 64/100
Les mainteneurs répondent en général sous 1 jour
-
bug scope:types
Difficulté 2/5 1-3 heures Accessibilité débutants 82/100
Les mainteneurs répondent en général sous 1 jour