forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of rust-lang#73460 - tmandry:variant-lineinfo, r=oli-obk
Emit line info for generator variants Debuggers should be able to read a generator / async fn state machine and show the line it's suspended at. Eventually, this could grow into an "async stack trace" feature of sorts. While no debugger support this for Rust today, this PR adds the debuginfo necessary for that support to exist. [This gist](https://gist.github.com/tmandry/6d7004fa008684f76809208847459f9b) shows the resulting debuginfo for a simple example. Here's a snippet: ``` 0x00000986: DW_TAG_variant DW_AT_discr_value (0x03) 0x00000988: DW_TAG_member DW_AT_name ("3") DW_AT_type (0x000009bc "Suspend0") DW_AT_decl_file ("/home/tmandry/code/playground/generator-simple.rs") DW_AT_decl_line (6) DW_AT_alignment (8) DW_AT_data_member_location (0x00) ``` The file and line have been added here. The line currently points to the beginning of the statement containing the yield (or await), because that's what the MIR source info points to for the yield terminator. (We may want to point to the yield or await line specifically, but that can be done independently of this change.) Debuggers don't know how to use this kind of info yet. However, we're hoping to experiment with adding such support to Fuchsia's debugger. It would be exciting if someone were interested in adding similar to support to gdb/lldb. r? @oli-obk cc @eddyb @jonas-schievink Part of rust-lang#73524.
- Loading branch information
Showing
10 changed files
with
341 additions
and
41 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
// Verify debuginfo for generators: | ||
// - Each variant points to the file and line of its yield point | ||
// - The generator types and variants are marked artificial | ||
// - Captured vars from the source are not marked artificial | ||
// | ||
// ignore-tidy-linelength | ||
// compile-flags: -C debuginfo=2 --edition=2018 | ||
|
||
#![feature(generators, generator_trait)] | ||
use std::ops::Generator; | ||
|
||
fn generator_test() -> impl Generator<Yield = i32, Return = ()> { | ||
|| { | ||
yield 0; | ||
let s = String::from("foo"); | ||
yield 1; | ||
} | ||
} | ||
|
||
async fn foo() {} | ||
async fn async_fn_test() { | ||
foo().await; | ||
let s = String::from("foo"); | ||
foo().await; | ||
} | ||
|
||
// FIXME: We need "checksum" to prevent matching with the wrong (duplicate) file | ||
// metadata, even when -C codegen-units=1. | ||
// CHECK: [[FILE:!.*]] = !DIFile(filename: "{{.*}}/generator-debug.rs", {{.*}}, checksum: | ||
|
||
// CHECK: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "generator-0", scope: [[FN:![0-9]*]], | ||
// CHECK-SAME: flags: DIFlagArtificial | ||
// CHECK: [[FN]] = !DINamespace(name: "generator_test" | ||
// CHECK: [[VARIANT:!.*]] = !DICompositeType(tag: DW_TAG_variant_part, scope: [[FN]], | ||
// CHECK-SAME: flags: DIFlagArtificial | ||
// CHECK-SAME: discriminator: [[DISC:![0-9]*]] | ||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "0", scope: [[VARIANT]], | ||
// CHECK-SAME: file: [[FILE]], line: 13, | ||
// CHECK-SAME: flags: DIFlagArtificial | ||
// CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "Unresumed", scope: [[GEN]], | ||
// CHECK-SAME: flags: DIFlagArtificial | ||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "1", scope: [[VARIANT]], | ||
// CHECK-SAME: file: [[FILE]], line: 17, | ||
// CHECK-SAME: flags: DIFlagArtificial | ||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "2", scope: [[VARIANT]], | ||
// CHECK-SAME: file: [[FILE]], line: 17, | ||
// CHECK-SAME: flags: DIFlagArtificial | ||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "3", scope: [[VARIANT]], | ||
// CHECK-SAME: file: [[FILE]], line: 14, | ||
// CHECK-SAME: flags: DIFlagArtificial | ||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "4", scope: [[VARIANT]], | ||
// CHECK-SAME: file: [[FILE]], line: 16, | ||
// CHECK-SAME: flags: DIFlagArtificial | ||
// CHECK: [[S1:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]], | ||
// CHECK-SAME: flags: DIFlagArtificial | ||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[S1]] | ||
// CHECK-NOT: flags: DIFlagArtificial | ||
// CHECK-SAME: ) | ||
// CHECK: [[DISC]] = !DIDerivedType(tag: DW_TAG_member, name: "__state", scope: [[FN]], | ||
// CHECK-SAME: flags: DIFlagArtificial | ||
|
||
// CHECK: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "generator-0", scope: [[FN:![0-9]*]], | ||
// CHECK-SAME: flags: DIFlagArtificial | ||
// CHECK: [[FN]] = !DINamespace(name: "async_fn_test" | ||
// CHECK: [[VARIANT:!.*]] = !DICompositeType(tag: DW_TAG_variant_part, scope: [[FN]], | ||
// CHECK-SAME: flags: DIFlagArtificial | ||
// CHECK-SAME: discriminator: [[DISC:![0-9]*]] | ||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "0", scope: [[VARIANT]], | ||
// CHECK-SAME: file: [[FILE]], line: 21, | ||
// CHECK-SAME: flags: DIFlagArtificial | ||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "1", scope: [[VARIANT]], | ||
// CHECK-SAME: file: [[FILE]], line: 25, | ||
// CHECK-SAME: flags: DIFlagArtificial | ||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "2", scope: [[VARIANT]], | ||
// CHECK-SAME: file: [[FILE]], line: 25, | ||
// CHECK-SAME: flags: DIFlagArtificial | ||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "3", scope: [[VARIANT]], | ||
// CHECK-SAME: file: [[FILE]], line: 22, | ||
// CHECK-SAME: flags: DIFlagArtificial | ||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "4", scope: [[VARIANT]], | ||
// CHECK-SAME: file: [[FILE]], line: 24, | ||
// CHECK-SAME: flags: DIFlagArtificial | ||
// CHECK: [[S1:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Suspend1", scope: [[GEN]], | ||
// CHECK-SAME: flags: DIFlagArtificial | ||
// CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "s", scope: [[S1]] | ||
// CHECK-NOT: flags: DIFlagArtificial | ||
// CHECK-SAME: ) | ||
// CHECK: [[DISC]] = !DIDerivedType(tag: DW_TAG_member, name: "__state", scope: [[FN]], | ||
// CHECK-SAME: flags: DIFlagArtificial | ||
|
||
fn main() { | ||
let _dummy = generator_test(); | ||
let _dummy = async_fn_test(); | ||
} |
15 changes: 14 additions & 1 deletion
15
src/test/mir-opt/generator-drop-cleanup/rustc.main-{{closure}}.generator_drop.0.mir
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 14 additions & 1 deletion
15
src/test/mir-opt/generator-tiny/rustc.main-{{closure}}.generator_resume.0.mir
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters