-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Don't set the linkage_name for static variables #46457
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @pnkfelix (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
Ping from triage! It's been over 7 days since we heard from reviewer @pnkfelix. Please assign a new reviewer @rust-lang/compiler. |
@m4b Can you squash your commits into one? I'd also like to see some capitalization on the comments, as the is apparently the style rustc goes for. |
Not my area of expertise, but it looks good to merge after @Zoxc comments are addressed. |
@Zoxc sure - but just curious doesn’t git allow to squash automatically ? Or does that not integrate with bors? (I know next to nothing about rust + bors merging, review commands, etc) |
@m4b Squashing commits is a destructive operation (it destroys history), so it would be terrible if it was done automatically. |
No I mean when I merge PRs in my repos it allows me to squash their PR into a single commit (essentially what you’re asking me to do manually). Hence my question is why can’t the PR merger just do it. It’s not a big deal was just wondering if there’s some other reason I’m not seeing |
I think @m4b is referring to the Settings > Options > Merge Button > "Allow squash merging" option that Github has for each repository. We use it all the time where I work, but I think it wasn't on by default and we had to go turn it on (and eventually we even disabled "Allow merge commits" so that we can't ever forget to squash a PR). I have no idea if the Rust team has considered enabling that option, but if contributors are expected to manually squash their PRs today then it'd probably be an improvement. |
There is no project-wide blanket rule for squashing. I believe the general idea is to have commits that "tell a cohesive story". A series of "oh, fixed that test, addressed review" isn't that useful long term, but neither is a single 10KLOC commit that is "I changed a bunch of stuff". I don't know what was here before, but at first approximation a commit that is "+18 −7" seems unlikely to need multiple commits. |
Rust doesn't use the standard GitHub merge process, so any such functionality would need to be added to bors, yes. |
As @shepmaster is alluding to sometimes you do want to keep the commit history for a given PR, so making bors do it on its own would be detrimental. @alexcrichton could you take a look at this PR? It seems reasonable to me. |
We should also check that this behaves correctly for CodeView debug information. |
We should probably just add tests in general for this stuff ;) |
@m4b Yeah. You can add a gdb test for this at least (see https://github.com/rust-lang/rust/tree/master/src/test/debuginfo), assuming there's some observable difference in gdb. |
@m4b, thanks for the PR! The code looks good to me. If you could find a way to test in a |
I added a file based off of other files in the suggested directory, but I'm going to need someone to explain to me how debuginfo tests work. Specifically, I changed: https://github.com//m4b/rust/blob/fbac12b980a06c4f2e8efb4eee6974507b38e979/src/test/debuginfo/gdb-pretty-struct-and-enums-pre-gdb-7-7.rs#L23 To not the expected value and running
which makes me suspicious that my test is doing anything in the first place. |
@tromey does the rust gdb language setting hardcode namespace assumptions? I'm seeing really weird behavior by the rust language setting, e.g.: For a simple rust program: #[no_mangle]
pub static TEST: u64 = 0xdeadbeef;
pub fn main() {
println!("{}", TEST);
} we see this (correct) debuginfo:
which matches the c++ output for no-mangled static variables. However, consider this gdb transcript:
It seems like there is something wrong with the rust language setting in gdb, since even the c and c++ language settings allow the symbol to be properly printed... |
// gdb-check:$1 = 3735928559 | ||
|
||
// gdb-command: ptype NO_MANGLE_DEADBEEF | ||
// gdb-check:$2 = u6 |
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 should probably say u64
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.
Ha yup sorry was trying to get tests to fail on my machine as per above comment, will fix
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.
@m4b it did fail in travis, it seems
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.
Yes but it doesn’t on my local machine, using above instructions. I do not know why...
0660e4c
to
ee84cf3
Compare
It shouldn't but I think the best thing would be if you could email me the executable and then I'll just debug gdb and see what is going on. |
If someone could help explain the CI failure I’m at a total loss. I don’t see any expected output, it says the test panicked (I don’t even know what that means in this context) and as I wrote above I’m unable to even get tests running on my local machine. :headache: |
☔ The latest upstream changes (presumably #46335) made this pull request unmergeable. Please resolve the merge conflicts. |
I debugged this a bit in gdb and I now wonder if a different approach would be preferable for this patch (plus maybe a gdb extension as well). gdb's expression parser tries to implement rust-like semantics. And, while "no mangle" affects the linkage name, I don't think it affects the name of the item as known to Rust. That is, I think the linkage name is If that's so, then I think it would be better to keep The gdb extension then would be to allow referring to items by linkage name in the Rust expression parser. In my test with g++ this is somewhat consistent with what C++ does. (g++ doesn't seem to emit the linkage name, but surely that's a g++ bug)
|
This is a very interesting point actually. To extrapolate a bit, iiuc, there's tension here between rusts linkage/crate module and binary linkage models. E.g., if I define This closely mirrors the usage you gave with the cpp code, so I think I agree that the namespace should be included. However, for cases like when you have the following in your crate: extern "C" {
static FOO: u64;
} I think this matches the C++ case of an unnamespaced static variable, and this should definitely not have a namespace (it literally gets defined at link time, with that exact name, with no module prefixes and explodes when there are multiple symbols). So the problem still remains that the rust gdb extension is not capable of printing unnamespaced statics for some reason (which I'll note was the original impetus of the issue). Since the c and c++ gdb extensions have no issue, and report it as a static variable with debugging info, but when switching to the rust language setting the variable either disappears or reports it has no debugging info, this strongly suggests to me the extension is failing in these cases and should be fixed (and not worked around). I would be happy to take a look at this if you're busy and could give me an initial pointer to take a look at.
Why ? This seems to exactly match expectations and the dwarf spec - its linkage name would have to be just its name, in which case it is omitted. clang also agrees, and does not emit a linkage name. |
15b51a4
to
038aae0
Compare
This is with the latest changes:
Which is the same situation as before w.r.t. gdb not working only in rust language mode. The dwarf info is correct:
@tromey its clear to me this is entirely a gdb issue that needs to be resolved over there and theres nothing more to be done on rustc's or this PRs end. I propose to merge this once (I ask again) someone can help to explain the build failure to me. EDIT: For completeness, here is the g++ debug info for the c++ file above:
Actually, I just realized we don't emit file and line attributes for the namespace; I'm not sure why that would cause a problem rust side, but it is important to note that it is slightly different. Nevertheless I think this should be merged |
So what exactly is the state here? The build error looks like just the new debuginfo test failing. Do you think there is another version of the test that would pass? Setting the language in the test after "run" looks like a potential race condition. I'm trying to reproduce this locally at the moment. |
@m4b I cannot reproduce the error locally. You could try to move the |
@michaelwoerister ok, will try; thanks for looking into this! Alternatively, could add different print and wait until the debugging issues in gets figured out, and then update back to what it is now. |
a827264
to
1310588
Compare
I don't actually know this area of Rust, but the question really revolves around the language semantics of
The way I see it is that C++ source refers to this as I'd appreciate your thoughts on this. TBH I was surprised that that C++ snippet compiled at all, since my mental model didn't allow for extern C objects in namespaces. So maybe I'm further confused somewhere. |
1310588
to
500dc14
Compare
@michaelwoerister I removed the test file; I cannot get it working and I can't repro here so i'm at a loss.
I am not even remotely a C++ expert but afaik, extern C in C++ affects the linkage model, not the namespace; so I believe you can have two extern C for a symbol Similar things go for rust, e.g., stuff like this happens: das-labor/panopticon#314 (comment) (tl;dr two different versions of goblin were getting pulled into the binary project, and since they both I'll email you the latest binary; as I said, I think the gdb plugin for rust language settings has a bug, and isn't displaying it properly, as the c++/c correctly access everything, as I pasted above. |
Based on 10.5/6 of the C++17 draft, C++ allows multiple declarations with C linkage in different namespaces, but these refer to the same function, and there can still only one be definition. I think a similar thing in rust would be: mod foo {
extern {
pub fn test();
}
}
pub mod bar {
#[no_mangle]
pub fn test() {
println!("test");
}
}
fn main() {
unsafe { foo::test(); }
} |
📌 Commit 500dc14 has been approved by |
Don't set the linkage_name for static variables For `no_mangle` statics: 1. Linkage_name no longer set 2. The static variable also no longer has a dwarf namespace scope This matches C++ output, which does not set the linkage_name and is not scoped: e.g. c++: ``` 0x000000b6: DW_TAG_base_type [8] DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000077] = "long int") DW_AT_encoding [DW_FORM_data1] (DW_ATE_signed) DW_AT_byte_size [DW_FORM_data1] (0x08) 0x000000bd: DW_TAG_variable [9] DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000053] = "TEST") DW_AT_type [DW_FORM_ref4] (cu + 0x0048 => {0x00000048}) DW_AT_external [DW_FORM_flag_present] (true) DW_AT_decl_file [DW_FORM_data1] ("/home/m4b/tmp/bad_debug/test.cpp") DW_AT_decl_line [DW_FORM_data1] (14) DW_AT_location [DW_FORM_exprloc] (<0x9> 03 40 10 20 00 00 00 00 00 ) 0x000000d2: DW_TAG_namespace [2] * DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000009d] = "std") ``` and (now) Rust: ``` 0x0000002a: DW_TAG_variable [2] DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000046] = "TEST") DW_AT_type [DW_FORM_ref4] (cu + 0x0045 => {0x00000045}) DW_AT_external [DW_FORM_flag_present] (true) DW_AT_decl_file [DW_FORM_data1] ("/tmp/test.rs") DW_AT_decl_line [DW_FORM_data1] (8) DW_AT_alignment [DW_FORM_udata] (1) DW_AT_location [DW_FORM_exprloc] (<0x9> 03 c0 4d 06 00 00 00 00 00 ) 0x00000040: DW_TAG_namespace [3] * DW_AT_name [DW_FORM_strp] ( .debug_str[0x0000004b] = "test") ```
☀️ Test successful - status-appveyor, status-travis |
@philipc thanks for the example, that aligns with what my understanding for rust cases has come to. Unfortunately, and I suspect for many others (but this is obviously speculation) when I write no mangle I go to a “c place” in my mind and would never expect the no mangle to have a namespace prefix, and hence when I pop open gdb I’d just expect to write the bare, unmangled name. I don’t know a good solution/compromise for this at the moment. Maybe there is none and it’s just education that everything is namespaced in rust at the debugging level ? |
I've pushed a gdb patch to address one of the issues pointed out by this PR: https://sourceware.org/ml/gdb-patches/2018-01/msg00418.html I'm not sure I covered everything, so if you know of something more, please ping me. Thanks! |
In rust-lang/rust#46457, "m4b" pointed out that the Rust support in gdb doesn't properly handle the lookup of qualified names. In particular, as shown in the test case in this patch, something like "::NAME" should be found in the global scope, but is not. This turns out to happen because rust_lookup_symbol_nonlocal does not search the global scope unless the name in question is unqualified. However, lookup_symbol_aux does not search the global scope, and appears to search the static scope only as a fallback (I wonder if this is needed?). This patch fixes the problem by changing rust_lookup_symbol_nonlocal to search the static and global blocks in more cases. Regression tested against various versions of the rust compiler on Fedora 26 x86-64. (Note that there are unrelated failures with newer versions of rustc; I will be addressing those separately.) 2018-01-19 Tom Tromey <tom@tromey.com> * rust-lang.c (rust_lookup_symbol_nonlocal): Look up qualified symbols in the static and global blocks. 2018-01-19 Tom Tromey <tom@tromey.com> * gdb.rust/modules.rs (TWENTY_THREE): New global. * gdb.rust/modules.exp: Add ::-qualified lookup test.
For
no_mangle
statics:This matches C++ output, which does not set the linkage_name and is not scoped:
e.g. c++:
and (now) Rust: