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

1.48 beta test failures, debuginfo-gdb 9.2 -> 10.1 #79009

Closed
infinity0 opened this issue Nov 12, 2020 · 7 comments · Fixed by #84752
Closed

1.48 beta test failures, debuginfo-gdb 9.2 -> 10.1 #79009

infinity0 opened this issue Nov 12, 2020 · 7 comments · Fixed by #84752
Assignees
Labels
A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) C-bug Category: This is a bug. P-medium Medium priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@infinity0
Copy link
Contributor

infinity0 commented Nov 12, 2020

This is with 1.48.0-beta.8, and previously these all passed in 1.47.0. On Debian I see these failures on all architectures. The main difference is we are using gdb 10 now, gdb 9.2 previously. The other debuginfo tests pass fine.

test [debuginfo-gdb] debuginfo/extern-c-fn.rs ... FAILED
error: line not found in debugger output: $1 = [...]"abcd\000"
status: exit code: 0
command: "/usr/bin/gdb" "-quiet" "-batch" "-nx" "-command=/<<PKGBUILDDIR>>/build/x86_64-unknown-linux-gnu/test/debuginfo/extern-c-fn.gdb/extern-c-fn.debugger.script"
stdout:
------------------------------------------
GNU gdb (Debian 10.1-1) 10.1
[..]
Breakpoint 1 at 0x122e: file /<<PKGBUILDDIR>>/src/test/debuginfo/extern-c-fn.rs, line 52.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, extern_c_fn::fn_with_c_abi (s=0x555555556081, len=20) at /<<PKGBUILDDIR>>/src/test/debuginfo/extern-c-fn.rs:52
52	    zzz(); // #break
$1 = (*mut u8) 0x555555556081
$2 = 20
$3 = 19
$4 = true
$5 = 20.5
[Inferior 1 (process 25039) exited normally]
test [debuginfo-gdb] debuginfo/generator-objects.rs ... FAILED
error: line not found in debugger output: $1 = generator_objects::main::generator-0 {__0: 0x[...], <<variant>>: {__state: 0, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {[...]}, 4: generator_objects::main::generator-0::Suspend1 {[...]}}}
status: exit code: 0
command: "/usr/bin/gdb" "-quiet" "-batch" "-nx" "-command=/<<PKGBUILDDIR>>/build/x86_64-unknown-linux-gnu/test/debuginfo/generator-objects.gdb/generator-objects.debugger.script"
stdout:
------------------------------------------
GNU gdb (Debian 10.1-1) 10.1
[..]
Breakpoint 1 at 0x137e: file /<<PKGBUILDDIR>>/src/test/debuginfo/generator-objects.rs, line 58.
Breakpoint 2 at 0x13ab: file /<<PKGBUILDDIR>>/src/test/debuginfo/generator-objects.rs, line 60.
Breakpoint 3 at 0x13d8: file /<<PKGBUILDDIR>>/src/test/debuginfo/generator-objects.rs, line 62.
Breakpoint 4 at 0x140f: file /<<PKGBUILDDIR>>/src/test/debuginfo/generator-objects.rs, line 64.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, generator_objects::main () at /<<PKGBUILDDIR>>/src/test/debuginfo/generator-objects.rs:58
58	    _zzz(); // #break
$1 = (null)

Breakpoint 2, generator_objects::main () at /<<PKGBUILDDIR>>/src/test/debuginfo/generator-objects.rs:60
60	    _zzz(); // #break
$2 = (null)

Breakpoint 3, generator_objects::main () at /<<PKGBUILDDIR>>/src/test/debuginfo/generator-objects.rs:62
62	    _zzz(); // #break
$3 = (null)
6 7 8

Breakpoint 4, generator_objects::main () at /<<PKGBUILDDIR>>/src/test/debuginfo/generator-objects.rs:64
64	    _zzz(); // #break
$4 = (null)
A debugging session is active.

	Inferior 1 [process 25180] will be killed.

Quit anyway? (y or n) [answered Y; input not from terminal]
test [debuginfo-gdb] debuginfo/issue-57822.rs ... FAILED
error: line not found in debugger output: $2 = issue_57822::main::generator-3 {__0: issue_57822::main::generator-2 {__0: 2, <<variant>>: {[...]}}, <<variant>>: {[...]}}
status: exit code: 0
command: "/usr/bin/gdb" "-quiet" "-batch" "-nx" "-command=/<<PKGBUILDDIR>>/build/x86_64-unknown-linux-gnu/test/debuginfo/issue-57822.gdb/issue-57822.debugger.script"
stdout:
------------------------------------------
GNU gdb (Debian 10.1-1) 10.1
[..]
Breakpoint 1 at 0x12ef: file /<<PKGBUILDDIR>>/src/test/debuginfo/issue-57822.rs, line 51.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, issue_57822::main () at /<<PKGBUILDDIR>>/src/test/debuginfo/issue-57822.rs:51
51	    zzz(); // #break
$1 = issue_57822::main::closure-1 (issue_57822::main::closure-0 (1))
$2 = issue_57822::main::generator-2{__0: 2, __state: 0, 0: issue_57822::main::generator-2::Unresumed}
A debugging session is active.

	Inferior 1 [process 25521] will be killed.

Quit anyway? (y or n) [answered Y; input not from terminal]
test [debuginfo-gdb] debuginfo/pretty-huge-vec.rs ... FAILED
error: line not found in debugger output: $2 = &[u8] {data_ptr: [...]"\000", length: 1000000000}
status: exit code: 0
command: "/usr/bin/gdb" "-quiet" "-batch" "-nx" "-command=/<<PKGBUILDDIR>>/build/x86_64-unknown-linux-gnu/test/debuginfo/pretty-huge-vec.gdb/pretty-huge-vec.debugger.script"
stdout:
------------------------------------------
GNU gdb (Debian 10.1-1) 10.1
[..]
Breakpoint 1 at 0x1fef: file /<<PKGBUILDDIR>>/src/test/debuginfo/pretty-huge-vec.rs, line 27.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, pretty_huge_vec::main () at /<<PKGBUILDDIR>>/src/test/debuginfo/pretty-huge-vec.rs:27
27	    zzz(); // #break
$1 = Vec(size=1000000000) = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...}
$2 = &[u8] {data_ptr: 0x7fffbc266010, length: 1000000000}
A debugging session is active.

	Inferior 1 [process 26156] will be killed.

Quit anyway? (y or n) [answered Y; input not from terminal]
@infinity0 infinity0 added the C-bug Category: This is a bug. label Nov 12, 2020
@Mark-Simulacrum
Copy link
Member

Can you verify that gdb 9.2 still passes with 1.48 beta? (Not sure how easy that is for you)

Regardless, it seems like this is probably too difficult for us to land a fix for in the next few days in time for 1.48, and it does not seem like a release blocker to me.

@Mark-Simulacrum Mark-Simulacrum added the regression-from-stable-to-beta Performance or correctness regression from stable to beta. label Nov 12, 2020
@rustbot rustbot added the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label Nov 12, 2020
@jyn514 jyn514 added A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 12, 2020
@infinity0
Copy link
Contributor Author

@Mark-Simulacrum It's not easy for me to run the whole build - sadly Debian deletes old versions from the main archive when they get updated. However I still have gdb 9.2 locally and I can confirm running a random sample of these tests by hand against rustc 1.48 & gdb 9.2 does appear to produce the correct expected output.

The differences appear minor except that in generator-objects the output is 9.2/expected:non-null vs 10:null which is slightly concerning, so someone with more in-depth knowledge about gdb & rust should look into this further.

@spastorino
Copy link
Member

Assigning P-medium as discussed as part of the Prioritization Working Group procedure and removing I-prioritize.

@spastorino spastorino added P-medium Medium priority and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Nov 18, 2020
@Mark-Simulacrum Mark-Simulacrum added regression-from-stable-to-stable Performance or correctness regression from one stable version to another. and removed regression-from-stable-to-beta Performance or correctness regression from stable to beta. labels Dec 10, 2020
@jesusprubio
Copy link
Contributor

jesusprubio commented Feb 1, 2021

Same errors here:

  • Fedora 33
  • rustc 1.51.0-dev
  • GNU gdb 10.1-2.fc33
failures:
    [debuginfo-gdb] debuginfo/extern-c-fn.rs
    [debuginfo-gdb] debuginfo/generator-objects.rs
    [debuginfo-gdb] debuginfo/issue-57822.rs
    [debuginfo-gdb] debuginfo/pretty-huge-vec.rs

test result: FAILED. 85 passed; 4 failed; 27 ignored; 0 measured; 0 filtered out; finished in 7.56s

I have also confirmed these errors are not happening using v9. To reproduce:

gdb --version     # GNU gdb (GDB) Fedora  10.1-2.fc33
./x.py test          # those 4 tests failed
sudo dnf downgrade -y gdb
gdb --version    # GNU gdb (GDB) Fedora 9.2-7.fc33
./x.py test          # all tests ok

@Apteryks
Copy link
Contributor

Apteryks commented Feb 3, 2021

I can reproduce also on GNU Guix, even in 1.49 when using GDB 10. The debuginfo tests pass when using GDB 8.2.

@faern
Copy link
Contributor

faern commented Mar 25, 2021

I'm also getting this on Fedora 33 with the same versions of everything as @jesusprubio. I have tried both with and without the package rust-gdb installed. Is there any known workaround?

@lrh2000
Copy link
Contributor

lrh2000 commented Apr 26, 2021

@rustbot claim

I encountered this issue on Arch Linux using GDB 10.1. Then I built the latest GDB from source and the problem remains the same. So I spent some time to investigate why the problem occurs.

As said by @infinity0, there are actually two separate problems. The first one is minor. It simply means that with respect to the Rust language, GDB won't try to interpret pointers as strings anymore. We can see the offending commit here (c_value_print_inner will try to print strings for pointers but generic_value_print won't). I am not clear whether or not the change is intended, but there are some workarounds. For example, we can fix it by replacing print s with printf "%s\n", s in the test cases.

Another problem seems to be very strange and slightly concerning. The test cases revealed that GDB would interpret generators as (null). The reason is a little complex, but I'll try my best to explain it.

First, generators are treated as special enums when generating debug-info.

ty::Generator(def_id, substs, _) => {
let upvar_tys: Vec<_> = substs
.as_generator()
.prefix_tys()
.map(|t| cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t))
.collect();
prepare_enum_metadata(cx, t, def_id, unique_type_id, usage_site_span, upvar_tys)
.finalize(cx)
}

In the original test cases, generators are parsed as structs instead of enums. It indeed shows that something must be wrong.
// gdb-command:print b
// gdb-check:$1 = generator_objects::main::generator-0 {__0: 0x[...], <<variant>>: {__state: 0, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {[...]}, 4: generator_objects::main::generator-0::Suspend1 {[...]}}}

GDB 10 "fixes" this problem. I'm not sure whether or not the behavior is intended, either. But anyway, generators are parsed as enums in newer GDB. The corresponding commit is here.

Unfortunately, rustc does not produce the correct debug-info. At least, GDB fails to understand it correctly. Normally, an enum has an external discriminant and some internal structures or tuples that share the same memory space. The discriminant is used to pick one specific structure or tuple, and it is marked as artificial. When printing an enum, GDB will always choose the first non-artificial field (i.e. the specific structure or tuple). We can see the code here and here.

Besides the discriminant, generators can have other external fields. They are used to track variable that are defined outside the closure but used inside the closure. The key problem is that rustc forgets to mark them as artificial. Therefore, GDB selects one external field to print. In our test case, the external field is actually &mut a and it is a pointer instead of a structure or a tuple. GDB tries to treat the pointer as a tuple and finally it prints (null).

let mut outer_fields = match layout.variants {
Variants::Single { .. } => vec![],
Variants::Multiple { .. } => {
let tuple_mdf = TupleMemberDescriptionFactory {
ty: enum_type,
component_types: outer_field_tys,
span,
};
tuple_mdf
.create_member_descriptions(cx)
.into_iter()
.map(|desc| Some(desc.into_metadata(cx, containing_scope)))
.collect()
}
};

I have tried to fix the problem and now we can get something like:

(gdb) p b
$2 = generator_objects::main::generator-0::Suspend0{c: 6, d: 7}

I think it looks good. I'll open PRs for the issue after some code cleanup.

lrh2000 added a commit to lrh2000/rust that referenced this issue Apr 27, 2021
As mentioned in rust-lang#79009, there are four failed debuginfo test cases
when using GDB 10. This commit fixes two of them, which fail because
GDB 10 won't print pointers as string anymore. We can use `printf`
as a workaround. It should work regardless of the version of GDB.

Refer this [comment] for more details.

[comment]: rust-lang#79009 (comment)
bors added a commit to rust-lang-ci/rust that referenced this issue Apr 29, 2021
…crum

Fix failed tests related to pointer printing when using GDB 10

As mentioned in rust-lang#79009, there are four failed debuginfo test cases when using GDB 10. This PR fixes two of them, which fail because GDB 10 won't print pointers as string anymore. We can use `printf` as a workaround. It should work regardless of the version of GDB.

Refer this [comment] for more details.

[comment]: rust-lang#79009 (comment)
lrh2000 added a commit to lrh2000/rust that referenced this issue Apr 30, 2021
 - Literally, variants are not artificial. We have `yield` statements,
   upvars and inner variables in the source code.
 - Functionally, we don't want debuggers to suppress the variants. It
   contains the state of the generator, which is useful when debugging.
   So they shouldn't be marked artificial.
 - Debuggers may use artificial flags to find the active variant. In
   this case, marking variants artificial will make debuggers not work
   properly.

Fixes rust-lang#79009.
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue May 1, 2021
Fix debuginfo for generators

First, all fields except the discriminant (including `outer_fields`) should be put into structures inside the variant part, which gives an equivalent layout but offers us much better integration with debuggers.

Second, artificial flags in generator variants should be removed.
 - Literally, variants are not artificial. We have `yield` statements, upvars and inner variables in the source code.
 - Functionally, we don't want debuggers to suppress the variants. It contains the state of the generator, which is useful when debugging. So they shouldn't be marked artificial.
 - Debuggers may use artificial flags to find the active variant. In this case, marking variants artificial will make debuggers not work properly.

Fixes rust-lang#79009.

And refer https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Debuginfo.20for.20generators.
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue May 2, 2021
Fix debuginfo for generators

First, all fields except the discriminant (including `outer_fields`) should be put into structures inside the variant part, which gives an equivalent layout but offers us much better integration with debuggers.

Second, artificial flags in generator variants should be removed.
 - Literally, variants are not artificial. We have `yield` statements, upvars and inner variables in the source code.
 - Functionally, we don't want debuggers to suppress the variants. It contains the state of the generator, which is useful when debugging. So they shouldn't be marked artificial.
 - Debuggers may use artificial flags to find the active variant. In this case, marking variants artificial will make debuggers not work properly.

Fixes rust-lang#62572.
Fixes rust-lang#79009.

And refer https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Debuginfo.20for.20generators.
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue May 2, 2021
Fix debuginfo for generators

First, all fields except the discriminant (including `outer_fields`) should be put into structures inside the variant part, which gives an equivalent layout but offers us much better integration with debuggers.

Second, artificial flags in generator variants should be removed.
 - Literally, variants are not artificial. We have `yield` statements, upvars and inner variables in the source code.
 - Functionally, we don't want debuggers to suppress the variants. It contains the state of the generator, which is useful when debugging. So they shouldn't be marked artificial.
 - Debuggers may use artificial flags to find the active variant. In this case, marking variants artificial will make debuggers not work properly.

Fixes rust-lang#62572.
Fixes rust-lang#79009.

And refer https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Debuginfo.20for.20generators.
@bors bors closed this as completed in 5bf989e May 2, 2021
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.) C-bug Category: This is a bug. P-medium Medium priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants