Uh oh!
There was an error while loading. Please reload this page.
Don't set the linkage_name for static variables - #46457
Conversation
rust-highfive
commented
Dec 3, 2017
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. |
shepmaster
commented
Dec 9, 2017
Ping from triage! It's been over 7 days since we heard from reviewer @pnkfelix. Please assign a new reviewer @rust-lang/compiler. |
Zoxc
commented
Dec 9, 2017
@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. |
estebank
commented
Dec 9, 2017
Not my area of expertise, but it looks good to merge after @Zoxc comments are addressed. |
m4b
commented
Dec 9, 2017
@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) |
Zoxc
commented
Dec 9, 2017
@m4b Squashing commits is a destructive operation (it destroys history), so it would be terrible if it was done automatically. |
m4b
commented
Dec 9, 2017
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 |
Ixrec
commented
Dec 9, 2017
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. |
shepmaster
commented
Dec 9, 2017
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. |
shepmaster
commented
Dec 9, 2017
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. |
Zoxc
commented
Dec 10, 2017
We should also check that this behaves correctly for CodeView debug information. |
m4b
commented
Dec 10, 2017
We should probably just add tests in general for this stuff ;) |
Zoxc
commented
Dec 10, 2017
@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. |
alexcrichton
commented
Dec 10, 2017
michaelwoerister
commented
Dec 12, 2017
@m4b, thanks for the PR! The code looks good to me. If you could find a way to test in a |
m4b
commented
Dec 13, 2017
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. |
m4b
commented
Dec 13, 2017
@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]pubstaticTEST:u64 = 0xdeadbeef;pubfnmain(){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... |
There was a problem hiding this comment.
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.
Yes but it doesn’t on my local machine, using above instructions. I do not know why...
tromey
commented
Dec 13, 2017
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. |
m4b
commented
Dec 13, 2017
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: |
bors
commented
Dec 14, 2017
☔ The latest upstream changes (presumably #46335) made this pull request unmergeable. Please resolve the merge conflicts. |
tromey
commented
Dec 14, 2017
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) |
m4b
commented
Dec 14, 2017
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"{staticFOO: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
038aae0CompareThis 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 |
michaelwoerister
commented
Dec 15, 2017
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. |
michaelwoerister
commented
Dec 15, 2017
@m4b I cannot reproduce the error locally. You could try to move the |
m4b
commented
Dec 15, 2017
@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
1310588Comparetromey
commented
Dec 18, 2017
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. |
m4b
commented
Dec 20, 2017
@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. |
philipc
commented
Dec 20, 2017
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{pubfntest();}}pubmod bar {#[no_mangle]pubfntest(){println!("test");}}fnmain(){unsafe{ foo::test();}} |
michaelwoerister
commented
Dec 20, 2017
bors
commented
Dec 20, 2017
📌 Commit 500dc14 has been approved by |
bors
commented
Dec 20, 2017
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")
```bors
commented
Dec 20, 2017
☀️ Test successful - status-appveyor, status-travis |
m4b
commented
Dec 20, 2017
@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 ? |
tromey
commented
Jan 19, 2018
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_manglestatics:This matches C++ output, which does not set the linkage_name and is not scoped:
e.g. c++:
and (now) Rust: