corert
corert copied to clipboard
ARM32 crash at startup due to misalignment
Here’s output from gdb:
Thread 1 "MyApp" received signal SIGBUS, Bus error.
RhpLockCmpXchg64 () at /home/linaro/corert/src/Native/Runtime/arm/Interlocked.S:47
47 cmp r6, r4
(gdb) bt
#0 RhpLockCmpXchg64 () at /home/linaro/corert/src/Native/Runtime/arm/Interlocked.S:47
#1 0x0049c5ee in S_P_CoreLib_System_IO_UnmanagedMemoryStream__get_PositionPointer ()
gdb probably has off by 1 bug, I think it’s the previous instruction which crashed the app.
The failing line of C# code is probably this https://github.com/dotnet/corefx/blob/master/src/Common/src/CoreLib/System/IO/UnmanagedMemoryStream.cs#L329 but I’m not 100% sure, as there’s no debug information in the binary due to another CoreRT ARM32 bug.
I wasn’t able to make minimal repro, when I wrote a class with a long field, Interlocked.Read(ref long) returned the value without crashing. Probably clang optimizes away.
Any idea how to fix or workaround?
This is a problem with the object layout or GC not respecting the required alignment. Does a program like this reproduce the crash?
using System;
using System.Threading;
using System.IO;
class My
{
static unsafe void Main()
{
new Thread(() => { GC.Collect(); Thread.Sleep(1); }).Start();
Random r = new Random();
for (;;)
{
byte b;
var s = new UnmanagedMemoryStream(&b, 1);
GC.KeepAlive(new String('a', r.Next(100)));
Console.WriteLine(s.Position);
}
}
}
If yes, the thing to check by looking at the disassembly are:
- Does
new UnmanagedMemoryStreamcallRhpNewFastAlign8allocation helper? - Is the
UnmanagedMemoryStream._positionfield offset aligned at 8 bytes?
Yes, it prints 0, on the next line Bus error, then quits. When debugging, gdb says it’s same location, Interlocked.S:47.
I’m afraid I don’t know how to check the things that you’ve mentioned. I normally use debuggers to find out who called what or native layout details, but debug symbol writer appears to be broken on ARM32, so gdb is of limited help.
Does it also crash immediately when you comment out the new Thread(() => { GC.Collect(); Thread.Sleep(1); }).Start(); line in the repro?
ilc compiler crashed with segfault. Attaching a pic.
Fortunately, same dotnet publish command worked the second time.
Yes, the output is identical, 0 then Bus error.
The place to set a breakpoint is RhpNewFastAlign8 and step through it. This method is supposed to return aligned pointer, but it is not doing that for some reason. The bug is likely going to be somewhere in RhpGcAlloc that is called by this method.