public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* GDB and debug fission
@ 2021-01-08  1:25 Alexander Yermolovich
  2021-01-08  1:48 ` Sterling Augustine
  0 siblings, 1 reply; 12+ messages in thread
From: Alexander Yermolovich @ 2021-01-08  1:25 UTC (permalink / raw)
  To: gdb

Hello.

For latest gdb to work with -gsplit-dwarf debug information generated by clang, either in split or single mode does it need gdb_index or pubnames?
In normal case where debug information is part of executable gdb_index is nice to speed up startup time, and I think I read pubnames is not used, but with debug fission are either gdb_index or pubnames necessary?


Thank You
Alex

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: GDB and debug fission
  2021-01-08  1:25 GDB and debug fission Alexander Yermolovich
@ 2021-01-08  1:48 ` Sterling Augustine
  2021-01-08  2:12   ` Alexander Yermolovich
  2021-01-08  2:17   ` David Blaikie
  0 siblings, 2 replies; 12+ messages in thread
From: Sterling Augustine @ 2021-01-08  1:48 UTC (permalink / raw)
  To: Alexander Yermolovich; +Cc: gdb

On Thu, Jan 7, 2021 at 5:25 PM Alexander Yermolovich via Gdb
<gdb@sourceware.org> wrote:
>
> Hello.
>
> For latest gdb to work with -gsplit-dwarf debug information generated by clang, either in split or single mode does it need gdb_index or pubnames?
> In normal case where debug information is part of executable gdb_index is nice to speed up startup time, and I think I read pubnames is not used, but with debug fission are either gdb_index or pubnames necessary?

For gdb to work with split-dwarf debug info, it needs a gdb_index.
That can be generated in several ways. Gdb can build one itself--there
is a script somewhere to add a gdb index.

But it is somewhat easier to have the linker you use generate
gdb_index for you (both gnu-ld and llvm's lld can do this). They do
this by reading the .gnu_pubnames section, so in some way, you need
both pubnames *and* an index.

So you would ordinarily use the following commands:

$(CC) $(normal_arguments) -ggnu-pubnames
$(LD)  $(normal_arguments) -Wl,--gdb-index

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: GDB and debug fission
  2021-01-08  1:48 ` Sterling Augustine
@ 2021-01-08  2:12   ` Alexander Yermolovich
  2021-01-08  3:16     ` David Blaikie
  2021-01-08  2:17   ` David Blaikie
  1 sibling, 1 reply; 12+ messages in thread
From: Alexander Yermolovich @ 2021-01-08  2:12 UTC (permalink / raw)
  To: Sterling Augustine; +Cc: gdb

Thanks for clarification.
Yep I saw LLD builds gdb_index using gnu-pubnames. It just wasn't clear to me if gdb needs it with split-dwarf. I saw a comment on one of llvm reviews from couple years ago about it, but things might have changed since then. So thought I would ask. 🙂

Without gdb_index and gnu_pubnames what will be the behavior of gdb?
I tried a toy example locally with split-dwarf without gdb_index and pubnames and it seemed to work with binary compiled with -O2 and -g2.
By work I mean I was able to step through code and print same variables as when I compiled it with monolithic debug information.

Thank You
Alex

________________________________
From: Sterling Augustine <saugustine@google.com>
Sent: Thursday, January 7, 2021 5:48 PM
To: Alexander Yermolovich <ayermolo@fb.com>
Cc: gdb@sourceware.org <gdb@sourceware.org>
Subject: Re: GDB and debug fission

On Thu, Jan 7, 2021 at 5:25 PM Alexander Yermolovich via Gdb
<gdb@sourceware.org> wrote:
>
> Hello.
>
> For latest gdb to work with -gsplit-dwarf debug information generated by clang, either in split or single mode does it need gdb_index or pubnames?
> In normal case where debug information is part of executable gdb_index is nice to speed up startup time, and I think I read pubnames is not used, but with debug fission are either gdb_index or pubnames necessary?

For gdb to work with split-dwarf debug info, it needs a gdb_index.
That can be generated in several ways. Gdb can build one itself--there
is a script somewhere to add a gdb index.

But it is somewhat easier to have the linker you use generate
gdb_index for you (both gnu-ld and llvm's lld can do this). They do
this by reading the .gnu_pubnames section, so in some way, you need
both pubnames *and* an index.

So you would ordinarily use the following commands:

$(CC) $(normal_arguments) -ggnu-pubnames
$(LD)  $(normal_arguments) -Wl,--gdb-index

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: GDB and debug fission
  2021-01-08  1:48 ` Sterling Augustine
  2021-01-08  2:12   ` Alexander Yermolovich
@ 2021-01-08  2:17   ` David Blaikie
  1 sibling, 0 replies; 12+ messages in thread
From: David Blaikie @ 2021-01-08  2:17 UTC (permalink / raw)
  To: Sterling Augustine; +Cc: Alexander Yermolovich, gdb

On Thu, Jan 7, 2021 at 5:48 PM Sterling Augustine via Gdb
<gdb@sourceware.org> wrote:
>
> On Thu, Jan 7, 2021 at 5:25 PM Alexander Yermolovich via Gdb
> <gdb@sourceware.org> wrote:
> >
> > Hello.
> >
> > For latest gdb to work with -gsplit-dwarf debug information generated by clang, either in split or single mode does it need gdb_index or pubnames?
> > In normal case where debug information is part of executable gdb_index is nice to speed up startup time, and I think I read pubnames is not used, but with debug fission are either gdb_index or pubnames necessary?
>
> For gdb to work with split-dwarf debug info, it needs a gdb_index.
> That can be generated in several ways. Gdb can build one itself--there
> is a script somewhere to add a gdb index.

Hmm, do you know if that ^ works with split DWARF? I assumed it
wouldn't (since I figured it was powered by the same logic that would
be used by gdb in the absence of an index). If that does work - we
could use that to reduce build overhead & just tell people "when you
want to debug, run this script, then use the debugger" (or build it
into the debugger, etc)

> But it is somewhat easier to have the linker you use generate
> gdb_index for you (both gnu-ld and llvm's lld can do this). They do
> this by reading the .gnu_pubnames section, so in some way, you need
> both pubnames *and* an index.
>
> So you would ordinarily use the following commands:
>
> $(CC) $(normal_arguments) -ggnu-pubnames
> $(LD)  $(normal_arguments) -Wl,--gdb-index

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: GDB and debug fission
  2021-01-08  2:12   ` Alexander Yermolovich
@ 2021-01-08  3:16     ` David Blaikie
  2021-01-08 18:52       ` Alexander Yermolovich
  2021-01-29 20:34       ` David Blaikie
  0 siblings, 2 replies; 12+ messages in thread
From: David Blaikie @ 2021-01-08  3:16 UTC (permalink / raw)
  To: Alexander Yermolovich; +Cc: Sterling Augustine, gdb

On Thu, Jan 7, 2021 at 6:13 PM Alexander Yermolovich via Gdb <
gdb@sourceware.org> wrote:

> Thanks for clarification.
> Yep I saw LLD builds gdb_index using gnu-pubnames. It just wasn't clear to
> me if gdb needs it with split-dwarf. I saw a comment on one of llvm reviews
> from couple years ago about it, but things might have changed since then.
> So thought I would ask. 🙂
>
> Without gdb_index and gnu_pubnames what will be the behavior of gdb?
> I tried a toy example locally with split-dwarf without gdb_index and
> pubnames and it seemed to work with binary compiled with -O2 and -g2.
> By work I mean I was able to step through code and print same variables as
> when I compiled it with monolithic debug information.
>

Hmm - so far, I haven't been able to reproduce the failures I've seen in
the past - it's possible I've made mistakes in the past and promoted the
idea that gdb requires an index when using Split DWARF.

What /does/ seem to be the case is that if you do create a gdb-index, it
must be comprehensive - you must have built all your objects (that have
DWARF) with -ggnu-pubnames, because it looks like gdb is assuming the index
is comprehensive.

Here's my example:

$ cat a.cpp

struct t1 { int x; };

void a() {

  t1 v1 = {3};

}

$ cat b.cpp

void a();

int main() {

  a();

}

$ clang++ a.cpp b.cpp -gsplit-dwarf -g -gno-pubnames

$ gdb --batch -ex "ptype t1" ./a.out

...

type = struct t1 {

    int x;

}

Aborted

$ clang++ a.cpp b.cpp -gsplit-dwarf -g -Wl,--gdb-index -fuse-ld=lld

$ gdb --batch -ex "ptype t1" ./a.out

...

type = struct t1 {

    int x;

}

Aborted

$ clang++ a.cpp b.cpp -gsplit-dwarf -g -gno-pubnames -Wl,--gdb-index
-fuse-ld=lld

$ gdb --batch -ex "ptype t1" ./a.out

...

No symbol "t1" in current context.

And just for some added complexity... let's check if gdb can appropriately
respect DW_AT_GNU_pubnames on CUs without an index.

Hmm, seems it doesn't (or, at least, it doesn't worry about
DW_AT_GNU_pubnames, perhaps it relies on checking the contents of the
debug_gnu_pubnames/pubtypes section to see which units are covered by
names? Or it's ignoring the contents entirely... - would have to hand-craft
a dodgy debug_gnu_pub* section to test whether it's using it at all)

(expanding/modifying the above example with 3 "external" files (so there's
no risk gdb accidentally parsed them when parsing the main function, for
instance) and 3 types)

$ clang++ -gsplit-dwarf -ggnu-pubnames -g b.cpp c.cpp -c
$ llvm-objcopy --remove-section=.debug_gnu_pubnames
--remove-section=.debug_gnu_pubtypes c.o
$ clang++ -gsplit-dwarf -g -gno-pubnames d.cpp -c
$ clang++ a.cpp b.o c.o d.o -g

$ gdb --batch -ex "ptype at" -ex "ptype bt" -ex "ptype ct" ./a.out

...

type = struct at {

    int i;

}

type = struct bt {

    int i;

}

type = struct ct {

    int i;

}

Aborted

Let's try that hand-crafted/corrupt pubnames.

Hmm, looks like gdb didn't care about my pubnames?

$ llvm-dwarfdump-tot a.out -debug-gnu-pubtypes

a.out:  file format elf64-x86-64


.debug_gnu_pubtypes contents:

length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset =
0x00000000, unit_size = 0x00000030

Offset     Linkage  Kind     Name

0x00000041 STATIC   TYPE     "int"

length = 0x0000001f, format = DWARF32, version = 0x0002, unit_offset =
0x00000030, unit_size = 0x00000030

Offset     Linkage  Kind     Name

0x00000031 EXTERNAL TYPE     "at"

0x00000041 STATIC   TYPE     "int"

length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset =
0x00000060, unit_size = 0x00000030

Offset     Linkage  Kind     Name
<<<<<<<<<<<<<< hand modified to remove "bt" here >>>>>>>>>>

0x00000028 STATIC   TYPE     "int"

length = 0x0000001f, format = DWARF32, version = 0x0002, unit_offset =
0x00000090, unit_size = 0x00000030

Offset     Linkage  Kind     Name

0x00000031 EXTERNAL TYPE     "ct"

0x00000041 STATIC   TYPE     "int"

$ gdb --batch -ex "ptype at" -ex "ptype bt" -ex "ptype ct" ./a.out

Unable to determine compiler version.

Skipping loading of libstdc++ pretty-printers for now.

Loading libc++ pretty-printers.

Non-google3 binary detected.

type = struct at {

    int i;

}
<<<<<<<<<< gdb still manages to find bt >>>>>>>>>>>

type = struct bt {

    int i;

}

type = struct ct {

    int i;

}

Aborted

So based on all that, I /think/ the answer is:

If you are going to use a linker-generated gdb-index with Split DWARF, then
you must have gnu-pubnames on every input file. (because it can't build
indexes for CUs without pubnames because it doesn't have access to the unit
contents (because they're split) - in non-split cases, 'gold' will build
the index itself by parsing the DWARF, I don't think 'lld' can do that, so
if you're using lld, this advice applies to non-split DWARF too (either
index everything, or don't have an index))
But you'll have a really slow debugging experience if you don't do that -
but, so far as I can tell, it looks like it'll be correct, just slow.

But I'm super not sure about all of this. The "gdb only handles Split DWARF
with an index" may be rumor, rumor that I accidentally promoted as fact
based on some misunderstandings/incomplete experiments. Or maybe there's
some truth to it I don't know how to reproduce...

- Dave


> Thank You
> Alex
>
> ________________________________
> From: Sterling Augustine <saugustine@google.com>
> Sent: Thursday, January 7, 2021 5:48 PM
> To: Alexander Yermolovich <ayermolo@fb.com>
> Cc: gdb@sourceware.org <gdb@sourceware.org>
> Subject: Re: GDB and debug fission
>
> On Thu, Jan 7, 2021 at 5:25 PM Alexander Yermolovich via Gdb
> <gdb@sourceware.org> wrote:
> >
> > Hello.
> >
> > For latest gdb to work with -gsplit-dwarf debug information generated by
> clang, either in split or single mode does it need gdb_index or pubnames?
> > In normal case where debug information is part of executable gdb_index
> is nice to speed up startup time, and I think I read pubnames is not used,
> but with debug fission are either gdb_index or pubnames necessary?
>
> For gdb to work with split-dwarf debug info, it needs a gdb_index.
> That can be generated in several ways. Gdb can build one itself--there
> is a script somewhere to add a gdb index.
>
> But it is somewhat easier to have the linker you use generate
> gdb_index for you (both gnu-ld and llvm's lld can do this). They do
> this by reading the .gnu_pubnames section, so in some way, you need
> both pubnames *and* an index.
>
> So you would ordinarily use the following commands:
>
> $(CC) $(normal_arguments) -ggnu-pubnames
> $(LD)  $(normal_arguments) -Wl,--gdb-index
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: GDB and debug fission
  2021-01-08  3:16     ` David Blaikie
@ 2021-01-08 18:52       ` Alexander Yermolovich
  2021-01-08 19:01         ` David Blaikie
  2021-01-29 20:34       ` David Blaikie
  1 sibling, 1 reply; 12+ messages in thread
From: Alexander Yermolovich @ 2021-01-08 18:52 UTC (permalink / raw)
  To: David Blaikie; +Cc: Sterling Augustine, gdb

Thanks for the thorough response!
I will keep your findings about incomplete gdb_index in mind.
I think I saw a patch for LLD that would have not relied on pubnames, but I don't believe it landed.
Quickly looking at current code for gdb_index construction it uses pubnames from object files.

Alex.
________________________________
From: David Blaikie <dblaikie@gmail.com>
Sent: Thursday, January 7, 2021 7:16 PM
To: Alexander Yermolovich <ayermolo@fb.com>
Cc: Sterling Augustine <saugustine@google.com>; gdb@sourceware.org <gdb@sourceware.org>
Subject: Re: GDB and debug fission



On Thu, Jan 7, 2021 at 6:13 PM Alexander Yermolovich via Gdb <gdb@sourceware.org<mailto:gdb@sourceware.org>> wrote:
Thanks for clarification.
Yep I saw LLD builds gdb_index using gnu-pubnames. It just wasn't clear to me if gdb needs it with split-dwarf. I saw a comment on one of llvm reviews from couple years ago about it, but things might have changed since then. So thought I would ask. 🙂

Without gdb_index and gnu_pubnames what will be the behavior of gdb?
I tried a toy example locally with split-dwarf without gdb_index and pubnames and it seemed to work with binary compiled with -O2 and -g2.
By work I mean I was able to step through code and print same variables as when I compiled it with monolithic debug information.

Hmm - so far, I haven't been able to reproduce the failures I've seen in the past - it's possible I've made mistakes in the past and promoted the idea that gdb requires an index when using Split DWARF.

What /does/ seem to be the case is that if you do create a gdb-index, it must be comprehensive - you must have built all your objects (that have DWARF) with -ggnu-pubnames, because it looks like gdb is assuming the index is comprehensive.

Here's my example:

$ cat a.cpp

struct t1 { int x; };

void a() {

  t1 v1 = {3};

}

$ cat b.cpp

void a();

int main() {

  a();

}

$ clang++ a.cpp b.cpp -gsplit-dwarf -g -gno-pubnames

$ gdb --batch -ex "ptype t1" ./a.out

...

type = struct t1 {

    int x;

}

Aborted

$ clang++ a.cpp b.cpp -gsplit-dwarf -g -Wl,--gdb-index -fuse-ld=lld

$ gdb --batch -ex "ptype t1" ./a.out

...

type = struct t1 {

    int x;

}

Aborted

$ clang++ a.cpp b.cpp -gsplit-dwarf -g -gno-pubnames -Wl,--gdb-index -fuse-ld=lld

$ gdb --batch -ex "ptype t1" ./a.out

...

No symbol "t1" in current context.


And just for some added complexity... let's check if gdb can appropriately respect DW_AT_GNU_pubnames on CUs without an index.

Hmm, seems it doesn't (or, at least, it doesn't worry about DW_AT_GNU_pubnames, perhaps it relies on checking the contents of the debug_gnu_pubnames/pubtypes section to see which units are covered by names? Or it's ignoring the contents entirely... - would have to hand-craft a dodgy debug_gnu_pub* section to test whether it's using it at all)

(expanding/modifying the above example with 3 "external" files (so there's no risk gdb accidentally parsed them when parsing the main function, for instance) and 3 types)


$ clang++ -gsplit-dwarf -ggnu-pubnames -g b.cpp c.cpp -c
$ llvm-objcopy --remove-section=.debug_gnu_pubnames --remove-section=.debug_gnu_pubtypes c.o
$ clang++ -gsplit-dwarf -g -gno-pubnames d.cpp -c
$ clang++ a.cpp b.o c.o d.o -g

$ gdb --batch -ex "ptype at" -ex "ptype bt" -ex "ptype ct" ./a.out

...

type = struct at {

    int i;

}

type = struct bt {

    int i;

}

type = struct ct {

    int i;

}

Aborted

Let's try that hand-crafted/corrupt pubnames.

Hmm, looks like gdb didn't care about my pubnames?


$ llvm-dwarfdump-tot a.out -debug-gnu-pubtypes

a.out:  file format elf64-x86-64


.debug_gnu_pubtypes contents:

length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset = 0x00000000, unit_size = 0x00000030

Offset     Linkage  Kind     Name

0x00000041 STATIC   TYPE     "int"

length = 0x0000001f, format = DWARF32, version = 0x0002, unit_offset = 0x00000030, unit_size = 0x00000030

Offset     Linkage  Kind     Name

0x00000031 EXTERNAL TYPE     "at"

0x00000041 STATIC   TYPE     "int"

length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset = 0x00000060, unit_size = 0x00000030

Offset     Linkage  Kind     Name
<<<<<<<<<<<<<< hand modified to remove "bt" here >>>>>>>>>>

0x00000028 STATIC   TYPE     "int"

length = 0x0000001f, format = DWARF32, version = 0x0002, unit_offset = 0x00000090, unit_size = 0x00000030

Offset     Linkage  Kind     Name

0x00000031 EXTERNAL TYPE     "ct"

0x00000041 STATIC   TYPE     "int"

$ gdb --batch -ex "ptype at" -ex "ptype bt" -ex "ptype ct" ./a.out

Unable to determine compiler version.

Skipping loading of libstdc++ pretty-printers for now.

Loading libc++ pretty-printers.

Non-google3 binary detected.

type = struct at {

    int i;

}
<<<<<<<<<< gdb still manages to find bt >>>>>>>>>>>

type = struct bt {

    int i;

}

type = struct ct {

    int i;

}

Aborted

So based on all that, I /think/ the answer is:

If you are going to use a linker-generated gdb-index with Split DWARF, then you must have gnu-pubnames on every input file. (because it can't build indexes for CUs without pubnames because it doesn't have access to the unit contents (because they're split) - in non-split cases, 'gold' will build the index itself by parsing the DWARF, I don't think 'lld' can do that, so if you're using lld, this advice applies to non-split DWARF too (either index everything, or don't have an index))
But you'll have a really slow debugging experience if you don't do that - but, so far as I can tell, it looks like it'll be correct, just slow.

But I'm super not sure about all of this. The "gdb only handles Split DWARF with an index" may be rumor, rumor that I accidentally promoted as fact based on some misunderstandings/incomplete experiments. Or maybe there's some truth to it I don't know how to reproduce...

- Dave

Thank You
Alex

________________________________
From: Sterling Augustine <saugustine@google.com<mailto:saugustine@google.com>>
Sent: Thursday, January 7, 2021 5:48 PM
To: Alexander Yermolovich <ayermolo@fb.com<mailto:ayermolo@fb.com>>
Cc: gdb@sourceware.org<mailto:gdb@sourceware.org> <gdb@sourceware.org<mailto:gdb@sourceware.org>>
Subject: Re: GDB and debug fission

On Thu, Jan 7, 2021 at 5:25 PM Alexander Yermolovich via Gdb
<gdb@sourceware.org<mailto:gdb@sourceware.org>> wrote:
>
> Hello.
>
> For latest gdb to work with -gsplit-dwarf debug information generated by clang, either in split or single mode does it need gdb_index or pubnames?
> In normal case where debug information is part of executable gdb_index is nice to speed up startup time, and I think I read pubnames is not used, but with debug fission are either gdb_index or pubnames necessary?

For gdb to work with split-dwarf debug info, it needs a gdb_index.
That can be generated in several ways. Gdb can build one itself--there
is a script somewhere to add a gdb index.

But it is somewhat easier to have the linker you use generate
gdb_index for you (both gnu-ld and llvm's lld can do this). They do
this by reading the .gnu_pubnames section, so in some way, you need
both pubnames *and* an index.

So you would ordinarily use the following commands:

$(CC) $(normal_arguments) -ggnu-pubnames
$(LD)  $(normal_arguments) -Wl,--gdb-index

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: GDB and debug fission
  2021-01-08 18:52       ` Alexander Yermolovich
@ 2021-01-08 19:01         ` David Blaikie
  0 siblings, 0 replies; 12+ messages in thread
From: David Blaikie @ 2021-01-08 19:01 UTC (permalink / raw)
  To: Alexander Yermolovich; +Cc: Sterling Augustine, gdb

On Fri, Jan 8, 2021 at 10:52 AM Alexander Yermolovich <ayermolo@fb.com>
wrote:

> Thanks for the thorough response!
> I will keep your findings about incomplete gdb_index in mind.
> I think I saw a patch for LLD that would have not relied on pubnames, but
> I don't believe it landed.
>

Yeah, I think it was proposed - but that wouldn't help with Split DWARF,
because the linker wouldn't have access to the DWARF to reconstruct the
index/names from (since they'd be in the dwo files) - only relevant to
non-split gdb-index creation.


> Quickly looking at current code for gdb_index construction it uses
> pubnames from object files.
>
> Alex.
> ------------------------------
> *From:* David Blaikie <dblaikie@gmail.com>
> *Sent:* Thursday, January 7, 2021 7:16 PM
> *To:* Alexander Yermolovich <ayermolo@fb.com>
> *Cc:* Sterling Augustine <saugustine@google.com>; gdb@sourceware.org <
> gdb@sourceware.org>
> *Subject:* Re: GDB and debug fission
>
>
>
> On Thu, Jan 7, 2021 at 6:13 PM Alexander Yermolovich via Gdb <
> gdb@sourceware.org> wrote:
>
> Thanks for clarification.
> Yep I saw LLD builds gdb_index using gnu-pubnames. It just wasn't clear to
> me if gdb needs it with split-dwarf. I saw a comment on one of llvm reviews
> from couple years ago about it, but things might have changed since then.
> So thought I would ask. 🙂
>
> Without gdb_index and gnu_pubnames what will be the behavior of gdb?
> I tried a toy example locally with split-dwarf without gdb_index and
> pubnames and it seemed to work with binary compiled with -O2 and -g2.
> By work I mean I was able to step through code and print same variables as
> when I compiled it with monolithic debug information.
>
>
> Hmm - so far, I haven't been able to reproduce the failures I've seen in
> the past - it's possible I've made mistakes in the past and promoted the
> idea that gdb requires an index when using Split DWARF.
>
> What /does/ seem to be the case is that if you do create a gdb-index, it
> must be comprehensive - you must have built all your objects (that have
> DWARF) with -ggnu-pubnames, because it looks like gdb is assuming the index
> is comprehensive.
>
> Here's my example:
>
> $ cat a.cpp
>
> struct t1 { int x; };
>
> void a() {
>
>   t1 v1 = {3};
>
> }
>
> $ cat b.cpp
>
> void a();
>
> int main() {
>
>   a();
>
> }
>
> $ clang++ a.cpp b.cpp -gsplit-dwarf -g -gno-pubnames
>
> $ gdb --batch -ex "ptype t1" ./a.out
>
> ...
>
> type = struct t1 {
>
>     int x;
>
> }
>
> Aborted
>
> $ clang++ a.cpp b.cpp -gsplit-dwarf -g -Wl,--gdb-index -fuse-ld=lld
>
> $ gdb --batch -ex "ptype t1" ./a.out
>
> ...
>
> type = struct t1 {
>
>     int x;
>
> }
>
> Aborted
>
> $ clang++ a.cpp b.cpp -gsplit-dwarf -g -gno-pubnames -Wl,--gdb-index
> -fuse-ld=lld
>
> $ gdb --batch -ex "ptype t1" ./a.out
>
> ...
>
> No symbol "t1" in current context.
>
> And just for some added complexity... let's check if gdb can appropriately
> respect DW_AT_GNU_pubnames on CUs without an index.
>
> Hmm, seems it doesn't (or, at least, it doesn't worry about
> DW_AT_GNU_pubnames, perhaps it relies on checking the contents of the
> debug_gnu_pubnames/pubtypes section to see which units are covered by
> names? Or it's ignoring the contents entirely... - would have to hand-craft
> a dodgy debug_gnu_pub* section to test whether it's using it at all)
>
> (expanding/modifying the above example with 3 "external" files (so there's
> no risk gdb accidentally parsed them when parsing the main function, for
> instance) and 3 types)
>
> $ clang++ -gsplit-dwarf -ggnu-pubnames -g b.cpp c.cpp -c
> $ llvm-objcopy --remove-section=.debug_gnu_pubnames
> --remove-section=.debug_gnu_pubtypes c.o
> $ clang++ -gsplit-dwarf -g -gno-pubnames d.cpp -c
> $ clang++ a.cpp b.o c.o d.o -g
>
> $ gdb --batch -ex "ptype at" -ex "ptype bt" -ex "ptype ct" ./a.out
>
> ...
>
> type = struct at {
>
>     int i;
>
> }
>
> type = struct bt {
>
>     int i;
>
> }
>
> type = struct ct {
>
>     int i;
>
> }
>
> Aborted
>
> Let's try that hand-crafted/corrupt pubnames.
>
> Hmm, looks like gdb didn't care about my pubnames?
>
> $ llvm-dwarfdump-tot a.out -debug-gnu-pubtypes
>
> a.out:  file format elf64-x86-64
>
>
> .debug_gnu_pubtypes contents:
>
> length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset =
> 0x00000000, unit_size = 0x00000030
>
> Offset     Linkage  Kind     Name
>
> 0x00000041 STATIC   TYPE     "int"
>
> length = 0x0000001f, format = DWARF32, version = 0x0002, unit_offset =
> 0x00000030, unit_size = 0x00000030
>
> Offset     Linkage  Kind     Name
>
> 0x00000031 EXTERNAL TYPE     "at"
>
> 0x00000041 STATIC   TYPE     "int"
>
> length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset =
> 0x00000060, unit_size = 0x00000030
>
> Offset     Linkage  Kind     Name
> <<<<<<<<<<<<<< hand modified to remove "bt" here >>>>>>>>>>
>
> 0x00000028 STATIC   TYPE     "int"
>
> length = 0x0000001f, format = DWARF32, version = 0x0002, unit_offset =
> 0x00000090, unit_size = 0x00000030
>
> Offset     Linkage  Kind     Name
>
> 0x00000031 EXTERNAL TYPE     "ct"
>
> 0x00000041 STATIC   TYPE     "int"
>
> $ gdb --batch -ex "ptype at" -ex "ptype bt" -ex "ptype ct" ./a.out
>
> Unable to determine compiler version.
>
> Skipping loading of libstdc++ pretty-printers for now.
>
> Loading libc++ pretty-printers.
>
> Non-google3 binary detected.
>
> type = struct at {
>
>     int i;
>
> }
> <<<<<<<<<< gdb still manages to find bt >>>>>>>>>>>
>
> type = struct bt {
>
>     int i;
>
> }
>
> type = struct ct {
>
>     int i;
>
> }
>
> Aborted
>
> So based on all that, I /think/ the answer is:
>
> If you are going to use a linker-generated gdb-index with Split DWARF,
> then you must have gnu-pubnames on every input file. (because it can't
> build indexes for CUs without pubnames because it doesn't have access to
> the unit contents (because they're split) - in non-split cases, 'gold' will
> build the index itself by parsing the DWARF, I don't think 'lld' can do
> that, so if you're using lld, this advice applies to non-split DWARF too
> (either index everything, or don't have an index))
> But you'll have a really slow debugging experience if you don't do that -
> but, so far as I can tell, it looks like it'll be correct, just slow.
>
> But I'm super not sure about all of this. The "gdb only handles Split
> DWARF with an index" may be rumor, rumor that I accidentally promoted as
> fact based on some misunderstandings/incomplete experiments. Or maybe
> there's some truth to it I don't know how to reproduce...
>
> - Dave
>
>
> Thank You
> Alex
>
> ________________________________
> From: Sterling Augustine <saugustine@google.com>
> Sent: Thursday, January 7, 2021 5:48 PM
> To: Alexander Yermolovich <ayermolo@fb.com>
> Cc: gdb@sourceware.org <gdb@sourceware.org>
> Subject: Re: GDB and debug fission
>
> On Thu, Jan 7, 2021 at 5:25 PM Alexander Yermolovich via Gdb
> <gdb@sourceware.org> wrote:
> >
> > Hello.
> >
> > For latest gdb to work with -gsplit-dwarf debug information generated by
> clang, either in split or single mode does it need gdb_index or pubnames?
> > In normal case where debug information is part of executable gdb_index
> is nice to speed up startup time, and I think I read pubnames is not used,
> but with debug fission are either gdb_index or pubnames necessary?
>
> For gdb to work with split-dwarf debug info, it needs a gdb_index.
> That can be generated in several ways. Gdb can build one itself--there
> is a script somewhere to add a gdb index.
>
> But it is somewhat easier to have the linker you use generate
> gdb_index for you (both gnu-ld and llvm's lld can do this). They do
> this by reading the .gnu_pubnames section, so in some way, you need
> both pubnames *and* an index.
>
> So you would ordinarily use the following commands:
>
> $(CC) $(normal_arguments) -ggnu-pubnames
> $(LD)  $(normal_arguments) -Wl,--gdb-index
>
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: GDB and debug fission
  2021-01-08  3:16     ` David Blaikie
  2021-01-08 18:52       ` Alexander Yermolovich
@ 2021-01-29 20:34       ` David Blaikie
  2021-01-30  0:42         ` Alexander Yermolovich
  1 sibling, 1 reply; 12+ messages in thread
From: David Blaikie @ 2021-01-29 20:34 UTC (permalink / raw)
  To: Alexander Yermolovich, Jorge Gorbe Moya; +Cc: Sterling Augustine, gdb

Well, I found one place where the index seems necessary: Type units:

$ g++-tot a.cpp -fdebug-types-section -gdwarf-4 -gsplit-dwarf -c
$ g++-tot a.o -fuse-ld=gold
$ gdb ./a.out
...
(gdb) ptype t1
No symbol "t1" in current context.
(gdb) start
Temporary breakpoint 1 at 0x401106: file a.cpp, line 3.
Starting program: /usr/local/google/home/blaikie/dev/scratch/a.out

Temporary breakpoint 1, main () at a.cpp:3
3       int main() { t1 v1; }
(gdb) ptype t1
type = const float

But if you add -Wl,--gdb-index to the link command - it works correctly,
with t1 being found and rendered.

On Thu, Jan 7, 2021 at 7:16 PM David Blaikie <dblaikie@gmail.com> wrote:

>
>
> On Thu, Jan 7, 2021 at 6:13 PM Alexander Yermolovich via Gdb <
> gdb@sourceware.org> wrote:
>
>> Thanks for clarification.
>> Yep I saw LLD builds gdb_index using gnu-pubnames. It just wasn't clear
>> to me if gdb needs it with split-dwarf. I saw a comment on one of llvm
>> reviews from couple years ago about it, but things might have changed since
>> then. So thought I would ask. 🙂
>>
>> Without gdb_index and gnu_pubnames what will be the behavior of gdb?
>> I tried a toy example locally with split-dwarf without gdb_index and
>> pubnames and it seemed to work with binary compiled with -O2 and -g2.
>> By work I mean I was able to step through code and print same variables
>> as when I compiled it with monolithic debug information.
>>
>
> Hmm - so far, I haven't been able to reproduce the failures I've seen in
> the past - it's possible I've made mistakes in the past and promoted the
> idea that gdb requires an index when using Split DWARF.
>
> What /does/ seem to be the case is that if you do create a gdb-index, it
> must be comprehensive - you must have built all your objects (that have
> DWARF) with -ggnu-pubnames, because it looks like gdb is assuming the index
> is comprehensive.
>
> Here's my example:
>
> $ cat a.cpp
>
> struct t1 { int x; };
>
> void a() {
>
>   t1 v1 = {3};
>
> }
>
> $ cat b.cpp
>
> void a();
>
> int main() {
>
>   a();
>
> }
>
> $ clang++ a.cpp b.cpp -gsplit-dwarf -g -gno-pubnames
>
> $ gdb --batch -ex "ptype t1" ./a.out
>
> ...
>
> type = struct t1 {
>
>     int x;
>
> }
>
> Aborted
>
> $ clang++ a.cpp b.cpp -gsplit-dwarf -g -Wl,--gdb-index -fuse-ld=lld
>
> $ gdb --batch -ex "ptype t1" ./a.out
>
> ...
>
> type = struct t1 {
>
>     int x;
>
> }
>
> Aborted
>
> $ clang++ a.cpp b.cpp -gsplit-dwarf -g -gno-pubnames -Wl,--gdb-index
> -fuse-ld=lld
>
> $ gdb --batch -ex "ptype t1" ./a.out
>
> ...
>
> No symbol "t1" in current context.
>
> And just for some added complexity... let's check if gdb can appropriately
> respect DW_AT_GNU_pubnames on CUs without an index.
>
> Hmm, seems it doesn't (or, at least, it doesn't worry about
> DW_AT_GNU_pubnames, perhaps it relies on checking the contents of the
> debug_gnu_pubnames/pubtypes section to see which units are covered by
> names? Or it's ignoring the contents entirely... - would have to hand-craft
> a dodgy debug_gnu_pub* section to test whether it's using it at all)
>
> (expanding/modifying the above example with 3 "external" files (so there's
> no risk gdb accidentally parsed them when parsing the main function, for
> instance) and 3 types)
>
> $ clang++ -gsplit-dwarf -ggnu-pubnames -g b.cpp c.cpp -c
> $ llvm-objcopy --remove-section=.debug_gnu_pubnames
> --remove-section=.debug_gnu_pubtypes c.o
> $ clang++ -gsplit-dwarf -g -gno-pubnames d.cpp -c
> $ clang++ a.cpp b.o c.o d.o -g
>
> $ gdb --batch -ex "ptype at" -ex "ptype bt" -ex "ptype ct" ./a.out
>
> ...
>
> type = struct at {
>
>     int i;
>
> }
>
> type = struct bt {
>
>     int i;
>
> }
>
> type = struct ct {
>
>     int i;
>
> }
>
> Aborted
>
> Let's try that hand-crafted/corrupt pubnames.
>
> Hmm, looks like gdb didn't care about my pubnames?
>
> $ llvm-dwarfdump-tot a.out -debug-gnu-pubtypes
>
> a.out:  file format elf64-x86-64
>
>
> .debug_gnu_pubtypes contents:
>
> length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset =
> 0x00000000, unit_size = 0x00000030
>
> Offset     Linkage  Kind     Name
>
> 0x00000041 STATIC   TYPE     "int"
>
> length = 0x0000001f, format = DWARF32, version = 0x0002, unit_offset =
> 0x00000030, unit_size = 0x00000030
>
> Offset     Linkage  Kind     Name
>
> 0x00000031 EXTERNAL TYPE     "at"
>
> 0x00000041 STATIC   TYPE     "int"
>
> length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset =
> 0x00000060, unit_size = 0x00000030
>
> Offset     Linkage  Kind     Name
> <<<<<<<<<<<<<< hand modified to remove "bt" here >>>>>>>>>>
>
> 0x00000028 STATIC   TYPE     "int"
>
> length = 0x0000001f, format = DWARF32, version = 0x0002, unit_offset =
> 0x00000090, unit_size = 0x00000030
>
> Offset     Linkage  Kind     Name
>
> 0x00000031 EXTERNAL TYPE     "ct"
>
> 0x00000041 STATIC   TYPE     "int"
>
> $ gdb --batch -ex "ptype at" -ex "ptype bt" -ex "ptype ct" ./a.out
>
> Unable to determine compiler version.
>
> Skipping loading of libstdc++ pretty-printers for now.
>
> Loading libc++ pretty-printers.
>
> Non-google3 binary detected.
>
> type = struct at {
>
>     int i;
>
> }
> <<<<<<<<<< gdb still manages to find bt >>>>>>>>>>>
>
> type = struct bt {
>
>     int i;
>
> }
>
> type = struct ct {
>
>     int i;
>
> }
>
> Aborted
>
> So based on all that, I /think/ the answer is:
>
> If you are going to use a linker-generated gdb-index with Split DWARF,
> then you must have gnu-pubnames on every input file. (because it can't
> build indexes for CUs without pubnames because it doesn't have access to
> the unit contents (because they're split) - in non-split cases, 'gold' will
> build the index itself by parsing the DWARF, I don't think 'lld' can do
> that, so if you're using lld, this advice applies to non-split DWARF too
> (either index everything, or don't have an index))
> But you'll have a really slow debugging experience if you don't do that -
> but, so far as I can tell, it looks like it'll be correct, just slow.
>
> But I'm super not sure about all of this. The "gdb only handles Split
> DWARF with an index" may be rumor, rumor that I accidentally promoted as
> fact based on some misunderstandings/incomplete experiments. Or maybe
> there's some truth to it I don't know how to reproduce...
>
> - Dave
>
>
>> Thank You
>> Alex
>>
>> ________________________________
>> From: Sterling Augustine <saugustine@google.com>
>> Sent: Thursday, January 7, 2021 5:48 PM
>> To: Alexander Yermolovich <ayermolo@fb.com>
>> Cc: gdb@sourceware.org <gdb@sourceware.org>
>> Subject: Re: GDB and debug fission
>>
>> On Thu, Jan 7, 2021 at 5:25 PM Alexander Yermolovich via Gdb
>> <gdb@sourceware.org> wrote:
>> >
>> > Hello.
>> >
>> > For latest gdb to work with -gsplit-dwarf debug information generated
>> by clang, either in split or single mode does it need gdb_index or pubnames?
>> > In normal case where debug information is part of executable gdb_index
>> is nice to speed up startup time, and I think I read pubnames is not used,
>> but with debug fission are either gdb_index or pubnames necessary?
>>
>> For gdb to work with split-dwarf debug info, it needs a gdb_index.
>> That can be generated in several ways. Gdb can build one itself--there
>> is a script somewhere to add a gdb index.
>>
>> But it is somewhat easier to have the linker you use generate
>> gdb_index for you (both gnu-ld and llvm's lld can do this). They do
>> this by reading the .gnu_pubnames section, so in some way, you need
>> both pubnames *and* an index.
>>
>> So you would ordinarily use the following commands:
>>
>> $(CC) $(normal_arguments) -ggnu-pubnames
>> $(LD)  $(normal_arguments) -Wl,--gdb-index
>>
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: GDB and debug fission
  2021-01-29 20:34       ` David Blaikie
@ 2021-01-30  0:42         ` Alexander Yermolovich
  2021-01-30  1:06           ` David Blaikie
  0 siblings, 1 reply; 12+ messages in thread
From: Alexander Yermolovich @ 2021-01-30  0:42 UTC (permalink / raw)
  To: David Blaikie, Jorge Gorbe Moya; +Cc: Sterling Augustine, gdb

I tried it locally with:

struct t1 { int x; };

int main() { t1 v1; }
Using your commands, but with g++ (GCC) 8.4.1 20200928 (Red Hat 8.4.1-1)/gold and TOT clang++/lld.
GNU gdb (GDB) 9.1
For me it was able to resolve t1.
Some kind of regression with TOT gcc?

Alex
________________________________
From: David Blaikie <dblaikie@gmail.com>
Sent: Friday, January 29, 2021 12:34 PM
To: Alexander Yermolovich <ayermolo@fb.com>; Jorge Gorbe Moya <jgorbe@google.com>
Cc: Sterling Augustine <saugustine@google.com>; gdb@sourceware.org <gdb@sourceware.org>
Subject: Re: GDB and debug fission

Well, I found one place where the index seems necessary: Type units:

$ g++-tot a.cpp -fdebug-types-section -gdwarf-4 -gsplit-dwarf -c
$ g++-tot a.o -fuse-ld=gold
$ gdb ./a.out
...
(gdb) ptype t1
No symbol "t1" in current context.
(gdb) start
Temporary breakpoint 1 at 0x401106: file a.cpp, line 3.
Starting program: /usr/local/google/home/blaikie/dev/scratch/a.out

Temporary breakpoint 1, main () at a.cpp:3
3       int main() { t1 v1; }
(gdb) ptype t1
type = const float

But if you add -Wl,--gdb-index to the link command - it works correctly, with t1 being found and rendered.

On Thu, Jan 7, 2021 at 7:16 PM David Blaikie <dblaikie@gmail.com<mailto:dblaikie@gmail.com>> wrote:


On Thu, Jan 7, 2021 at 6:13 PM Alexander Yermolovich via Gdb <gdb@sourceware.org<mailto:gdb@sourceware.org>> wrote:
Thanks for clarification.
Yep I saw LLD builds gdb_index using gnu-pubnames. It just wasn't clear to me if gdb needs it with split-dwarf. I saw a comment on one of llvm reviews from couple years ago about it, but things might have changed since then. So thought I would ask. 🙂

Without gdb_index and gnu_pubnames what will be the behavior of gdb?
I tried a toy example locally with split-dwarf without gdb_index and pubnames and it seemed to work with binary compiled with -O2 and -g2.
By work I mean I was able to step through code and print same variables as when I compiled it with monolithic debug information.

Hmm - so far, I haven't been able to reproduce the failures I've seen in the past - it's possible I've made mistakes in the past and promoted the idea that gdb requires an index when using Split DWARF.

What /does/ seem to be the case is that if you do create a gdb-index, it must be comprehensive - you must have built all your objects (that have DWARF) with -ggnu-pubnames, because it looks like gdb is assuming the index is comprehensive.

Here's my example:

$ cat a.cpp

struct t1 { int x; };

void a() {

  t1 v1 = {3};

}

$ cat b.cpp

void a();

int main() {

  a();

}

$ clang++ a.cpp b.cpp -gsplit-dwarf -g -gno-pubnames

$ gdb --batch -ex "ptype t1" ./a.out

...

type = struct t1 {

    int x;

}

Aborted

$ clang++ a.cpp b.cpp -gsplit-dwarf -g -Wl,--gdb-index -fuse-ld=lld

$ gdb --batch -ex "ptype t1" ./a.out

...

type = struct t1 {

    int x;

}

Aborted

$ clang++ a.cpp b.cpp -gsplit-dwarf -g -gno-pubnames -Wl,--gdb-index -fuse-ld=lld

$ gdb --batch -ex "ptype t1" ./a.out

...

No symbol "t1" in current context.


And just for some added complexity... let's check if gdb can appropriately respect DW_AT_GNU_pubnames on CUs without an index.

Hmm, seems it doesn't (or, at least, it doesn't worry about DW_AT_GNU_pubnames, perhaps it relies on checking the contents of the debug_gnu_pubnames/pubtypes section to see which units are covered by names? Or it's ignoring the contents entirely... - would have to hand-craft a dodgy debug_gnu_pub* section to test whether it's using it at all)

(expanding/modifying the above example with 3 "external" files (so there's no risk gdb accidentally parsed them when parsing the main function, for instance) and 3 types)


$ clang++ -gsplit-dwarf -ggnu-pubnames -g b.cpp c.cpp -c
$ llvm-objcopy --remove-section=.debug_gnu_pubnames --remove-section=.debug_gnu_pubtypes c.o
$ clang++ -gsplit-dwarf -g -gno-pubnames d.cpp -c
$ clang++ a.cpp b.o c.o d.o -g

$ gdb --batch -ex "ptype at" -ex "ptype bt" -ex "ptype ct" ./a.out

...

type = struct at {

    int i;

}

type = struct bt {

    int i;

}

type = struct ct {

    int i;

}

Aborted

Let's try that hand-crafted/corrupt pubnames.

Hmm, looks like gdb didn't care about my pubnames?


$ llvm-dwarfdump-tot a.out -debug-gnu-pubtypes

a.out:  file format elf64-x86-64


.debug_gnu_pubtypes contents:

length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset = 0x00000000, unit_size = 0x00000030

Offset     Linkage  Kind     Name

0x00000041 STATIC   TYPE     "int"

length = 0x0000001f, format = DWARF32, version = 0x0002, unit_offset = 0x00000030, unit_size = 0x00000030

Offset     Linkage  Kind     Name

0x00000031 EXTERNAL TYPE     "at"

0x00000041 STATIC   TYPE     "int"

length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset = 0x00000060, unit_size = 0x00000030

Offset     Linkage  Kind     Name
<<<<<<<<<<<<<< hand modified to remove "bt" here >>>>>>>>>>

0x00000028 STATIC   TYPE     "int"

length = 0x0000001f, format = DWARF32, version = 0x0002, unit_offset = 0x00000090, unit_size = 0x00000030

Offset     Linkage  Kind     Name

0x00000031 EXTERNAL TYPE     "ct"

0x00000041 STATIC   TYPE     "int"

$ gdb --batch -ex "ptype at" -ex "ptype bt" -ex "ptype ct" ./a.out

Unable to determine compiler version.

Skipping loading of libstdc++ pretty-printers for now.

Loading libc++ pretty-printers.

Non-google3 binary detected.

type = struct at {

    int i;

}
<<<<<<<<<< gdb still manages to find bt >>>>>>>>>>>

type = struct bt {

    int i;

}

type = struct ct {

    int i;

}

Aborted

So based on all that, I /think/ the answer is:

If you are going to use a linker-generated gdb-index with Split DWARF, then you must have gnu-pubnames on every input file. (because it can't build indexes for CUs without pubnames because it doesn't have access to the unit contents (because they're split) - in non-split cases, 'gold' will build the index itself by parsing the DWARF, I don't think 'lld' can do that, so if you're using lld, this advice applies to non-split DWARF too (either index everything, or don't have an index))
But you'll have a really slow debugging experience if you don't do that - but, so far as I can tell, it looks like it'll be correct, just slow.

But I'm super not sure about all of this. The "gdb only handles Split DWARF with an index" may be rumor, rumor that I accidentally promoted as fact based on some misunderstandings/incomplete experiments. Or maybe there's some truth to it I don't know how to reproduce...

- Dave

Thank You
Alex

________________________________
From: Sterling Augustine <saugustine@google.com<mailto:saugustine@google.com>>
Sent: Thursday, January 7, 2021 5:48 PM
To: Alexander Yermolovich <ayermolo@fb.com<mailto:ayermolo@fb.com>>
Cc: gdb@sourceware.org<mailto:gdb@sourceware.org> <gdb@sourceware.org<mailto:gdb@sourceware.org>>
Subject: Re: GDB and debug fission

On Thu, Jan 7, 2021 at 5:25 PM Alexander Yermolovich via Gdb
<gdb@sourceware.org<mailto:gdb@sourceware.org>> wrote:
>
> Hello.
>
> For latest gdb to work with -gsplit-dwarf debug information generated by clang, either in split or single mode does it need gdb_index or pubnames?
> In normal case where debug information is part of executable gdb_index is nice to speed up startup time, and I think I read pubnames is not used, but with debug fission are either gdb_index or pubnames necessary?

For gdb to work with split-dwarf debug info, it needs a gdb_index.
That can be generated in several ways. Gdb can build one itself--there
is a script somewhere to add a gdb index.

But it is somewhat easier to have the linker you use generate
gdb_index for you (both gnu-ld and llvm's lld can do this). They do
this by reading the .gnu_pubnames section, so in some way, you need
both pubnames *and* an index.

So you would ordinarily use the following commands:

$(CC) $(normal_arguments) -ggnu-pubnames
$(LD)  $(normal_arguments) -Wl,--gdb-index

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: GDB and debug fission
  2021-01-30  0:42         ` Alexander Yermolovich
@ 2021-01-30  1:06           ` David Blaikie
  2021-02-01 20:07             ` Alexander Yermolovich
  0 siblings, 1 reply; 12+ messages in thread
From: David Blaikie @ 2021-01-30  1:06 UTC (permalink / raw)
  To: Alexander Yermolovich; +Cc: Jorge Gorbe Moya, Sterling Augustine, gdb

Ah, you might need a dwp to reproduce this. Try building a dwp for the .dwo
and deleting the dwo?



On Fri, Jan 29, 2021 at 4:42 PM Alexander Yermolovich <ayermolo@fb.com>
wrote:

> I tried it locally with:
>
> struct t1 { int x; };
>
> int main() { t1 v1; }
> Using your commands, but with g++ (GCC) 8.4.1 20200928 (Red Hat
> 8.4.1-1)/gold and TOT clang++/lld.
> GNU gdb (GDB) 9.1
> For me it was able to resolve t1.
> Some kind of regression with TOT gcc?
>
> Alex
> ------------------------------
> *From:* David Blaikie <dblaikie@gmail.com>
> *Sent:* Friday, January 29, 2021 12:34 PM
> *To:* Alexander Yermolovich <ayermolo@fb.com>; Jorge Gorbe Moya <
> jgorbe@google.com>
> *Cc:* Sterling Augustine <saugustine@google.com>; gdb@sourceware.org <
> gdb@sourceware.org>
> *Subject:* Re: GDB and debug fission
>
> Well, I found one place where the index seems necessary: Type units:
>
> $ g++-tot a.cpp -fdebug-types-section -gdwarf-4 -gsplit-dwarf -c
> $ g++-tot a.o -fuse-ld=gold
> $ gdb ./a.out
> ...
> (gdb) ptype t1
> No symbol "t1" in current context.
> (gdb) start
> Temporary breakpoint 1 at 0x401106: file a.cpp, line 3.
> Starting program: /usr/local/google/home/blaikie/dev/scratch/a.out
>
> Temporary breakpoint 1, main () at a.cpp:3
> 3       int main() { t1 v1; }
> (gdb) ptype t1
> type = const float
>
> But if you add -Wl,--gdb-index to the link command - it works correctly,
> with t1 being found and rendered.
>
> On Thu, Jan 7, 2021 at 7:16 PM David Blaikie <dblaikie@gmail.com> wrote:
>
>
>
> On Thu, Jan 7, 2021 at 6:13 PM Alexander Yermolovich via Gdb <
> gdb@sourceware.org> wrote:
>
> Thanks for clarification.
> Yep I saw LLD builds gdb_index using gnu-pubnames. It just wasn't clear to
> me if gdb needs it with split-dwarf. I saw a comment on one of llvm reviews
> from couple years ago about it, but things might have changed since then.
> So thought I would ask. 🙂
>
> Without gdb_index and gnu_pubnames what will be the behavior of gdb?
> I tried a toy example locally with split-dwarf without gdb_index and
> pubnames and it seemed to work with binary compiled with -O2 and -g2.
> By work I mean I was able to step through code and print same variables as
> when I compiled it with monolithic debug information.
>
>
> Hmm - so far, I haven't been able to reproduce the failures I've seen in
> the past - it's possible I've made mistakes in the past and promoted the
> idea that gdb requires an index when using Split DWARF.
>
> What /does/ seem to be the case is that if you do create a gdb-index, it
> must be comprehensive - you must have built all your objects (that have
> DWARF) with -ggnu-pubnames, because it looks like gdb is assuming the index
> is comprehensive.
>
> Here's my example:
>
> $ cat a.cpp
>
> struct t1 { int x; };
>
> void a() {
>
>   t1 v1 = {3};
>
> }
>
> $ cat b.cpp
>
> void a();
>
> int main() {
>
>   a();
>
> }
>
> $ clang++ a.cpp b.cpp -gsplit-dwarf -g -gno-pubnames
>
> $ gdb --batch -ex "ptype t1" ./a.out
>
> ...
>
> type = struct t1 {
>
>     int x;
>
> }
>
> Aborted
>
> $ clang++ a.cpp b.cpp -gsplit-dwarf -g -Wl,--gdb-index -fuse-ld=lld
>
> $ gdb --batch -ex "ptype t1" ./a.out
>
> ...
>
> type = struct t1 {
>
>     int x;
>
> }
>
> Aborted
>
> $ clang++ a.cpp b.cpp -gsplit-dwarf -g -gno-pubnames -Wl,--gdb-index
> -fuse-ld=lld
>
> $ gdb --batch -ex "ptype t1" ./a.out
>
> ...
>
> No symbol "t1" in current context.
>
> And just for some added complexity... let's check if gdb can appropriately
> respect DW_AT_GNU_pubnames on CUs without an index.
>
> Hmm, seems it doesn't (or, at least, it doesn't worry about
> DW_AT_GNU_pubnames, perhaps it relies on checking the contents of the
> debug_gnu_pubnames/pubtypes section to see which units are covered by
> names? Or it's ignoring the contents entirely... - would have to hand-craft
> a dodgy debug_gnu_pub* section to test whether it's using it at all)
>
> (expanding/modifying the above example with 3 "external" files (so there's
> no risk gdb accidentally parsed them when parsing the main function, for
> instance) and 3 types)
>
> $ clang++ -gsplit-dwarf -ggnu-pubnames -g b.cpp c.cpp -c
> $ llvm-objcopy --remove-section=.debug_gnu_pubnames
> --remove-section=.debug_gnu_pubtypes c.o
> $ clang++ -gsplit-dwarf -g -gno-pubnames d.cpp -c
> $ clang++ a.cpp b.o c.o d.o -g
>
> $ gdb --batch -ex "ptype at" -ex "ptype bt" -ex "ptype ct" ./a.out
>
> ...
>
> type = struct at {
>
>     int i;
>
> }
>
> type = struct bt {
>
>     int i;
>
> }
>
> type = struct ct {
>
>     int i;
>
> }
>
> Aborted
>
> Let's try that hand-crafted/corrupt pubnames.
>
> Hmm, looks like gdb didn't care about my pubnames?
>
> $ llvm-dwarfdump-tot a.out -debug-gnu-pubtypes
>
> a.out:  file format elf64-x86-64
>
>
> .debug_gnu_pubtypes contents:
>
> length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset =
> 0x00000000, unit_size = 0x00000030
>
> Offset     Linkage  Kind     Name
>
> 0x00000041 STATIC   TYPE     "int"
>
> length = 0x0000001f, format = DWARF32, version = 0x0002, unit_offset =
> 0x00000030, unit_size = 0x00000030
>
> Offset     Linkage  Kind     Name
>
> 0x00000031 EXTERNAL TYPE     "at"
>
> 0x00000041 STATIC   TYPE     "int"
>
> length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset =
> 0x00000060, unit_size = 0x00000030
>
> Offset     Linkage  Kind     Name
> <<<<<<<<<<<<<< hand modified to remove "bt" here >>>>>>>>>>
>
> 0x00000028 STATIC   TYPE     "int"
>
> length = 0x0000001f, format = DWARF32, version = 0x0002, unit_offset =
> 0x00000090, unit_size = 0x00000030
>
> Offset     Linkage  Kind     Name
>
> 0x00000031 EXTERNAL TYPE     "ct"
>
> 0x00000041 STATIC   TYPE     "int"
>
> $ gdb --batch -ex "ptype at" -ex "ptype bt" -ex "ptype ct" ./a.out
>
> Unable to determine compiler version.
>
> Skipping loading of libstdc++ pretty-printers for now.
>
> Loading libc++ pretty-printers.
>
> Non-google3 binary detected.
>
> type = struct at {
>
>     int i;
>
> }
> <<<<<<<<<< gdb still manages to find bt >>>>>>>>>>>
>
> type = struct bt {
>
>     int i;
>
> }
>
> type = struct ct {
>
>     int i;
>
> }
>
> Aborted
>
> So based on all that, I /think/ the answer is:
>
> If you are going to use a linker-generated gdb-index with Split DWARF,
> then you must have gnu-pubnames on every input file. (because it can't
> build indexes for CUs without pubnames because it doesn't have access to
> the unit contents (because they're split) - in non-split cases, 'gold' will
> build the index itself by parsing the DWARF, I don't think 'lld' can do
> that, so if you're using lld, this advice applies to non-split DWARF too
> (either index everything, or don't have an index))
> But you'll have a really slow debugging experience if you don't do that -
> but, so far as I can tell, it looks like it'll be correct, just slow.
>
> But I'm super not sure about all of this. The "gdb only handles Split
> DWARF with an index" may be rumor, rumor that I accidentally promoted as
> fact based on some misunderstandings/incomplete experiments. Or maybe
> there's some truth to it I don't know how to reproduce...
>
> - Dave
>
>
> Thank You
> Alex
>
> ________________________________
> From: Sterling Augustine <saugustine@google.com>
> Sent: Thursday, January 7, 2021 5:48 PM
> To: Alexander Yermolovich <ayermolo@fb.com>
> Cc: gdb@sourceware.org <gdb@sourceware.org>
> Subject: Re: GDB and debug fission
>
> On Thu, Jan 7, 2021 at 5:25 PM Alexander Yermolovich via Gdb
> <gdb@sourceware.org> wrote:
> >
> > Hello.
> >
> > For latest gdb to work with -gsplit-dwarf debug information generated by
> clang, either in split or single mode does it need gdb_index or pubnames?
> > In normal case where debug information is part of executable gdb_index
> is nice to speed up startup time, and I think I read pubnames is not used,
> but with debug fission are either gdb_index or pubnames necessary?
>
> For gdb to work with split-dwarf debug info, it needs a gdb_index.
> That can be generated in several ways. Gdb can build one itself--there
> is a script somewhere to add a gdb index.
>
> But it is somewhat easier to have the linker you use generate
> gdb_index for you (both gnu-ld and llvm's lld can do this). They do
> this by reading the .gnu_pubnames section, so in some way, you need
> both pubnames *and* an index.
>
> So you would ordinarily use the following commands:
>
> $(CC) $(normal_arguments) -ggnu-pubnames
> $(LD)  $(normal_arguments) -Wl,--gdb-index
>
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: GDB and debug fission
  2021-01-30  1:06           ` David Blaikie
@ 2021-02-01 20:07             ` Alexander Yermolovich
  2021-02-01 20:14               ` David Blaikie
  0 siblings, 1 reply; 12+ messages in thread
From: Alexander Yermolovich @ 2021-02-01 20:07 UTC (permalink / raw)
  To: David Blaikie; +Cc: Jorge Gorbe Moya, Sterling Augustine, gdb

I tried creating dwp, even without deleting dwo I see:
(gdb) ptype t1
No symbol "t1" in current context.
(gdb) start
Temporary breakpoint 1 at 0x4005ca: file main.cpp, line 3.
Starting program: /data/users/ayermolo/tasks/T81935790/main
warning: Loadable section ".note.gnu.property" outside of ELF segments
warning: Loadable section ".note.gnu.property" outside of ELF segments

Temporary breakpoint 1, main () at main.cpp:3
3 int main() { t1 v1; }
(gdb) ptype t1
No symbol "t1" in current context.

I guess it makes sense since I think gdb will just use dwp if it sees it in same directory.
With -Wl,--gdb-index I see same behavior as you. Everything gets resovled.

I see same behavior with TOT clang.

Alex
________________________________
From: David Blaikie <dblaikie@gmail.com>
Sent: Friday, January 29, 2021 5:06 PM
To: Alexander Yermolovich <ayermolo@fb.com>
Cc: Jorge Gorbe Moya <jgorbe@google.com>; Sterling Augustine <saugustine@google.com>; gdb@sourceware.org <gdb@sourceware.org>
Subject: Re: GDB and debug fission

Ah, you might need a dwp to reproduce this. Try building a dwp for the .dwo and deleting the dwo?



On Fri, Jan 29, 2021 at 4:42 PM Alexander Yermolovich <ayermolo@fb.com<mailto:ayermolo@fb.com>> wrote:
I tried it locally with:

struct t1 { int x; };

int main() { t1 v1; }
Using your commands, but with g++ (GCC) 8.4.1 20200928 (Red Hat 8.4.1-1)/gold and TOT clang++/lld.
GNU gdb (GDB) 9.1
For me it was able to resolve t1.
Some kind of regression with TOT gcc?

Alex
________________________________
From: David Blaikie <dblaikie@gmail.com<mailto:dblaikie@gmail.com>>
Sent: Friday, January 29, 2021 12:34 PM
To: Alexander Yermolovich <ayermolo@fb.com<mailto:ayermolo@fb.com>>; Jorge Gorbe Moya <jgorbe@google.com<mailto:jgorbe@google.com>>
Cc: Sterling Augustine <saugustine@google.com<mailto:saugustine@google.com>>; gdb@sourceware.org<mailto:gdb@sourceware.org> <gdb@sourceware.org<mailto:gdb@sourceware.org>>
Subject: Re: GDB and debug fission

Well, I found one place where the index seems necessary: Type units:

$ g++-tot a.cpp -fdebug-types-section -gdwarf-4 -gsplit-dwarf -c
$ g++-tot a.o -fuse-ld=gold
$ gdb ./a.out
...
(gdb) ptype t1
No symbol "t1" in current context.
(gdb) start
Temporary breakpoint 1 at 0x401106: file a.cpp, line 3.
Starting program: /usr/local/google/home/blaikie/dev/scratch/a.out

Temporary breakpoint 1, main () at a.cpp:3
3       int main() { t1 v1; }
(gdb) ptype t1
type = const float

But if you add -Wl,--gdb-index to the link command - it works correctly, with t1 being found and rendered.

On Thu, Jan 7, 2021 at 7:16 PM David Blaikie <dblaikie@gmail.com<mailto:dblaikie@gmail.com>> wrote:


On Thu, Jan 7, 2021 at 6:13 PM Alexander Yermolovich via Gdb <gdb@sourceware.org<mailto:gdb@sourceware.org>> wrote:
Thanks for clarification.
Yep I saw LLD builds gdb_index using gnu-pubnames. It just wasn't clear to me if gdb needs it with split-dwarf. I saw a comment on one of llvm reviews from couple years ago about it, but things might have changed since then. So thought I would ask. 🙂

Without gdb_index and gnu_pubnames what will be the behavior of gdb?
I tried a toy example locally with split-dwarf without gdb_index and pubnames and it seemed to work with binary compiled with -O2 and -g2.
By work I mean I was able to step through code and print same variables as when I compiled it with monolithic debug information.

Hmm - so far, I haven't been able to reproduce the failures I've seen in the past - it's possible I've made mistakes in the past and promoted the idea that gdb requires an index when using Split DWARF.

What /does/ seem to be the case is that if you do create a gdb-index, it must be comprehensive - you must have built all your objects (that have DWARF) with -ggnu-pubnames, because it looks like gdb is assuming the index is comprehensive.

Here's my example:

$ cat a.cpp

struct t1 { int x; };

void a() {

  t1 v1 = {3};

}

$ cat b.cpp

void a();

int main() {

  a();

}

$ clang++ a.cpp b.cpp -gsplit-dwarf -g -gno-pubnames

$ gdb --batch -ex "ptype t1" ./a.out

...

type = struct t1 {

    int x;

}

Aborted

$ clang++ a.cpp b.cpp -gsplit-dwarf -g -Wl,--gdb-index -fuse-ld=lld

$ gdb --batch -ex "ptype t1" ./a.out

...

type = struct t1 {

    int x;

}

Aborted

$ clang++ a.cpp b.cpp -gsplit-dwarf -g -gno-pubnames -Wl,--gdb-index -fuse-ld=lld

$ gdb --batch -ex "ptype t1" ./a.out

...

No symbol "t1" in current context.


And just for some added complexity... let's check if gdb can appropriately respect DW_AT_GNU_pubnames on CUs without an index.

Hmm, seems it doesn't (or, at least, it doesn't worry about DW_AT_GNU_pubnames, perhaps it relies on checking the contents of the debug_gnu_pubnames/pubtypes section to see which units are covered by names? Or it's ignoring the contents entirely... - would have to hand-craft a dodgy debug_gnu_pub* section to test whether it's using it at all)

(expanding/modifying the above example with 3 "external" files (so there's no risk gdb accidentally parsed them when parsing the main function, for instance) and 3 types)


$ clang++ -gsplit-dwarf -ggnu-pubnames -g b.cpp c.cpp -c
$ llvm-objcopy --remove-section=.debug_gnu_pubnames --remove-section=.debug_gnu_pubtypes c.o
$ clang++ -gsplit-dwarf -g -gno-pubnames d.cpp -c
$ clang++ a.cpp b.o c.o d.o -g

$ gdb --batch -ex "ptype at" -ex "ptype bt" -ex "ptype ct" ./a.out

...

type = struct at {

    int i;

}

type = struct bt {

    int i;

}

type = struct ct {

    int i;

}

Aborted

Let's try that hand-crafted/corrupt pubnames.

Hmm, looks like gdb didn't care about my pubnames?


$ llvm-dwarfdump-tot a.out -debug-gnu-pubtypes

a.out:  file format elf64-x86-64


.debug_gnu_pubtypes contents:

length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset = 0x00000000, unit_size = 0x00000030

Offset     Linkage  Kind     Name

0x00000041 STATIC   TYPE     "int"

length = 0x0000001f, format = DWARF32, version = 0x0002, unit_offset = 0x00000030, unit_size = 0x00000030

Offset     Linkage  Kind     Name

0x00000031 EXTERNAL TYPE     "at"

0x00000041 STATIC   TYPE     "int"

length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset = 0x00000060, unit_size = 0x00000030

Offset     Linkage  Kind     Name
<<<<<<<<<<<<<< hand modified to remove "bt" here >>>>>>>>>>

0x00000028 STATIC   TYPE     "int"

length = 0x0000001f, format = DWARF32, version = 0x0002, unit_offset = 0x00000090, unit_size = 0x00000030

Offset     Linkage  Kind     Name

0x00000031 EXTERNAL TYPE     "ct"

0x00000041 STATIC   TYPE     "int"

$ gdb --batch -ex "ptype at" -ex "ptype bt" -ex "ptype ct" ./a.out

Unable to determine compiler version.

Skipping loading of libstdc++ pretty-printers for now.

Loading libc++ pretty-printers.

Non-google3 binary detected.

type = struct at {

    int i;

}
<<<<<<<<<< gdb still manages to find bt >>>>>>>>>>>

type = struct bt {

    int i;

}

type = struct ct {

    int i;

}

Aborted

So based on all that, I /think/ the answer is:

If you are going to use a linker-generated gdb-index with Split DWARF, then you must have gnu-pubnames on every input file. (because it can't build indexes for CUs without pubnames because it doesn't have access to the unit contents (because they're split) - in non-split cases, 'gold' will build the index itself by parsing the DWARF, I don't think 'lld' can do that, so if you're using lld, this advice applies to non-split DWARF too (either index everything, or don't have an index))
But you'll have a really slow debugging experience if you don't do that - but, so far as I can tell, it looks like it'll be correct, just slow.

But I'm super not sure about all of this. The "gdb only handles Split DWARF with an index" may be rumor, rumor that I accidentally promoted as fact based on some misunderstandings/incomplete experiments. Or maybe there's some truth to it I don't know how to reproduce...

- Dave

Thank You
Alex

________________________________
From: Sterling Augustine <saugustine@google.com<mailto:saugustine@google.com>>
Sent: Thursday, January 7, 2021 5:48 PM
To: Alexander Yermolovich <ayermolo@fb.com<mailto:ayermolo@fb.com>>
Cc: gdb@sourceware.org<mailto:gdb@sourceware.org> <gdb@sourceware.org<mailto:gdb@sourceware.org>>
Subject: Re: GDB and debug fission

On Thu, Jan 7, 2021 at 5:25 PM Alexander Yermolovich via Gdb
<gdb@sourceware.org<mailto:gdb@sourceware.org>> wrote:
>
> Hello.
>
> For latest gdb to work with -gsplit-dwarf debug information generated by clang, either in split or single mode does it need gdb_index or pubnames?
> In normal case where debug information is part of executable gdb_index is nice to speed up startup time, and I think I read pubnames is not used, but with debug fission are either gdb_index or pubnames necessary?

For gdb to work with split-dwarf debug info, it needs a gdb_index.
That can be generated in several ways. Gdb can build one itself--there
is a script somewhere to add a gdb index.

But it is somewhat easier to have the linker you use generate
gdb_index for you (both gnu-ld and llvm's lld can do this). They do
this by reading the .gnu_pubnames section, so in some way, you need
both pubnames *and* an index.

So you would ordinarily use the following commands:

$(CC) $(normal_arguments) -ggnu-pubnames
$(LD)  $(normal_arguments) -Wl,--gdb-index

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: GDB and debug fission
  2021-02-01 20:07             ` Alexander Yermolovich
@ 2021-02-01 20:14               ` David Blaikie
  0 siblings, 0 replies; 12+ messages in thread
From: David Blaikie @ 2021-02-01 20:14 UTC (permalink / raw)
  To: Alexander Yermolovich; +Cc: Jorge Gorbe Moya, Sterling Augustine, gdb

Glad to hear you can reproduce this - so, yeah, there's at least one place
where gdb has impaired behavior in the absence of an index when using split
DWARF.

On Mon, Feb 1, 2021 at 12:07 PM Alexander Yermolovich <ayermolo@fb.com>
wrote:

> I tried creating dwp, even without deleting dwo I see:
> (gdb) ptype t1
> No symbol "t1" in current context.
> (gdb) start
> Temporary breakpoint 1 at 0x4005ca: file main.cpp, line 3.
> Starting program: /data/users/ayermolo/tasks/T81935790/main
> warning: Loadable section ".note.gnu.property" outside of ELF segments
> warning: Loadable section ".note.gnu.property" outside of ELF segments
>
> Temporary breakpoint 1, main () at main.cpp:3
> 3 int main() { t1 v1; }
> (gdb) ptype t1
> No symbol "t1" in current context.
>
> I guess it makes sense since I think gdb will just use dwp if it sees it
> in same directory.
> With -Wl,--gdb-index I see same behavior as you. Everything gets resovled.
>
> I see same behavior with TOT clang.
>
> Alex
> ------------------------------
> *From:* David Blaikie <dblaikie@gmail.com>
> *Sent:* Friday, January 29, 2021 5:06 PM
> *To:* Alexander Yermolovich <ayermolo@fb.com>
> *Cc:* Jorge Gorbe Moya <jgorbe@google.com>; Sterling Augustine <
> saugustine@google.com>; gdb@sourceware.org <gdb@sourceware.org>
> *Subject:* Re: GDB and debug fission
>
> Ah, you might need a dwp to reproduce this. Try building a dwp for the
> .dwo and deleting the dwo?
>
>
>
> On Fri, Jan 29, 2021 at 4:42 PM Alexander Yermolovich <ayermolo@fb.com>
> wrote:
>
> I tried it locally with:
>
> struct t1 { int x; };
>
> int main() { t1 v1; }
> Using your commands, but with g++ (GCC) 8.4.1 20200928 (Red Hat
> 8.4.1-1)/gold and TOT clang++/lld.
> GNU gdb (GDB) 9.1
> For me it was able to resolve t1.
> Some kind of regression with TOT gcc?
>
> Alex
> ------------------------------
> *From:* David Blaikie <dblaikie@gmail.com>
> *Sent:* Friday, January 29, 2021 12:34 PM
> *To:* Alexander Yermolovich <ayermolo@fb.com>; Jorge Gorbe Moya <
> jgorbe@google.com>
> *Cc:* Sterling Augustine <saugustine@google.com>; gdb@sourceware.org <
> gdb@sourceware.org>
> *Subject:* Re: GDB and debug fission
>
> Well, I found one place where the index seems necessary: Type units:
>
> $ g++-tot a.cpp -fdebug-types-section -gdwarf-4 -gsplit-dwarf -c
> $ g++-tot a.o -fuse-ld=gold
> $ gdb ./a.out
> ...
> (gdb) ptype t1
> No symbol "t1" in current context.
> (gdb) start
> Temporary breakpoint 1 at 0x401106: file a.cpp, line 3.
> Starting program: /usr/local/google/home/blaikie/dev/scratch/a.out
>
> Temporary breakpoint 1, main () at a.cpp:3
> 3       int main() { t1 v1; }
> (gdb) ptype t1
> type = const float
>
> But if you add -Wl,--gdb-index to the link command - it works correctly,
> with t1 being found and rendered.
>
> On Thu, Jan 7, 2021 at 7:16 PM David Blaikie <dblaikie@gmail.com> wrote:
>
>
>
> On Thu, Jan 7, 2021 at 6:13 PM Alexander Yermolovich via Gdb <
> gdb@sourceware.org> wrote:
>
> Thanks for clarification.
> Yep I saw LLD builds gdb_index using gnu-pubnames. It just wasn't clear to
> me if gdb needs it with split-dwarf. I saw a comment on one of llvm reviews
> from couple years ago about it, but things might have changed since then.
> So thought I would ask. 🙂
>
> Without gdb_index and gnu_pubnames what will be the behavior of gdb?
> I tried a toy example locally with split-dwarf without gdb_index and
> pubnames and it seemed to work with binary compiled with -O2 and -g2.
> By work I mean I was able to step through code and print same variables as
> when I compiled it with monolithic debug information.
>
>
> Hmm - so far, I haven't been able to reproduce the failures I've seen in
> the past - it's possible I've made mistakes in the past and promoted the
> idea that gdb requires an index when using Split DWARF.
>
> What /does/ seem to be the case is that if you do create a gdb-index, it
> must be comprehensive - you must have built all your objects (that have
> DWARF) with -ggnu-pubnames, because it looks like gdb is assuming the index
> is comprehensive.
>
> Here's my example:
>
> $ cat a.cpp
>
> struct t1 { int x; };
>
> void a() {
>
>   t1 v1 = {3};
>
> }
>
> $ cat b.cpp
>
> void a();
>
> int main() {
>
>   a();
>
> }
>
> $ clang++ a.cpp b.cpp -gsplit-dwarf -g -gno-pubnames
>
> $ gdb --batch -ex "ptype t1" ./a.out
>
> ...
>
> type = struct t1 {
>
>     int x;
>
> }
>
> Aborted
>
> $ clang++ a.cpp b.cpp -gsplit-dwarf -g -Wl,--gdb-index -fuse-ld=lld
>
> $ gdb --batch -ex "ptype t1" ./a.out
>
> ...
>
> type = struct t1 {
>
>     int x;
>
> }
>
> Aborted
>
> $ clang++ a.cpp b.cpp -gsplit-dwarf -g -gno-pubnames -Wl,--gdb-index
> -fuse-ld=lld
>
> $ gdb --batch -ex "ptype t1" ./a.out
>
> ...
>
> No symbol "t1" in current context.
>
> And just for some added complexity... let's check if gdb can appropriately
> respect DW_AT_GNU_pubnames on CUs without an index.
>
> Hmm, seems it doesn't (or, at least, it doesn't worry about
> DW_AT_GNU_pubnames, perhaps it relies on checking the contents of the
> debug_gnu_pubnames/pubtypes section to see which units are covered by
> names? Or it's ignoring the contents entirely... - would have to hand-craft
> a dodgy debug_gnu_pub* section to test whether it's using it at all)
>
> (expanding/modifying the above example with 3 "external" files (so there's
> no risk gdb accidentally parsed them when parsing the main function, for
> instance) and 3 types)
>
> $ clang++ -gsplit-dwarf -ggnu-pubnames -g b.cpp c.cpp -c
> $ llvm-objcopy --remove-section=.debug_gnu_pubnames
> --remove-section=.debug_gnu_pubtypes c.o
> $ clang++ -gsplit-dwarf -g -gno-pubnames d.cpp -c
> $ clang++ a.cpp b.o c.o d.o -g
>
> $ gdb --batch -ex "ptype at" -ex "ptype bt" -ex "ptype ct" ./a.out
>
> ...
>
> type = struct at {
>
>     int i;
>
> }
>
> type = struct bt {
>
>     int i;
>
> }
>
> type = struct ct {
>
>     int i;
>
> }
>
> Aborted
>
> Let's try that hand-crafted/corrupt pubnames.
>
> Hmm, looks like gdb didn't care about my pubnames?
>
> $ llvm-dwarfdump-tot a.out -debug-gnu-pubtypes
>
> a.out:  file format elf64-x86-64
>
>
> .debug_gnu_pubtypes contents:
>
> length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset =
> 0x00000000, unit_size = 0x00000030
>
> Offset     Linkage  Kind     Name
>
> 0x00000041 STATIC   TYPE     "int"
>
> length = 0x0000001f, format = DWARF32, version = 0x0002, unit_offset =
> 0x00000030, unit_size = 0x00000030
>
> Offset     Linkage  Kind     Name
>
> 0x00000031 EXTERNAL TYPE     "at"
>
> 0x00000041 STATIC   TYPE     "int"
>
> length = 0x00000017, format = DWARF32, version = 0x0002, unit_offset =
> 0x00000060, unit_size = 0x00000030
>
> Offset     Linkage  Kind     Name
> <<<<<<<<<<<<<< hand modified to remove "bt" here >>>>>>>>>>
>
> 0x00000028 STATIC   TYPE     "int"
>
> length = 0x0000001f, format = DWARF32, version = 0x0002, unit_offset =
> 0x00000090, unit_size = 0x00000030
>
> Offset     Linkage  Kind     Name
>
> 0x00000031 EXTERNAL TYPE     "ct"
>
> 0x00000041 STATIC   TYPE     "int"
>
> $ gdb --batch -ex "ptype at" -ex "ptype bt" -ex "ptype ct" ./a.out
>
> Unable to determine compiler version.
>
> Skipping loading of libstdc++ pretty-printers for now.
>
> Loading libc++ pretty-printers.
>
> Non-google3 binary detected.
>
> type = struct at {
>
>     int i;
>
> }
> <<<<<<<<<< gdb still manages to find bt >>>>>>>>>>>
>
> type = struct bt {
>
>     int i;
>
> }
>
> type = struct ct {
>
>     int i;
>
> }
>
> Aborted
>
> So based on all that, I /think/ the answer is:
>
> If you are going to use a linker-generated gdb-index with Split DWARF,
> then you must have gnu-pubnames on every input file. (because it can't
> build indexes for CUs without pubnames because it doesn't have access to
> the unit contents (because they're split) - in non-split cases, 'gold' will
> build the index itself by parsing the DWARF, I don't think 'lld' can do
> that, so if you're using lld, this advice applies to non-split DWARF too
> (either index everything, or don't have an index))
> But you'll have a really slow debugging experience if you don't do that -
> but, so far as I can tell, it looks like it'll be correct, just slow.
>
> But I'm super not sure about all of this. The "gdb only handles Split
> DWARF with an index" may be rumor, rumor that I accidentally promoted as
> fact based on some misunderstandings/incomplete experiments. Or maybe
> there's some truth to it I don't know how to reproduce...
>
> - Dave
>
>
> Thank You
> Alex
>
> ________________________________
> From: Sterling Augustine <saugustine@google.com>
> Sent: Thursday, January 7, 2021 5:48 PM
> To: Alexander Yermolovich <ayermolo@fb.com>
> Cc: gdb@sourceware.org <gdb@sourceware.org>
> Subject: Re: GDB and debug fission
>
> On Thu, Jan 7, 2021 at 5:25 PM Alexander Yermolovich via Gdb
> <gdb@sourceware.org> wrote:
> >
> > Hello.
> >
> > For latest gdb to work with -gsplit-dwarf debug information generated by
> clang, either in split or single mode does it need gdb_index or pubnames?
> > In normal case where debug information is part of executable gdb_index
> is nice to speed up startup time, and I think I read pubnames is not used,
> but with debug fission are either gdb_index or pubnames necessary?
>
> For gdb to work with split-dwarf debug info, it needs a gdb_index.
> That can be generated in several ways. Gdb can build one itself--there
> is a script somewhere to add a gdb index.
>
> But it is somewhat easier to have the linker you use generate
> gdb_index for you (both gnu-ld and llvm's lld can do this). They do
> this by reading the .gnu_pubnames section, so in some way, you need
> both pubnames *and* an index.
>
> So you would ordinarily use the following commands:
>
> $(CC) $(normal_arguments) -ggnu-pubnames
> $(LD)  $(normal_arguments) -Wl,--gdb-index
>
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2021-02-01 20:15 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-08  1:25 GDB and debug fission Alexander Yermolovich
2021-01-08  1:48 ` Sterling Augustine
2021-01-08  2:12   ` Alexander Yermolovich
2021-01-08  3:16     ` David Blaikie
2021-01-08 18:52       ` Alexander Yermolovich
2021-01-08 19:01         ` David Blaikie
2021-01-29 20:34       ` David Blaikie
2021-01-30  0:42         ` Alexander Yermolovich
2021-01-30  1:06           ` David Blaikie
2021-02-01 20:07             ` Alexander Yermolovich
2021-02-01 20:14               ` David Blaikie
2021-01-08  2:17   ` David Blaikie

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).