Skip to content

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

Merged
merged 1 commit into from
Feb 9, 2017
Merged

Emit DW_AT_main_subprogram #38109

merged 1 commit into from
Feb 9, 2017

Conversation

tromey
Copy link
Contributor

@tromey tromey commented Dec 1, 2016

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

@alexcrichton
Copy link
Member

It looks like llvm 3.7 may break the tests added here (on travis), but I think that can be fixed with // min-llvm-version 3.7

@tromey
Copy link
Contributor Author

tromey commented Dec 1, 2016

I think that can be fixed with // min-llvm-version 3.7

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.

Copy link
Member

@michaelwoerister michaelwoerister left a 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).

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)) {
Copy link
Member

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 {.

Copy link
Contributor Author

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;
                }
            }

Copy link
Member

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 |= ...;
}

Copy link
Contributor

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).

@@ -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,
Copy link
Member

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?

Copy link
Contributor Author

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.

Copy link
Member

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]
Copy link
Member

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?

@@ -451,6 +451,7 @@ pub mod debuginfo {
FlagIndirectVariable = 1 << 13,
FlagLValueReference = 1 << 14,
FlagRValueReference = 1 << 15,
FlagMainSubprogram = 1 << 21,
Copy link
Member

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.

@tromey
Copy link
Contributor Author

tromey commented Dec 2, 2016

It looks like llvm 3.7 may break the tests added here (on travis), but I think that can be fixed with // min-llvm-version 3.7

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.

@michaelwoerister
Copy link
Member

I'm wondering today if that should be "min-llvm-version 3.8"?

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 rust-llvm-only directive for tests?

@bors
Copy link
Collaborator

bors commented Dec 4, 2016

☔ The latest upstream changes (presumably #37857) made this pull request unmergeable. Please resolve the merge conflicts.

@tromey
Copy link
Contributor Author

tromey commented Dec 20, 2016

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 DW_AT_main_subprogram for the test main functions. I'll try to ping someone on irc tomorrow to see what can be done; or else if you are reading this and happen to know, please comment. Thanks :)

@tromey
Copy link
Contributor Author

tromey commented Dec 22, 2016

However the test cases fail now.

Of course this turned out to be operator error; somehow I had a stale rustc in my tree that I was running manually.

@michaelwoerister
Copy link
Member

Let me know when it's ready for review.

@tromey
Copy link
Contributor Author

tromey commented Dec 22, 2016

@michaelwoerister - hopefully it's ready now.

@tromey
Copy link
Contributor Author

tromey commented Dec 23, 2016

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.

@bors
Copy link
Collaborator

bors commented Dec 31, 2016

☔ The latest upstream changes (presumably #38701) made this pull request unmergeable. Please resolve the merge conflicts.

@alexcrichton
Copy link
Member

ping @tromey, it looks like this may need a rebase now?

@tromey
Copy link
Contributor Author

tromey commented Feb 5, 2017

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.

@cuviper
Copy link
Member

cuviper commented Feb 5, 2017

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.

There is a -DLLVM_RUSTLLVM for this sort of thing. It's used in PassWrapper.cpp to stub a couple functions that only exist in the Rust fork of LLVM.

@tromey
Copy link
Contributor Author

tromey commented Feb 5, 2017

There is a -DLLVM_RUSTLLVM for this sort of thing

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
@alexcrichton
Copy link
Member

re-r? @michaelwoerister

@michaelwoerister
Copy link
Member

@bors r+

Thanks @tromey!

@bors
Copy link
Collaborator

bors commented Feb 9, 2017

📌 Commit b037c52 has been approved by michaelwoerister

@bors
Copy link
Collaborator

bors commented Feb 9, 2017

⌛ Testing commit b037c52 with merge 4053276...

bors added a commit that referenced this pull request Feb 9, 2017
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
@bors
Copy link
Collaborator

bors commented Feb 9, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: michaelwoerister
Pushing 4053276 to master...

@bors bors merged commit b037c52 into rust-lang:master Feb 9, 2017
@tromey tromey deleted the main-subprogram branch August 1, 2018 16:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants