Need some help troubleshooting memory corruption

I think, I’m observing a bug either in Rust compiler or LLVM.

It happens only in release build, adding println! around one specific area “fixes” the issue.

Issue manifests as chrono::DateTime<chrono::FixedOffset> having somewhat corrupted value returned from my function. Memory analysis shows that bytes with indices [3] and [4] out of 12 bytes of the data type are corrupt.

Debugging via LLVM shows that there are certain 2 bytes on the stack which are never written to, but are copied into the result in the end. If at the beginning of the function, just after stack frame is created via subq $0x238, %rsp, I set them to “good” values, function returns correct result. Seems like the code after optimizations reads uninitialized values?

The function is a loop over Vec<(String, String)> , couple of branches in this loop (like if key == "param" { .. }. One of the branches parses string into chrono DateTime. Nothing crazy (pretty much, iterating / calling chrono parse functions / handling results / creating data structures).

I tried to simplify test case, but wasn’t able to – copying the whole function to a new project does not cause that issue.

Happens on Linux, but not on Mac OS X.

It looks to me like a mis-optimization of some sort.

What makes it difficult to analyze is that optimized code handles data in a weird way. So, chrono chrono::DateTime<chrono::FixedOffset> is 12 bytes: 4 bytes for year / month / day, 4 bytes for seconds and 4 bytes for subseconds. Corrupted bytes are last byte of ymd and first byte (least significant one) of seconds.

Why? Because internally code “works” (loads in eax register, etc) with 4 bytes with 1 byte offset (3 most significant bytes of ymd and 1 least significant of seconds). And that first byte (least significant of ymd) is copied individually via al register. Alignment is totally awkward.

Would be interesting to see an LLVM IR and actual assembly dump of the object file in question.

Seems like it was caused by I built the same version of rust we use + patch & issue went away.

1 Like