-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Emit DW_AT_main_subprogram #38109
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
Emit DW_AT_main_subprogram #38109
Conversation
It looks like llvm 3.7 may break the tests added here (on travis), but I think that can be fixed with |
Thanks - I will update the patch soon. I think for this I'll introduce a new test, so that the existing test keeps running on travis. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. Thanks @tromey! A test case for the common case would be good (can be very similar to the #[start] test case).
src/librustc_trans/debuginfo/mod.rs
Outdated
let mut flags = FlagPrototyped as c_uint; | ||
match *cx.sess().entry_fn.borrow() { | ||
Some((id, _)) => { | ||
if instance == Instance::mono(cx.shared(), cx.tcx().map.local_def_id(id)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be simplified to if id == local_id {
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I needed something a bit wordier:
if let Some(local_id_unwrapped) = local_id {
if id == local_id_unwrapped {
flags |= FlagMainSubprogram as c_uint;
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, that makes sense. Though you could probably make it shorter be wrapping id
in an Option
and then comparing Option
against Option
. Or do something like this:
let entry_fn_id = *cx.sess().entry_fn.borrow();
if entry_fn_id.is_some() && local_id == entry_fn_id {
flags |= ...;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The standard style is is if entry_fn_id == Some(local_id)
.
src/librustc_trans/debuginfo/mod.rs
Outdated
@@ -286,7 +296,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, | |||
is_local_to_unit, | |||
true, | |||
scope_line as c_uint, | |||
FlagPrototyped as c_uint, | |||
flags, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You removed the FlagPrototyped
(which might very well make sense). Can you comment on your reasoning there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
flags
is initialized to include it:
+ let mut flags = FlagPrototyped as c_uint;
I'm happy to write this some other way if you think it would be clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, that's right, I just missed it. Sorry.
@@ -18,6 +18,7 @@ | |||
|
|||
// CHECK-LABEL: @main | |||
// CHECK: load volatile i8, i8* getelementptr inbounds ([[B:\[[0-9]* x i8\]]], [[B]]* @__rustc_debug_gdb_scripts_section__, i32 0, i32 0), align 1 | |||
// CHECK: {{.*}}DISubprogram{{.*}}name: "start",{{.*}}DIFlagMainSubprogram{{.*}} | |||
|
|||
#[start] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having a #[start]
function is a rather special case, I think. Can we have another test case for a regular main
function?
src/librustc_llvm/ffi.rs
Outdated
@@ -451,6 +451,7 @@ pub mod debuginfo { | |||
FlagIndirectVariable = 1 << 13, | |||
FlagLValueReference = 1 << 14, | |||
FlagRValueReference = 1 << 15, | |||
FlagMainSubprogram = 1 << 21, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looks like older LLVM versions will just silently ignore this. At least 3.7 on Travis. Which is good.
I'm wondering today if that should be "min-llvm-version 3.8"? Since IIUC 3.7 is what is in travis, and will fail. Even 3.8 is technically wrong in a sense, because if there's a real 3.8 release, it won't contain the needed patch. |
I guess that no LLVM release in existence today contains the patch, so this test can only pass with our own version of LLVM. Do we have a |
☔ The latest upstream changes (presumably #37857) made this pull request unmergeable. Please resolve the merge conflicts. |
Just FYI - I've rebased this and fixed it up, and it works in manual testing. However the test cases fail now. I don't know the test suite setup very well; my suspicion is that the tests aren't built in isolation, leading rustc not to emit |
Of course this turned out to be operator error; somehow I had a stale rustc in my tree that I was running manually. |
Let me know when it's ready for review. |
815e039
to
9401dc9
Compare
@michaelwoerister - hopefully it's ready now. |
Well, I guess not. In the new scheme for DIFlags I suppose some kind of version or other configury is needed. Maybe I should have listened to that warning in RustWrapper.cpp. |
☔ The latest upstream changes (presumably #38701) made this pull request unmergeable. Please resolve the merge conflicts. |
ping @tromey, it looks like this may need a rebase now? |
Yeah. Sorry about my silence on this. I still intend to work on it. I think there are two issues with the patch currently. One is that the refactor in this area means that the old approach of passing in the constant, regardless of the underlying LLVM version, will no longer work, because the enumerator in question just doesn't exist in earlier versions of LLVM. The Rust fork of LLVM does have this, and so does 4.0, but I don't know of a way to distinguish the Rust LLVM from the ordinary upstream LLVM. So, maybe adding a way to distinguish this case would be good. Alternatively a simpler solution would be to only enable this feature for LLVM 4.0. I think this is less nice because in the future I hope to add more Rust-specific features to LLVM's debuginfo generation, and backport these to the Rust LLVM fork; and if this all comes to pass then it will be handy to have the necessary infrastructure already in place. The second problem with this patch is related: the tests also have no way to check whether they're being run against the Rust fork of LLVM. |
There is a |
Thanks! That really simplifies things. |
This changes rustc to emit DW_AT_main_subprogram on the "main" program. This lets gdb suitably stop at the user's main in response to "start" (rather than the library's main, which is what happens currently). Fixes rust-lang#32620 r? michaelwoerister
9401dc9
to
b037c52
Compare
re-r? @michaelwoerister |
📌 Commit b037c52 has been approved by |
Emit DW_AT_main_subprogram This changes rustc to emit DW_AT_main_subprogram on the "main" program. This lets gdb suitably stop at the user's main in response to "start" (rather than the library's main, which is what happens currently). Fixes #32620 r? michaelwoerister
☀️ Test successful - status-appveyor, status-travis |
This changes rustc to emit DW_AT_main_subprogram on the "main" program.
This lets gdb suitably stop at the user's main in response to
"start" (rather than the library's main, which is what happens
currently).
Fixes #32620
r? michaelwoerister