Skip to content
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

GDB pretty printer error when compiled with -Copt-level=1 #41970

Closed
nagisa opened this issue May 13, 2017 · 3 comments
Closed

GDB pretty printer error when compiled with -Copt-level=1 #41970

nagisa opened this issue May 13, 2017 · 3 comments
Labels
A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.)

Comments

@nagisa
Copy link
Member

nagisa commented May 13, 2017

When debugging the code from #41888 I noticed that this

fn main() {
    let _ = g((0, 0));
}

type P = (u32, u8); // one field must be ≥u32, the other field must be ≥u8
type R = Result<(), P>;

#[allow(dead_code)]
enum X {
    A(Box<X>),
    B(Box<X>),
    C, // B and C can be omitted, but they are added to ensure well-formed semantic
}

enum K {
    D
}

enum E {
    F(K), // must not be built-in type
    #[allow(dead_code)]
    G([X; 2]), // must present, can also be Vec<X> or (X, X), but not X or [X; 1] ...
}

fn g(mut pt: P) -> R {
    let mut y = None;
    loop {
        let status = if pt.0 == 0 {
            Some(E::F(K::D))
        } else {
            None
        };
        pt.0 = 1;

        match status {
            Some(infix_or_postfix) => {
                if let E::F(_op) = infix_or_postfix { // <- must be captured by value
                    y = Some(pt);
                    Ok(())?; // <- yes this line is needed
                }
            }
            _ => {
                Err(y.unwrap())? // <-- must use `?`, return Err won't trigger segfault
            }
        }
    }
}

when compiled with rustc test.rs -g -Copt-level=1 and run under gdb:

$ gdb test
GNU gdb (GDB) 7.12.1
(gdb) br test::g
Breakpoint 1 at 0x6b58: file /tmp/test.rs, line 36.
(gdb) r
Breakpoint 1, test::g (pt=<error reading variable: DWARF-2 expression error: `DW_OP_stack_value' operations must be used either alone or in conjunction with DW_OP_piece or DW_OP_bit_piece.>) at /tmp/test.rs:36
36	            Some(infix_or_postfix) => {

Works fine in lldb, works fine without optimisation.

@nagisa nagisa added the A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) label May 13, 2017
@tromey
Copy link
Contributor

tromey commented May 28, 2017

With a more recent gdb I get a different error:

(gdb) p pt
access outside bounds of object referenced via synthetic pointer

At least for me the location expressions look reasonable:

(gdb) info addr pt
Symbol "pt" is multi-location:
  Range 0x55555555b748-0x55555555b794: a complex DWARF expression:
     0: DW_OP_constu 0
     2: DW_OP_stack_value
    [4-byte piece], and a complex DWARF expression:
     0: DW_OP_constu 0
     2: DW_OP_stack_value
    [1-byte piece]
  Range 0x55555555b794-0x55555555b9b7: a complex DWARF expression:
     0: DW_OP_constu 1
     2: DW_OP_stack_value
    [4-byte piece], and a complex DWARF expression:
     0: DW_OP_constu 0
     2: DW_OP_stack_value
    [1-byte piece]
.

Offhand I'm not sure where the synthetic pointer might come into play.

It would be useful to see the location expressions from your compilation. That can help clarify whether it's a compiler bug (in your case, seemingly not in mine) or a gdb bug.

@tromey
Copy link
Contributor

tromey commented May 29, 2017

wallento pushed a commit to wallento/binutils-gdb that referenced this issue Jul 9, 2017
This Rust bug report:

rust-lang/rust#41970

noted an error from gdb.  What is happening here (for me, the original
report had a different error) is that a pieced DWARF expression is not
writing to every byte in the resulting value.  GDB errors in this
case.  However, it seems to me that it is always valid to write fewer
bytes; the issue comes from writing too many -- that is, the test is
reversed.  The test was also checking the sub-object, but this also
seems incorrect, as it's expected for the expression to write the
entirety of the enclosing object.  So, this patch reverses the test
and applies it to the outer type, not the subobject type.

Regtested on the buildbot.

gdb/ChangeLog
2017-07-09  Tom Tromey  <tom@tromey.com>

	* dwarf2loc.c (dwarf2_evaluate_loc_desc_full): Reverse size
	check and apply to outer type.

gdb/testsuite/ChangeLog
2017-07-09  Tom Tromey  <tom@tromey.com>

	* gdb.dwarf2/shortpiece.exp: New file.
@tromey
Copy link
Contributor

tromey commented Jul 9, 2017

I've checked in the gdb patch. I think this bug can probably be closed now.

@sfackler sfackler closed this as completed Jul 9, 2017
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

3 participants