This is an archive of the discontinued LLVM Phabricator instance.

[llvm-dwarfdump] --gdb-index: fix uninitialized TuListOffset
ClosedPublic

Authored by MaskRay on Jun 19 2019, 12:44 AM.

Details

Summary

Unfortunately I can't make a test because I don't know how to produce a
non-empty types CU list.

Diff Detail

Event Timeline

MaskRay created this revision.Jun 19 2019, 12:44 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 19 2019, 12:44 AM

I don't know a way to create that list, too. lld definitely does not create it. Maybe, gold can help?

Anyway, for this patch, expanding existing dwarfdump-dump-gdbindex.test should be enough.

MaskRay added a comment.EditedJun 19 2019, 3:01 AM

I don't know a way to create that list, too. lld definitely does not create it. Maybe, gold can help?

Anyway, for this patch, expanding existing dwarfdump-dump-gdbindex.test should be enough.

lld definitely does not create .gdb_index:

// Write the address area.
Hdr->CuTypesOff = Buf - Start;
Hdr->AddressAreaOff = Buf - Start;

but I can't get gold --gdb-index to produce it, either, even if I compile a not-so-trivial program with gcc.

Yes, I saw the same lines in lld.

At least, we can check that we report the correct value for the offset, even if the list is empty. dwarfdump-dump-gdbindex.test already has such input binary, so you only need to add some CHECK: lines.

MaskRay updated this revision to Diff 205566.Jun 19 2019, 6:04 AM

Update test/DebugInfo/dwarfdump-dump-gdbindex.test

ikudrin accepted this revision.Jun 19 2019, 6:40 AM

LGTM. Thanks!

This revision is now accepted and ready to land.Jun 19 2019, 6:40 AM
This revision was automatically updated to reflect the committed changes.
dblaikie added inline comments.Jun 19 2019, 9:39 AM
llvm/trunk/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
141–148 ↗(On Diff #205574)

Is this loop still untested (since all the test cases have TuListSize of zero - so the body of this loop could be incorrect & no test would diagnose it? (eg: if you put "assert(false)" in the loop, does it fire?)

For test cases of this feature, you could either construct one by hand writing assembly - or it's possible (& probably better to check the format agrees with gdb) by using gdb to generate the index: https://www-zeuthen.desy.de/unix/unixguide/infohtml/gdb/Index-Files.html

MaskRay added a comment.EditedJun 25 2019, 3:26 AM

@dblaikie save gdb-index generates index files of version 8. gold/lld generate version 7, llvm-dwarfdump recognize version 7 but not 8...

mkdir dir
gdb a -batch -q -ex 'save gdb-index dir'
objcopy --add-section .gdb_index=dir/a.gdb-index --set-section-flags .gdb_index=readonly a b
% myllvm-dwarfdump -gdb-index b
b:      file format ELF64-x86-64

.gdb_index contents:

<error parsing>

@dblaikie save gdb-index generates index files of version 8. gold/lld generate version 7, llvm-dwarfdump recognize version 7 but not 8...

mkdir dir
gdb a -batch -q -ex 'save gdb-index dir'
objcopy --add-section .gdb_index=dir/a.gdb-index --set-section-flags .gdb_index=readonly a b
% myllvm-dwarfdump -gdb-index b
b:      file format ELF64-x86-64

.gdb_index contents:

<error parsing>

Perhaps an older version of GDB would produce the older index?

Ping

@dblaikie I'm thinking if we should support gdb index version 8.

This 2013 change bumped the index version from 7 to 8: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=796a7ff8234cfaa8ad1ab884c1c8dafe29b18d42 My take is that the index format doesn't change.

I tried the C example on https://sourceware.org/bugzilla/show_bug.cgi?id=15021 . Unfortunately, the produced .gdb_index from mkdir dir; gdb-8 a -batch -q -ex 'save gdb-index dir'; objcopy --add-section .gdb_index=dir/a.gdb-index --set-section-flags .gdb_index=readonly a b has an abnormal large "number of CU indices":

178|   // The constant pool. CU vectors are stored first, followed by strings.                                 
179|   // The first value is the number of CU indices in the vector. Each subsequent                           
180|   // value is the index and symbol attributes of a CU in the CU list.                                     
181|   for (uint32_t i = 0; i < CuVectorsTotal; ++i) {
182|     ConstantPoolVectors.emplace_back(0, SmallVector<uint32_t, 0>());                                      
183|     auto &Vec = ConstantPoolVectors.back();
184|     Vec.first = Offset - ConstantPoolOffset;
185| 
186|     uint32_t Num = Data.getU32(&Offset);
187|     for (uint32_t j = 0; j < Num; ++j)
188|       Vec.second.push_back(Data.getU32(&Offset));
(gdb) p/x Num
$12 = 0x306f6f66

(gdb_7.4.1-1_amd64.deb from http://snapshot.debian.org/package/gdb/7.4.1-1/ says it uses index version 5)

Older gdb is not easy to build:

% cd /tmp/p/gdb-7.6
% mkdir Release; cd Release; ../configure --disable-binutils --disable-gas --disable-gdb --disable-gold --disable-gprof --disable-ld --disable-werror --enable-gdb CFLAGS=-fpermissive CXXFLAGS=-fpermissive --disable-nls && time make -j all-gdb
../../gdb/amd64-linux-nat.c:485:1: error: conflicting types for ‘ps_get_thread_area’                           
 ps_get_thread_area (const struct ps_prochandle *ph,
MaskRay added a comment.EditedJul 9 2019, 3:53 AM

When an enum is used:

enum foo { foo0 };
int main () { return foo0; }

The built .gdb_index will have non-empty type CU list and have a weirdly encoded Num:

186| uint32_t Num = Data.getU32(&Offset); // Num can be very large
187| for (uint32_t j = 0; j < Num; ++j)
188| Vec.second.push_back(Data.getU32(&Offset));

I don't know what gdb does... D64396 may help the investigation a bit.