llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.03k stars 11.97k forks source link

Debuginfo for alias variable /func is not emitted. #49396

Open llvmbot opened 3 years ago

llvmbot commented 3 years ago
Bugzilla Link 50052
Version trunk
OS Windows NT
Reporter LLVM Bugzilla Contributor
CC @adrian-prantl,@dwblaikie,@DougGregor,@jmorse,@kamleshbhalui,@pogo59,@zygoloid

Extended Description

We have a situation with clang ,where the debuginfo for alias variable /func is not emitted i.e $cat test.c int oldname = 1; extern int newname attribute((alias("oldname")));

$clang -g -O0 test.c

$gdb a.out (gdb) pt oldname type = int (gdb) pt newname type = <data variable, no debug info>

kamleshbhalui commented 3 years ago

created review: https://reviews.llvm.org/D103131

dwblaikie commented 3 years ago

Ah, interesting. Though apparently that's enough for gdb to be able to print out the variable's value. I guess it takes the DW_AT_name and does name lookup on it.

Yeah, gdb will leverage object-file symbols as well as using DWARF; IIRC it can demangle a function name to get parameter info & stuff, even without proper DWARF. Looking up the name of an external is comparatively easy.

Emitting two variable DIEs with the same address probably won't annoy any consumers, although it won't be obvious that the two vars are aliased; debuggers aren't likely to look for that sort of thing. My suspicion is that emitting a separate DIE with location would require fiddling with how the IR works (currently you can't attach debug metadata to an alias), so doing the import might actually be simpler.

Yeah - tradeoffs in both directions.

Attaching the debug info to the IR is quite useful so that the debug info can be dropped under optimizations (eg: LTO removes the alias, the debug info for the alias and all the types/etc it references could be dropped - you can see the cost of not doing this with the debug info I implemented for using declarations in C++ (Well, that's worse again because Clang's AST doesn't track where/how a using declaration is used - so we emit a bunch of unused ones to start with, but then have no way of culling them later either))

pogo59 commented 3 years ago

Ah, interesting. Though apparently that's enough for gdb to be able to print out the variable's value. I guess it takes the DW_AT_name and does name lookup on it.

Yeah, gdb will leverage object-file symbols as well as using DWARF; IIRC it can demangle a function name to get parameter info & stuff, even without proper DWARF. Looking up the name of an external is comparatively easy.

Emitting two variable DIEs with the same address probably won't annoy any consumers, although it won't be obvious that the two vars are aliased; debuggers aren't likely to look for that sort of thing. My suspicion is that emitting a separate DIE with location would require fiddling with how the IR works (currently you can't attach debug metadata to an alias), so doing the import might actually be simpler.

dwblaikie commented 3 years ago

Usual inspiration would be to check what GCC does (not that it's necessarily optimal, but a good place to start from/compare to).

gcc 7.5.0 (what I have on my Ubuntu 18.04) appears to ignore the alias attribute and emits "newname" as an external declaration. Nothing to tie it to "oldname" and no DW_AT_location.

Better than nothing, as you can inquire about the type for the name, but not useful beyond that.

Ah, interesting. Though apparently that's enough for gdb to be able to print out the variable's value. I guess it takes the DW_AT_name and does name lookup on it. (this is still informed by the debug info too, tohugh - trying to print the variable without any debug info results in: "'newname' has unknown type; cast it to its declared type")

Though, yeah, seems like it'd be nicer to include an address - Though I'm not sure if that'll confuse consumers seeing two entities with the same address (which, yeah, might come back to the use of imported declaration perhaps).

pogo59 commented 3 years ago

Usual inspiration would be to check what GCC does (not that it's necessarily optimal, but a good place to start from/compare to).

gcc 7.5.0 (what I have on my Ubuntu 18.04) appears to ignore the alias attribute and emits "newname" as an external declaration. Nothing to tie it to "oldname" and no DW_AT_location.

Better than nothing, as you can inquire about the type for the name, but not useful beyond that.

dwblaikie commented 3 years ago

I'm going to guess it'll probably be better/more likely that it'll be another DW_TAG_variable rather than imported declaration, but I don't know for sure.

Usual inspiration would be to check what GCC does (not that it's necessarily optimal, but a good place to start from/compare to).

pogo59 commented 3 years ago

CC: some of the usual debug-info parties.

As reported on llvm-dev, I tried adding a use of that name, and also tried -fstandalone-debug; still no debug info for newname. @​dblaikie and I both think this is a bug.

Looking at the IR, clang does emit a DIGlobalVariable for oldname, but nothing for newname.

Looking at the DWARF spec, the general mechanism for aliasing would appear to be DW_TAG_imported_declaration, with DW_AT_name giving the alias name and DW_AT_import pointing to the DIE of the original entity. See the final normative paragraph of section 3.2.3, top of page 73 in DWARF 5.

I tried hacking the .ll file but it looks like the IR parser doesn't like having a !dbg attached to an alias declaration, so doing this will likely be non-trivial.

llvmbot commented 3 years ago

assigned to @kamleshbhalui

llvmbot commented 4 months ago

@llvm/issue-subscribers-debuginfo

Author: None (llvmbot)

| | | | --- | --- | | Bugzilla Link | [50052](https://llvm.org/bz50052) | | Version | trunk | | OS | Windows NT | | Reporter | LLVM Bugzilla Contributor | | CC | @adrian-prantl,@dwblaikie,@DougGregor,@jmorse,@kamleshbhalui,@pogo59,@zygoloid | ## Extended Description We have a situation with clang ,where the debuginfo for alias variable /func is not emitted i.e $cat test.c int oldname = 1; extern int newname __attribute__((alias("oldname"))); $clang -g -O0 test.c $gdb a.out (gdb) pt oldname type = int (gdb) pt newname type = <data variable, no debug info>