Maybe my technical level is not enough, this question makes me very difficult to understand!
I have a program that can write Buffer,this is the code
public class WriteBuffer
{
private byte[] beginPtr;
private int position;
private int length;
public WriteBuffer(int len)
{
beginPtr = new byte[len];
position = 0;
length = 0;
if (beginPtr != null)
{
length = len;
}
}
public PbError.ErrorType writeUInt8(byte src)
{
if (beginPtr == null)
{
return PbError.ErrorType.PB_ERR_ARG_IS_NULL;
}
if (1 > length - position)
{
return PbError.ErrorType.PB_ERR_WRITE_BUFF_INSUFFIX;
}
beginPtr[position++] = src;
return PbError.ErrorType.PB_NO_ERROR;
}
public PbError.ErrorType writeInt32(int src)
{
if (beginPtr == null)
{
return PbError.ErrorType.PB_ERR_ARG_IS_NULL;
}
if (4 > length - position)
{
return PbError.ErrorType.PB_ERR_WRITE_BUFF_INSUFFIX;
}
if (BitConverter.IsLittleEndian)
{
src = IPAddress.HostToNetworkOrder(src);
}
WriteBytes(src, beginPtr, ref position);
return PbError.ErrorType.PB_NO_ERROR;
}
public PbError.ErrorType writeInt64(long src)
{
if (beginPtr == null)
{
return PbError.ErrorType.PB_ERR_ARG_IS_NULL;
}
if (8 > length - position)
{
return PbError.ErrorType.PB_ERR_WRITE_BUFF_INSUFFIX;
}
if (BitConverter.IsLittleEndian)
{
src = IPAddress.HostToNetworkOrder(src);
}
WriteBytes(src, beginPtr, ref position);
return PbError.ErrorType.PB_NO_ERROR;
}
public unsafe void WriteBytes(int val, byte[] dest, ref int offset)
{
if (dest == null)
{
throw new ArgumentNullException("dest");
}
if (offset < 0 || offset + 4 > dest.Length)
{
throw new ArgumentNullException("offset");
}
fixed (byte* ptr = dest)
{
*(int*)(ptr + offset) = val;
}
offset += 4;
}
public unsafe void WriteBytes(long val, byte[] dest, ref int offset)
{
if (dest == null)
{
throw new ArgumentNullException("dest");
}
if (offset < 0 || offset + 8 > dest.Length)
{
throw new ArgumentNullException("offset");
}
fixed (byte* ptr = dest)
{
*(long*)(ptr + offset) = val;
}
offset += 8;
}
}
and a test code here:write byte value first
public class Main : MonoBehaviour
{
private byte byte1;
private long long1;
private int int1;
private const string LOG_FILTER_TAG = "SELF_LOG: ";
WriteBuffer writeBuf = new WriteBuffer(1024);
private void Start()
{
byte1 = 1;
long1 = 10L;
int1 = 100;
}
private void OnGUI()
{
if (GUILayout.Button("Write To Buffer", GUILayout.Height(100f), GUILayout.Width(200f)))
{
//write byte
var ret = writeBuf.writeUInt8(byte1);
Debug.Log(LOG_FILTER_TAG + (ret == PbError.ErrorType.PB_NO_ERROR ? "Byte Success" : ret.ToString()));
//write long
ret = writeBuf.writeInt64(long1);
Debug.Log(LOG_FILTER_TAG + (ret == PbError.ErrorType.PB_NO_ERROR ? "long Success" : ret.ToString()));
//write int
ret = writeBuf.writeInt32(int1);
Debug.Log(LOG_FILTER_TAG + (ret == PbError.ErrorType.PB_NO_ERROR ? "int Success" : ret.ToString()));
}
}
}
I made an Android apk which scripting backend is IL2CPP RELEASE and ran it .The crash happened when I executed the code in OnGUI.The log found this content:signal 7 (SIGBUS), code 1 (BUS_ADRALN) !This means there is a problem with the memory alignment,Then I used libil2cpp.sym.so to locate the problem in the line of code
*(long*)(ptr + position) = val;
I guess this may be because I first wrote a byte, and then wrote a long at the offset + ptr, but the address of this position is not a multiple of 8, so it crashed.
Then I changed my code:write long value first
private void OnGUI()
{
if (GUILayout.Button("Write To Buffer", GUILayout.Height(100f), GUILayout.Width(200f)))
{
//write long
var ret = writeBuf.writeInt64(long1);
Debug.Log(LOG_FILTER_TAG + (ret == PbError.ErrorType.PB_NO_ERROR ? "long Success" : ret.ToString()));
//write byte
ret = writeBuf.writeUInt8(byte1);
Debug.Log(LOG_FILTER_TAG + (ret == PbError.ErrorType.PB_NO_ERROR ? "Byte Success" : ret.ToString()));
//write int
ret = writeBuf.writeInt32(int1);
Debug.Log(LOG_FILTER_TAG + (ret == PbError.ErrorType.PB_NO_ERROR ? "int Success" : ret.ToString()));
}
}
Just such a change does not crash anymore.This is also something that makes me very confused,Why won't it crash this time.After writing byte, write int again. At this time, offset+ptr is definitely not a multiple of 4, but why doesn't it crash anymore?Did I understand something wrong?
By the way, the crash is only issued in IL2CPP RELEASE,IL2CPP DEBUG or Mono will not.
question from:
https://stackoverflow.com/questions/66056991/signal-7-sigbus-code-1-bus-adraln-caused-the-crash