Open vries opened 4 years ago
This probably falls under the general assumption that the whole program is built with debug info - so if this is addressed, I'd expect it to only result in 'aaa' being described under -fstandalone-debug, and not under -fno-standalone-debug.
To make sure I understand, let me try to summarize the current status:
- this is a bug in -fstandalone-debug
- it's being discussed whether this is a bug in -fno-standalone-debug
Is this a correct summary?
Pretty much.
This probably falls under the general assumption that the whole program is built with debug info - so if this is addressed, I'd expect it to only result in 'aaa' being described under -fstandalone-debug, and not under -fno-standalone-debug.
To make sure I understand, let me try to summarize the current status:
Is this a correct summary?
With Clang 5 (the only version I have handy) + -fstandalone-debug, I still get no debug info for the external decl:
$ cat psym-external-decl.c extern int aaa; int main (void) { return aaa; } $ clang -c -g -fstandalone-debug psym-external-decl.c -o psym-external-decl.o $ readelf -wi psym-external-decl.o | grep aaa
Do newer Clangs behave differently?
Same with clang-10.0.0.
With Clang 5 (the only version I have handy) + -fstandalone-debug, I still get no debug info for the external decl:
$ cat psym-external-decl.c extern int aaa; int main (void) { return aaa; } $ clang -c -g -fstandalone-debug psym-external-decl.c -o psym-external-decl.o $ readelf -wi psym-external-decl.o | grep aaa
Do newer Clangs behave differently?
This probably falls under the general assumption that the whole program is built with debug info - so if this is addressed, I'd expect it to only result in 'aaa' being described under -fstandalone-debug, and not under -fno-standalone-debug.
"Whole program" including libraries? If a library exports data but isn't built with debug info, would you still want the client built with -fstandalone-debug in order to look at that data?
Yep - that'd be my take on it.
For example, if you have a library with a base class with an out-of-line key function - and you derive from that type in your library-using code, then if you don't build that library with debug info you won't be able to interact with the base members in derived objects - lldb won't work at all here, because it can't construct the Clang AST for the base type that the derived type needs to derive from. (though lldb's hopefully going to have that fixed in the next few months fingers crossed)
Try this:
a.h: struct base { int i = 42; virtual void func(); }; a.cpp (build without debug info)
void base::func() { }; b.cpp (build with debug info)
struct derived: base { int j = 3 }; int main() { derived d; } // break here (with gdb) and print 'd' - it won't show the 'i' member value, only 'j'
This probably falls under the general assumption that the whole program is built with debug info - so if this is addressed, I'd expect it to only result in 'aaa' being described under -fstandalone-debug, and not under -fno-standalone-debug.
"Whole program" including libraries? If a library exports data but isn't built with debug info, would you still want the client built with -fstandalone-debug in order to look at that data?
This probably falls under the general assumption that the whole program is built with debug info - so if this is addressed, I'd expect it to only result in 'aaa' being described under -fstandalone-debug, and not under -fno-standalone-debug.
Is this a missing feature in clang, or is this explicitly unsupported?
We do avoid emitting external declarations in general, as a size reduction with (usually) no usability loss. I'd call this case a missing feature, on the grounds that "aaa" is actually used within psym-external-decl.c.
We're not that great at making debug-info decisions based on whether symbols have been used; see also bug 21299 which is the flip side, emitting unused symbols.
I am working on a project that uses both assembly and C, and I also have the same problem that clang does not generate debug info for external symbols defined in assembly.
; test.asm
global g_Var
section .data
g_Var: dd 10
section .note.GNU-stack
// test.c
#include <stdio.h>
extern int g_Var;
int main()
{
printf("%d\n", g_Var);
}
nasm test.asm -o test.asm~
clang test.c -o test.c~ -c -g
clang test.c~ test.asm~ -o test
## debug using gdb
(gdb) p g_Var
'g_Var' has unknown type; cast it to its declared type
When using any debugging tool to print the value of g_Var
, it is required to manually cast it to its declared type, which is very tedious, especially when the type name is very long. But gcc is able to handle such situation quite well.
nasm test.asm -o test.asm~
gcc test.c -o test.c~ -c -g
gcc test.c~ test.asm~ -o test
## debug using gdb
(gdb) p g_Var
$1 = 10
Hope this could be improved in future releases 😀.
Extended Description
Consider the following test-case from the gdb testsuite: ... $ cat psym-external-decl.c extern int aaa; int main (void) { return aaa; } $ cat psym-external-decl-2.c int aaa = 33; ...
Run with script compile.sh: ... $ cat compile.sh
!/bin/sh
$cc -c -g psym-external-decl.c $cc -c psym-external-decl-2.c $cc -g psym-external-decl.o psym-external-decl-2.o
gdb -batch a.out -ex "ptype aaa" -ex "p aaa" ...
With gcc, we have: ... $ cc=gcc ./compile.sh type = int $1 = 33 ...
And with clang-10: ... $ cc=clang-10 ./compile.sh type = <data variable, no debug info> 'aaa' has unknown type; cast it to its declared type ...
The difference is caused by missing debug info for the declaration of aaa in psym-external-decl.c.
That is, with gcc, we have: ... $ readelf -wi psym-external-decl.o | grep aaa
<2e> DW_AT_name : aaa $ ... and with clang: ... $ readelf -wi psym-external-decl.o | grep aaa $ ... Is this a missing feature in clang, or is this explicitly unsupported?