Skip to content

debuginfo/evec-in-struct.rs fails on master #17808

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
bkoropoff opened this issue Oct 5, 2014 · 22 comments
Closed

debuginfo/evec-in-struct.rs fails on master #17808

bkoropoff opened this issue Oct 5, 2014 · 22 comments
Labels
A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.)

Comments

@bkoropoff
Copy link
Contributor

Relevant output:

    error: line not found in debugger output: $2 = {x = {6, 7, 8}, y = {{9, 10}, {11, 12}}}

...

    $2 = {x = {6, 7, 8}, y = {{9, 10}, {12, 0}}}

GDB version:

GNU gdb (GDB) Fedora 7.7.1-19.fc20

I'm not sure why this fails on my system and not on the build bots.

@bkoropoff
Copy link
Contributor Author

This seems to have started occuring after upgrading llvm

@huonw huonw added the A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) label Oct 5, 2014
@brson
Copy link
Contributor

brson commented Oct 7, 2014

cc @michaelwoerister

@michaelwoerister
Copy link
Member

Interesting. I'll look into it.

@michaelwoerister
Copy link
Member

I can't reproduce that. Are you doing anything special in your build? Any special configure-flags for example? Also, can you post the whole output from the test?

@bkoropoff
Copy link
Contributor Author

I removed my rust installation and built from a clean build directory with no configure options and still reproduced it. Full output:

$ make check-stage1-debuginfo-gdb TESTNAME=evec-in-struct
cfg: build triple x86_64-unknown-linux-gnu
cfg: host triples x86_64-unknown-linux-gnu
cfg: target triples x86_64-unknown-linux-gnu
cfg: enabling more debugging (CFG_ENABLE_DEBUG)
cfg: host for x86_64-unknown-linux-gnu is x86_64
cfg: os for x86_64-unknown-linux-gnu is unknown-linux-gnu
cfg: using CC=gcc (CFG_CC)
cfg: no lualatex found, deferring to xelatex
cfg: no xelatex found, deferring to pdflatex
cfg: no pdflatex found, disabling LaTeX docs
cfg: no pandoc found, omitting PDF and EPUB docs
cfg: no llnextgen found, omitting grammar-verification
cfg: including test rules
cfg: antlr4 not available, skipping lexer test...
run debuginfo-gdb [x86_64-unknown-linux-gnu]: x86_64-unknown-linux-gnu/stage1/bin/compiletest

running 1 test
test [debuginfo-gdb] debuginfo/evec-in-struct.rs ... FAILED

using metrics ratchet: tmp/check-stage1-T-x86_64-unknown-linux-gnu-H-x86_64-unknown-linux-gnu-debuginfo-gdb-metrics.json
result of ratchet: 0 metrics added, 0 removed, 0 improved, 0 regressed, 0 noise
updated ratchet file

failures:

---- [debuginfo-gdb] debuginfo/evec-in-struct.rs stdout ----
    NOTE: compiletest thinks it is using GDB version 7.7

    error: line not found in debugger output: $2 = {x = {6, 7, 8}, y = {{9, 10}, {11, 12}}}

    status: exit code: 0
    command: gdb -quiet -batch -nx -command=x86_64-unknown-linux-gnu/test/debuginfo-gdb/evec-in-struct.debugger.script
    stdout:
    ------------------------------------------
    GNU gdb (GDB) Fedora 7.7.1-19.fc20
    Copyright (C) 2014 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "x86_64-redhat-linux-gnu".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>.
    Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.
    For help, type "help".
    Type "apropos word" to search for commands related to "word".
    Breakpoint 1 at 0xa80: file /home/bkoropoff/Source/rust/src/test/debuginfo/evec-in-struct.rs, line 112.
    static void evec-in-struct::zzz(void);
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib64/libthread_db.so.1".

    Breakpoint 1, evec-in-struct::zzz () at /home/bkoropoff/Source/rust/src/test/debuginfo/evec-in-struct.rs:112
    112 fn zzz() { () }
    evec-in-struct::main () at /home/bkoropoff/Source/rust/src/test/debuginfo/evec-in-struct.rs:110
    110 }
    $1 = {x = {0, 1, 2}, y = -3, z = {4.5, 5.5}}
    $2 = {x = {6, 7, 8}, y = {{9, 10}, {12, 0}}}
    $3 = {x = {13, 14}, y = {15, 16}}
    $4 = {x = {17, 18, 19, 20, 21}}
    $5 = {x = {22, 23}, y = {24, 25}}
    A debugging session is active.

        Inferior 1 [process 27683] will be killed.

    Quit anyway? (y or n) [answered Y; input not from terminal]

    ------------------------------------------
    stderr:
    ------------------------------------------

    ------------------------------------------

    task '[debuginfo-gdb] debuginfo/evec-in-struct.rs' failed at 'explicit failure', /home/bkoropoff/Source/rust/src/compiletest/runtest.rs:1431



failures:
    [debuginfo-gdb] debuginfo/evec-in-struct.rs

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured

task '<main>' failed at 'Some tests failed', /home/bkoropoff/Source/rust/src/compiletest/compiletest.rs:255
make: *** [tmp/check-stage1-T-x86_64-unknown-linux-gnu-H-x86_64-unknown-linux-gnu-debuginfo-gdb.ok] Error 101

@bkoropoff
Copy link
Contributor Author

Reduced test case:

fn main() {
    let _foo = [[1u],[1]];
}

gdb output:

(gdb) p _foo
$1 = {{1}, {140737488347040}}

@michaelwoerister
Copy link
Member

Thanks a lot for the detailed information. I'll try to reproduce it again today. I wasn't able to do so so far, although you seem to have a very standard setup (Linux x86_64, recent GDB, no custom LLVM, ...)

@michaelwoerister
Copy link
Member

So, I installed Fedora 20 in a VM and wouldn't you believe it, I can reproduce the bug exactly as you describe it. This is going to be interesting :)

@michaelwoerister
Copy link
Member

LLVM has changed the way it encodes fixed-size arrays a few weeks back (llvm-mirror/llvm@06c1373) and for some reason GDB can't handle that on Fedora. I'm not sure yet how to deal with this problem since it doesn't seem to occur anywhere else and LLVM's new encoding is just as legal as the old one...

@bkoropoff
Copy link
Contributor Author

GDB seems to think the inner [uint, ..1] has padding that doesn't exist:

(gdb) p sizeof(_foo[0])
$1 = 16
(gdb) p sizeof(_foo[0][0])
$2 = 8

So it's simply reading from the wrong offset when displaying the second element of the outer array. LLDB works fine.

@bkoropoff
Copy link
Contributor Author

I just tested with stock gdb 7.7.1 built from source, and it worked! This suggests the issue is with a patch applied by Fedora. I'll grab the srpm and try to track it down.

@bkoropoff
Copy link
Contributor Author

I imported the entire patch stack into git and bisected down to gdb-archer.patch, which makes extensive changes to DWARF handling. It seems to be from a gdb development branch: https://sourceware.org/gdb/wiki/ProjectArcher

@michaelwoerister
Copy link
Member

Maybe Tom @tromey can help us out here?

tl;dr for Tom: LLVM changed the DWARF encoding of DW_TAG_subrange_type DIEs to use DW_AT_count instead of DW_AT_upper_bound. Most GDB versions can deal with this just fine but the one on Fedora, which contains patches from Project Archer, has problems handling this.

Do you have any suggestions on how to deal with this? Should we just report this in GDB's normal bug tracker? Any pointers from you would be much appreciated.

@tromey
Copy link
Contributor

tromey commented Nov 5, 2014

I am not sure offhand what the problem is, but if it happens with the Fedora gdb and not with the FSF gdb, then the correct place to report it is Red Hat's bugzilla. I can handle this if you like, just let me know.

@tromey
Copy link
Contributor

tromey commented Nov 5, 2014

... though come to think of it, it would be nice to have a dump of the relevant DWARF handy for the bug report. Could you get that? I didn't see it in this bug.

@michaelwoerister
Copy link
Member

Thanks Tom, I'll post the relevant DWARF here asap.

@michaelwoerister
Copy link
Member

As a reference, for the following program...

int main() {
    int _foo[2][1] = {{1}, {1}};

    return 0;
}

... GCC produces the following DWARF:


.debug_info

COMPILE_UNIT<header overall offset = 0x00000000>:
< 0><0x0000000b>  DW_TAG_compile_unit
                    DW_AT_producer              GNU C 4.8.3 20140911 (Red Hat 4.8.3-7) -mtune=generic -march=x86-64 -g
                    DW_AT_language              DW_LANG_C89
                    DW_AT_name                  ./cversion.c
                    DW_AT_comp_dir              /home/mw/stuff/evec-issue
                    DW_AT_low_pc                0x004004f0
                    DW_AT_high_pc               <offset-from-lowpc>25
                    DW_AT_stmt_list             0x00000000

LOCAL_SYMBOLS:
< 1><0x0000002d>    DW_TAG_subprogram
                      DW_AT_external              yes(1)
                      DW_AT_name                  main
                      DW_AT_decl_file             0x00000001 ./cversion.c
                      DW_AT_decl_line             0x00000002
                      DW_AT_type                  <0x0000005d>
                      DW_AT_low_pc                0x004004f0
                      DW_AT_high_pc               <offset-from-lowpc>25
                      DW_AT_frame_base            len 0x0001: 9c: DW_OP_call_frame_cfa
                      DW_AT_GNU_all_call_sites    yes(1)
                      DW_AT_sibling               <0x0000005d>
< 2><0x0000004e>      DW_TAG_variable
                        DW_AT_name                  _foo
                        DW_AT_decl_file             0x00000001 ./cversion.c
                        DW_AT_decl_line             0x00000003
                        DW_AT_type                  <0x00000064>
                        DW_AT_location              len 0x0002: 9160: DW_OP_fbreg -32
< 1><0x0000005d>    DW_TAG_base_type
                      DW_AT_byte_size             0x00000004
                      DW_AT_encoding              DW_ATE_signed
                      DW_AT_name                  int
< 1><0x00000064>    DW_TAG_array_type
                      DW_AT_type                  <0x0000005d>
                      DW_AT_sibling               <0x0000007a>
< 2><0x0000006d>      DW_TAG_subrange_type
                        DW_AT_type                  <0x0000007a>
                        DW_AT_upper_bound           1
< 2><0x00000073>      DW_TAG_subrange_type
                        DW_AT_type                  <0x0000007a>
                        DW_AT_upper_bound           0
< 1><0x0000007a>    DW_TAG_base_type
                      DW_AT_byte_size             0x00000008
                      DW_AT_encoding              DW_ATE_unsigned
                      DW_AT_name                  sizetype

.debug_line: line number info for a single cu
Source lines (from CU-DIE at .debug_info offset 0x0000000b):

            NS new statement, BB new basic block, ET end of text sequence
            PE prologue end, EB epilogue begin
            IA=val ISA number, DI=val discriminator value
<pc>        [row,col] NS BB ET PE EB IS= DI= uri: "filepath"
0x004004f0  [   2, 0] NS uri: "/home/mw/stuff/evec-issue/./cversion.c"
0x004004f4  [   3, 0] NS
0x00400502  [   5, 0] NS
0x00400507  [   6, 0] NS
0x00400509  [   6, 0] NS ET

.debug_pubnames

.debug_macinfo

.debug_string
name at offset 0x00000000, length   25 is '/home/mw/stuff/evec-issue'
name at offset 0x0000001a, length    8 is 'sizetype'
name at offset 0x00000023, length   12 is './cversion.c'
name at offset 0x00000030, length   70 is 'GNU C 4.8.3 20140911 (Red Hat 4.8.3-7) -mtune=generic -march=x86-64 -g'
name at offset 0x00000077, length    4 is '_foo'
name at offset 0x0000007c, length    4 is 'main'

.debug_aranges

COMPILE_UNIT<header overall offset = 0x00000000>:
< 0><0x0000000b>  DW_TAG_compile_unit
                    DW_AT_producer              GNU C 4.8.3 20140911 (Red Hat 4.8.3-7) -mtune=generic -march=x86-64 -g
                    DW_AT_language              DW_LANG_C89
                    DW_AT_name                  ./cversion.c
                    DW_AT_comp_dir              /home/mw/stuff/evec-issue
                    DW_AT_low_pc                0x004004f0
                    DW_AT_high_pc               <offset-from-lowpc>25
                    DW_AT_stmt_list             0x00000000


arange starts at 0x004004f0, length of 0x00000019, cu_die_offset = 0x0000000b
arange end

The interesting part here is the DW_TAG_array_type with it's two nested sub-ranges. Fedora GDB can handle that. With the Rust equivalent (which I'll post as soon as LLVM is finished rebuilding) GDB gets the memory adressing wrong. Note that this only occurs for nested sub-ranges.

@michaelwoerister
Copy link
Member

So, here's the Rust version of the program:

fn main() {
    let _foo = [[1u],[1]];

    return;
}

The DWARF for it looks like this:

.debug_info

COMPILE_UNIT<header overall offset = 0x00000000>:
< 0><0x0000000b>  DW_TAG_compile_unit
                    DW_AT_producer              rustc version 0.13.0-dev (0ecf914ce 2014-10-30 15:06:08 +0500)
                    DW_AT_language              <Unknown LANG value 0x9000>
                    DW_AT_name                  ./rust-version.rs
                    DW_AT_stmt_list             0x00000000
                    DW_AT_comp_dir              /home/mw/stuff/evec-issue
                    DW_AT_low_pc                0x00000000
                    DW_AT_high_pc               <offset-from-lowpc>71

LOCAL_SYMBOLS:
< 1><0x0000002a>    DW_TAG_namespace
                      DW_AT_name                  rust-version
< 2><0x0000002f>      DW_TAG_subprogram
                        DW_AT_low_pc                0x00000000
                        DW_AT_high_pc               <offset-from-lowpc>71
                        DW_AT_frame_base            len 0x0001: 56: DW_OP_reg6
                        DW_AT_MIPS_linkage_name     _ZN12rust-version4mainE
                        DW_AT_name                  main
                        DW_AT_decl_file             0x00000001 /home/mw/stuff/evec-issue/rust-version.rs
                        DW_AT_decl_line             0x00000003
< 3><0x00000048>        DW_TAG_lexical_block
                          DW_AT_low_pc                0x00000029
                          DW_AT_high_pc               <offset-from-lowpc>30
< 4><0x00000055>          DW_TAG_variable
                            DW_AT_location              len 0x0002: 9170: DW_OP_fbreg -16
                            DW_AT_name                  _foo
                            DW_AT_decl_file             0x00000001 /home/mw/stuff/evec-issue/rust-version.rs
                            DW_AT_decl_line             0x00000004
                            DW_AT_type                  <0x00000066>
< 1><0x00000066>    DW_TAG_array_type
                      DW_AT_type                  <0x0000007a>
< 2><0x0000006b>      DW_TAG_subrange_type
                        DW_AT_type                  <0x00000081>
                        DW_AT_lower_bound           0
                        DW_AT_count                 0x00000002
< 2><0x00000072>      DW_TAG_subrange_type
                        DW_AT_type                  <0x00000081>
                        DW_AT_lower_bound           0
                        DW_AT_count                 0x00000001
< 1><0x0000007a>    DW_TAG_base_type
                      DW_AT_name                  uint
                      DW_AT_encoding              DW_ATE_unsigned
                      DW_AT_byte_size             0x00000008
< 1><0x00000081>    DW_TAG_base_type
                      DW_AT_name                  sizetype
                      DW_AT_byte_size             0x00000008
                      DW_AT_encoding              DW_ATE_unsigned

.debug_line: line number info for a single cu
Source lines (from CU-DIE at .debug_info offset 0x0000000b):

            NS new statement, BB new basic block, ET end of text sequence
            PE prologue end, EB epilogue begin
            IA=val ISA number, DI=val discriminator value
<pc>        [row,col] NS BB ET PE EB IS= DI= uri: "filepath"
0x00000000  [   3, 0] NS uri: "/home/mw/stuff/evec-issue/rust-version.rs"
0x00000029  [   4, 0] NS PE
0x0000003d  [   7, 0] NS
0x00000047  [   7, 0] NS ET

.debug_pubnames
global die-in-sect 0x0000002a, cu-in-sect 0x0000000b, die-in-cu 0x0000002a, cu-header-in-sect 0x00000000 'rust-version'
global die-in-sect 0x0000002f, cu-in-sect 0x0000000b, die-in-cu 0x0000002f, cu-header-in-sect 0x00000000 'main'

.debug_macinfo

.debug_string
name at offset 0x00000000, length   62 is 'rustc version 0.13.0-dev (0ecf914ce 2014-10-30 15:06:08 +0500)'
name at offset 0x0000003f, length   17 is './rust-version.rs'
name at offset 0x00000051, length   25 is '/home/mw/stuff/evec-issue'
name at offset 0x0000006b, length   12 is 'rust-version'
name at offset 0x00000078, length   23 is '_ZN12rust-version4mainE'
name at offset 0x00000090, length    4 is 'main'
name at offset 0x00000095, length    4 is '_foo'
name at offset 0x0000009a, length    4 is 'uint'
name at offset 0x0000009f, length    8 is 'sizetype'

As you can see, the DW_TAG_array_type looks pretty similar but the DW_TAG_subrange_type DIEs use DW_AT_lower_bound and DW_AT_count instead of DW_AT_lower_bound. This results in GDB reading some wrong value from memory:

(gdb) p _foo 
$1 = {{1}, {140737488347328}}

As far as I remember, omitting DW_AT_lower_bound did not help when I tried last week.

Let me know if you need anything else!

@tromey
Copy link
Contributor

tromey commented Nov 5, 2014

I opened a bug report: https://bugzilla.redhat.com/show_bug.cgi?id=1160826

@michaelwoerister
Copy link
Member

Thanks a lot!

@tromey
Copy link
Contributor

tromey commented Nov 6, 2014

Jan says that it is most likely the VLA patches. Fedora 21 will drop these and use the ones that went in upstream instead. So if you could, it would be worth trying the a newer gdb. You can find some RPMs here: http://rpmfind.net/linux/rpm2html/search.php?query=gdb; you'd want one marked "fc21".

@michaelwoerister
Copy link
Member

I can confirm that everything works as expected with the fc21 version of GDB.
I'll close this issue. Thanks for your help, Tom! And thanks for providing so much useful feedback, @bkoropoff!

lnicola pushed a commit to lnicola/rust that referenced this issue Aug 13, 2024
minor: log error when sysroot can't be discovered

Closes rust-lang#17808
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.)
Projects
None yet
Development

No branches or pull requests

5 participants