I am examining a few crashes that all have the signal SIGSEGV with the reason SEGV_ACCERR. After searching for SEGV_ACCERR, the closest thing I have found to a human readable explanation is: Invalid Permissions for object
What does this mean in a more general sense? When would a SEGV_ACCERR arise? Is there more specific documentation on this reason?
This is an error that I have mostly seen on 64 bit iOS devices and can happen if multiple threads read and change a variable under ARC. For example, I fixed a crash today where multiple background threads were reading and using a static NSDate and NSString variable and updating them without doing any kind of locking or queueing.
Using core data objects on multiple threads can also cause this crash, as I have seen many times in my crash logs.
I also use Crittercism, and this particular crash was a SEGV_ACCERR that only affected 64 bit devices.
As stated in the man page of sigaction, SEGV_ACCERR is a signal code for SIGSEGV that specifies Invalid permissions for mapped object. Contrary to SEGV_MAPERR which means that the address is not mapped to a valid object, SEGV_ACCERR means the address matches an object, but for sure it is neither the good one, nor one the process is allowed to access.
I've seen this in cases where code tries to execute from places other than "text".
For eg, if your pointer is pointing to a function in heap or stack and you try to execute that code (from heap or stack), the CPU throws this exception.
It's possible to get a SEGV_ACCERR
because of a stack overflow. Specifically, this happened to me on Android ARM64 with the following:
VeryLargeStruct s;
s = {}; // SEGV_ACCERR
It seems that the zero-initialization created a temporary that caused a stack overflow. This only happened with -O0
; presumably the temporary was optimized away at higher optimization levels.
On android arm64 if stack.cpp contains:
struct VeryLargeStruct {
int array[4096*4096];
};
int main() {
struct VeryLargeStruct s;
s = {};
}
and typing:
aarch64-linux-android26-clang++ -std=c++20 -g -DANDROID_STL=c++_static -static-libstdc++ stack.cpp -o stack
adb push stack /data/local/tmp
adb shell /data/local/tmp/stack
/data/tombstones/tombstone_01 contains a SEGV_MAPERR, not SEGV_ACCERR:
id: 11363, tid: 11363, name: stack >>> /data/local/tmp/stack <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x7ff2d02dd8
I get SEGV_ACCERR, when const.c contains:
int main() {
char *str="hello";
str[0]='H';
}
Then /data/tombstones/tombstone_00 contains:
pid: 9844, tid: 9844, name: consts >>> /data/local/tmp/consts <<<
Signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x55d10674e8
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With