【问题标题】:What does SEGV_ACCERR mean?SEGV_ACCERR 是什么意思?
【发布时间】:2013-10-01 15:16:13
【问题描述】:

我正在检查一些崩溃,它们都有信号 SIGSEGV,原因是 SEGV_ACCERR。搜索 SEGV_ACCERR 后,我发现最接近人类可读解释的是:Invalid Permissions for object

这在更一般的意义上是什么意思?什么时候会出现 SEGV_ACCERR?有没有关于这个原因的更具体的文档?

【问题讨论】:

  • 来源中的 This 表示“映射对象的权限无效”。我猜这意味着您正在尝试对不允许执行的映射区域执行某些操作。
  • 为什么你需要知道这个?您是否经历过程序的奇怪崩溃?如果是,请检查它处理内存的方式,可能使用内存检查器运行它,例如 Valgrind:valgrind.org
  • 你在什么平台上看到这个?
  • 供您参考,当设备内存不足时,我通常会看到CFNetwork 框架崩溃和SEGV_ACCERR 代码。

标签: c++ objective-c c signals


【解决方案1】:

这是我最常在 64 位 iOS 设备上看到的错误,如果多个线程读取并更改 ARC 下的变量,就会发生这种错误。例如,我今天修复了一个崩溃,其中多个后台线程正在读取和使用静态 NSDate 和 NSString 变量并更新它们而不进行任何类型的锁定或排队。

在多个线程上使用核心数据对象也可能导致此崩溃,正如我在崩溃日志中多次看到的那样。

我也使用 Crittercism,这个特殊的崩溃是一个只影响 64 位设备的 SEGV_ACCERR。

【讨论】:

  • 您知道任何文档吗?对象的无效权限似乎很适合您所描述的内容。
  • @Dan_Gabicoware 我不知道任何文档,对我来说似乎是合乎逻辑的。我们遇到过多次 SEGV_ACCERR 崩溃,所有这些似乎都是仅在 64 位设备上出现的错误指针问题/核心数据问题。
  • 在我们的 crittercism 日志中,此崩溃(或此崩溃的版本)并非 64 位设备独有。事实上,其中一个版本专门针对较旧的硬件,以 ipad 3 结尾。另一个版本针对所有硬件。不过,它们都是 ios 8 独有的,而其他崩溃则涵盖了广泛的旧 ios 版本。
【解决方案2】:

sigaction 的手册页所述,SEGV_ACCERR 是 SIGSEGV 的信号代码,它指定 映射对象的无效权限。与 SEGV_MAPERR 表示地址未映射到有效对象相反,SEGV_ACCERR 表示地址匹配一个对象,但可以肯定的是,它既不是好的对象,也不是允许进程访问的对象。

【讨论】:

  • 不要混淆:在这种情况下,“对象”并不是指 Swift 或 Obj-C 或 C++ 对象,而是指内核内存对象,即地址空间范围。该错误意味着某些东西试图以不允许的方式使用内存地址,即写入只读内存或从不可执行的内存中执行代码。
【解决方案3】:

在代码尝试从“文本”以外的地方执行的情况下,我已经看到了这种情况。

例如,如果您的指针指向堆或堆栈中的函数并且您尝试执行该代码(从堆或堆栈),CPU 会抛出此异常。

【讨论】:

  • 所以 youtube 是 trying 通过铬黑我?! :)
【解决方案4】:

由于堆栈溢出,有可能获得SEGV_ACCERR。具体来说,这在我的 Android ARM64 上发生了以下情况:

VeryLargeStruct s;
s = {}; // SEGV_ACCERR

似乎零初始化创建了一个导致堆栈溢出的临时。这只发生在-O0;大概是在更高的优化级别上对临时进行了优化。

【讨论】:

    【解决方案5】:

    在 android arm64 上,如果 stack.cpp 包含:

    struct VeryLargeStruct  {
        int array[4096*4096];
        };
    int main() {
        struct VeryLargeStruct s;
        s = {}; 
        }
    

    然后输入:

    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 包含一个 SEGV_MAPERR,而不是 SEGV_ACCERR:

    id: 11363, tid: 11363, name: stack  >>> /data/local/tmp/stack <<<
    signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x7ff2d02dd8
    

    当 const.c 包含时,我得到 SEGV_ACCERR:

    int main() {
        char *str="hello";
        str[0]='H';
        }
    

    然后 /data/tombstones/tombstone_00 包含:

    pid: 9844, tid: 9844, name: consts  >>> /data/local/tmp/consts <<<
    Signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x55d10674e8
    

    【讨论】:

    • 这些例子有帮助,谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-12
    • 2017-06-11
    • 2018-03-05
    • 2023-03-27
    • 1970-01-01
    • 2013-03-09
    • 2020-05-01
    相关资源
    最近更新 更多