-
Notifications
You must be signed in to change notification settings - Fork 13.4k
core::ptr::copy_nonoverlapping
crashes when writing to odd addresses on ARM thumbv7em-none-eabihf
#82945
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
Comments
What's the signal/interrupt that has been called? Are you sure you didn't hit a triple fault or an interrupt handler that just infinitely loops or something along those lines? |
I assume it is from me entering
|
Yeah, I don't think it is. You'll want to investigate why you got a hardfault interrupt, it'll tell you something along the lines of an invalid instruction, access to invalid memory or something of that sort. |
The culprit seems to be this instruction: ldrh.w r3, [r9, r3, lsl #1] Where
Why this would fail I don't know, the memory addresses are all valid |
copy_nonoverlapping
hangs on ARM thumbv7em-none-eabihf
`core::fmt_u32
crashes on ARM thumbv7em-none-eabihf
`
core::fmt_u32
crashes on ARM thumbv7em-none-eabihf
`core::fmt_u32
crashes on ARM thumbv7em-none-eabihf
After some experimentation I have determined the following minimal reproducible example: #[inline(never)]
fn fmt_u32() {
static DEC_DIGITS_LUT: &[u8; 6] = b"424242";
let mut buf = [0; 5];
let buf_ptr = buf.as_ptr() as *mut u8;
let lut_ptr = DEC_DIGITS_LUT.as_ptr();
// Crashes if n is odd
let n = 1;
unsafe {
core::ptr::copy_nonoverlapping(lut_ptr, buf_ptr.offset(n), 2);
}
let buf_slice = unsafe {
core::str::from_utf8_unchecked(
core::slice::from_raw_parts(buf_ptr.offset(n), 2))
};
// Force usage of `buf_slice`
write!(DummyWrite, "Test: {}", buf_slice).unwrap();
} It seems that |
core::fmt_u32
crashes on ARM thumbv7em-none-eabihf
core::ptr::copy_nonoverlapping
crashes when writing to odd addresses on ARM thumbv7em-none-eabihf
Does it work if you specify the |
It seems that my MWE gets fixed however I still hit the bug in strh r1, [r2, r0] where |
I can now confirm that by combining |
cc @japaric @jonas-schievink should this target enable |
I have never run into unaligned memory exception with Cortex-M chips. (*) The ARMv7-M Architecture Reference Manual says:
CCR looks like a register that cannot be accessed / set by software but it's set in hardware by the vendor. It could be:
(*) I have seen this very same code (
On modern ARM chips, exception on unaligned access is usually configurable. Cortex-A cores have a register, accessible from software, that can change the behavior but defaults to exceptions ON. I think old ARM chips are not configurable: unaligned access always results in exceptions. OSes like Linux handle unaligned access in interrupt context to support those chips. Those OSes also do not configure modern ARM chips to disable exceptions on unaligned access, from what I've seen. |
It is an xmc4500 (reference manual). From the reference manual on page 128 it seems like it is possible to to set the
I am going to try and see if I am able to experiment with that bit later today. |
Yep, I am able to set the |
I was wrong about this. The CCR register is part of the SCB peripheral and it's available from firmware and also exposed in the cortex-m crate. ARM Architecture Reference Manual says the reset value of this register is "implementation defined" in the latest revision of the document but "0x0" in older revisions. I see two ways to deal with CCR being "implementation defined": either (a) we set |
I just ran into this problem, and on the STM32H7A3, there are some memories (TCM memories like DTCM) for which the UNALIGN_TRP can be set to 0, and still cause the SCB to hit an "unaligned access" fault. setting |
I guess this is because you were using a pre-compiled libcore compiled without strict-align. If so, compiling with -Z build-std may work. |
Uh oh!
There was an error while loading. Please reload this page.
Updated report
After some further investigation it seems that the
core::ptr::copy_nonoverlapping
function crashes when the dest address is not even on thethumbv7em-none-eabihf
platform. In the example above I am copying two bytes and experience the crash when the address copied to is odd.MWE:
Original report
I am using the
cortex-m-semihosting
crate to write debug messages over SWD, however when writing multi-digit numbers the execution hangs. Looking at the stacktrace from gdb it seems that execution is stuck oncore::ptr::copy_nonoverlapping
. Experimenting with trivial uses ofcore::ptr::copy_nonoverlapping
does not seem to hang.Meta
The same behaviour is also present in rust nightly.
Toolchain:
thumbv7em-none-eabihf
rustc --version --verbose
:Stacktrace from gdb
The text was updated successfully, but these errors were encountered: