Change:
Updated summary: Under some conditions, drops are generated if a previously moved value is reassigned. This was bisected to . In the following minimised code for example: is dropped twice, see for complete mir. -- Edited by Original Description: There are now 3 instances of strange crashes/segfaults/hangs/error messages that happen using nightly 2017-06-20 (or it might be 2017-06-19) that don't happen with rustc 1.19.0-beta.2 ( 2017-06-15) reported on . I wanted to start an issue for discussing and investigating this because I think it's clear there's something wrong, but I apologize that we haven't yet gotten an isolated reproduction. I also don't know if these cases are the same bug or different bugs yet, please let me know if I should split this out into more issues. Or perhaps these already have issues! I didn't see any reported issues that looked similar enough to these and in the right time frame :-/ Via reddit user fulmicoton: Will ask if they can share more details. Described in pull request rust-, but I'm seeing weirdness on master too. All tests are passing using stable Rust on master. On Wednesday, was seeing one of cargo's tests () intermittently segfaulting and crashing with On master, I'm seeing the tests fail in a really really bizarre way: it looks like serialized JSON is being corrupted???? The test is making a request to the server, which returns JSON, and then the test attempts to deserialize the JSON and make assertions on it. The JSON returned by the server is valid JSON, but one of the keys looks like it's set to the value of the beginning of the JSON???? Here's the output that won't deserialize, pretty-printed and a bunch of stuff that looks fine removed to make the problem more obvious, also with comments that I've here even though JSON doesn't have comments: To reproduce: (involves installing postgres, sorry sorry, if this is too complex, I am happy to run experiments/patches on my setup) On master, run . You've reproduced the problem if you see:If I check out the changes in and run , I alternately get a failure that looks like: and a crash that looks like: Via see their description on this issue: bluejekyll/trust-dns To reproduce: Check out Run /cc
The regression was introduced by according to awesome .
cc -- regression due to
Woh. I need to read about that tool, that's awesome! BTW, I tried to clarify in the bug report on the trust-dns repo; it's not that OpenSSL and ring are affected, it's that I reproduced the issue with both OpenSSL and/or ring dependencies in use.
Thanks ! I've changed my description to just reference your bug and not duplicate what your description used to be :)
Running the test under GDB I get: When running all tests in the binary: a segmentation fault in jemalloc (Edit: reproduced with the system allocator as well): When filtering by the given test name: ` Edit: Here are some valgrind logs, they look... worrisome
If you want to take OpenSSL out of the picture, I believe the same issue can be triggered with openssl disabled: cargo test --no-default-features --features=ring
Incident 1 mentionned in this bug description is in tantivy. I tried to trim down the unit test to something simpler, smaller that stills fails without success. Introducing a single print statement is enough for the bug to disappear. The code does contain a lot of unsafe calls so this is probably a bad example to investigate. In case this is still useful, in 's master branch fails consistently. The backtrace is as follows
One debugging step that might help is to switch over to the system allocator, which has better runtime corruption checks, and then maybe run in valgrind.
Following advise, I used the system allocator. The failure happens when deallocating a buffer.
petgraph has been failing recently, not sure if its the same regression
I switched to the system allocator and indeed got much "better" / more precise valgrind results: Looking at the logs, I believe the bad codegen happens in : As far as I can tell, the problem is that in the third case is dropped in the line despite being moved a bit further up.
Checking the mir, it indeed seems to be the case that the line causes a drop: .
Here is the shortest piece of code I could write that reproduces. It is independant of tantivy but still calls the crate, so it still rather complex.
Thanks for that small sample! It also generates a broken mir with an erroneous drop for : Note how is moved to / into in but nevertheless dropped in .
The repro bisects to as well. cc since you reviewed that PR.
Here is an even smaller sample code that faults. No dependency whatsoever, no unsafe code.
Further minified: This no longer crashes but you'll see the erroneous drop if you look at the mir (slightly simplified, ): Note how is moved into and then consumed by however still dropped in . One thing I find curious, which I guess could be the problem, is that is extracted as but dropped as (note the missing lifetime specifier).
Fwiw, I've minified 's example a bit, still crashes:
Further minified crashing example, but only in debug mode:
It appears as if got confused by : Consider the following diffs from a good rustc to a bad rustc: Before they are almost identical however afterwards . Edit: The gist now includes the diff for : Some lifetimes are apparently no longer correctly erased.
I tried to make some sense of the debug logs, here is an excerpt: Judging by the doc comment on the and paths seem to be "bad", with both referring to the same thing.
I'll take this.
this seems pretty important to track down; if you don't have time, do raise the bat signal.

Discussion:
} fn visit_statement(&mut self, <del> _block: BasicBlock, </del> <ins> block: BasicBlock, </ins> statement: &mut Statement<'tcx>, <del> _location: Location) { </del> <ins> location: Location) { </ins> if let StatementKind::EndRegion(_) = statement.kind { statement.kind = StatementKind::Nop; } <ins> self.super_statement(block, statement, location); </ins> } }

} } <ins> fn field_assignment(a: &Allocator, c0: bool) { let mut x = (TwoPtrs(a.alloc(), a.alloc()), a.alloc()); x.1 = a.alloc(); x.1 = a.alloc(); let f = (x.0).0; if c0 { (x.0).0 = f; } } </ins> fn assignment2(a: &Allocator, c0: bool, c1: bool) { let mut _v = a.alloc(); let mut _w = a.alloc();

run_test(|a| struct_dynamic_drop(a, true, true, false)); run_test(|a| struct_dynamic_drop(a, true, true, true)); <ins> run_test(|a| field_assignment(a, false)); run_test(|a| field_assignment(a, true)); </ins> run_test_nopanic(|a| union1(a)); }