“非法指令:4”在OS X Lion中出现

10

我的一些 C++ 应用程序在 OS X Snow Leopard 中编译和运行都很顺利,但最近我改用了 OS X Lion,在这里,虽然没有编译错误,但当我尝试运行它时,出现了错误“非法指令:4”,我不知道原因是什么。

附注:

这些是我使用的链接标志

-Wl,-stack_size,0x10000000,-stack_addr,0xc0000000 

当我执行sudo truss executable命令时,我得到的输出如下:

setrlimit returned result = -1
    SYSCALL(args)        = return
getpid(0x0, 0x0, 0x0)        = 32993 0
__sysctl(0xBFFFF5EC, 0x3, 0xBFFFF5E8)        = 0 0
issetugid(0xBFFFF5EC, 0x3, 0xBFFFF5E8)       = 0 0
csops(0x0, 0x0, 0xBFFFF65C)      = 0 0
shared_region_check_np(0xBFFFD5E0, 0x0, 0xBFFFF65C)      = 0 0
stat64("/usr/lib/dtrace/libdtrace_dyld.dylib\0", 0xBFFFE830, 0xBFFFF65C)         = 0 0
open("/usr/lib/dtrace/libdtrace_dyld.dylib\0", 0x0, 0x0)         = 3 0
pread(0x3, "\312\376\272\276\0", 0x1000, 0x0)        = 4096 0
pread(0x3, "\316\372\355\376\a\0", 0x1000, 0x6000)       = 4096 0
mmap(0x4D3000, 0x2000, 0x1, 0x12, 0x3, 0x3)      = 0x4D3000 0
mmap(0x4D5000, 0x1000, 0x3, 0x12, 0x3, 0x3)      = 0x4D5000 0
mmap(0x4D6000, 0x1EF0, 0x1, 0x12, 0x3, 0x3)      = 0x4D6000 0
close(0x3)       = 0 0
stat64("/usr/lib/libstdc++.6.dylib\0", 0xBFFFE690, 0x1)      = 0 0
stat64("/usr/lib/libgcc_s.1.dylib\0", 0xBFFFE690, 0x1)       = 0 0
stat64("/usr/lib/libSystem.B.dylib\0", 0xBFFFE560, 0x1)      = 0 0
stat64("/usr/lib/libc++abi.dylib\0", 0xBFFFE5D0, 0x1)        = 0 0
stat64("/usr/lib/system/libcache.dylib\0", 0xBFFFE360, 0x1)      = 0 0
stat64("/usr/lib/system/libcommonCrypto.dylib\0", 0xBFFFE360, 0x1)       = 0 0
stat64("/usr/lib/system/libcompiler_rt.dylib\0", 0xBFFFE360, 0x1)        = 0 0
stat64("/usr/lib/system/libcopyfile.dylib\0", 0xBFFFE360, 0x1)       = 0 0
stat64("/usr/lib/system/libdispatch.dylib\0", 0xBFFFE360, 0x1)       = 0 0
stat64("/usr/lib/system/libdnsinfo.dylib\0", 0xBFFFE360, 0x1)        = 0 0
stat64("/usr/lib/system/libdyld.dylib\0", 0xBFFFE360, 0x1)       = 0 0
stat64("/usr/lib/system/libkeymgr.dylib\0", 0xBFFFE360, 0x1)         = 0 0
stat64("/usr/lib/system/liblaunch.dylib\0", 0xBFFFE360, 0x1)         = 0 0
stat64("/usr/lib/system/libmacho.dylib\0", 0xBFFFE360, 0x1)      = 0 0
stat64("/usr/lib/system/libmathCommon.A.dylib\0", 0xBFFFE360, 0x1)       = 0 0
stat64("/usr/lib/system/libquarantine.dylib\0", 0xBFFFE360, 0x1)         = 0 0
stat64("/usr/lib/system/libremovefile.dylib\0", 0xBFFFE360, 0x1)         = 0 0
stat64("/usr/lib/system/libsystem_blocks.dylib\0", 0xBFFFE360, 0x1)      = 0 0
stat64("/usr/lib/system/libsystem_c.dylib\0", 0xBFFFE360, 0x1)       = 0 0
stat64("/usr/lib/system/libsystem_dnssd.dylib\0", 0xBFFFE360, 0x1)       = 0 0
stat64("/usr/lib/system/libsystem_info.dylib\0", 0xBFFFE360, 0x1)        = 0 0
stat64("/usr/lib/system/libsystem_kernel.dylib\0", 0xBFFFE360, 0x1)      = 0 0
stat64("/usr/lib/system/libsystem_network.dylib\0", 0xBFFFE360, 0x1)         = 0 0
stat64("/usr/lib/system/libsystem_notify.dylib\0", 0xBFFFE360, 0x1)      = 0 0
stat64("/usr/lib/system/libsystem_sandbox.dylib\0", 0xBFFFE360, 0x1)         = 0 0
stat64("/usr/lib/system/libunc.dylib\0", 0xBFFFE360, 0x1)        = 0 0
stat64("/usr/lib/system/libunwind.dylib\0", 0xBFFFE360, 0x1)         = 0 0
stat64("/usr/lib/system/libxpc.dylib\0", 0xBFFFE360, 0x1)        = 0 0
open("/dev/dtracehelper\0", 0x2, 0xBFFFF5B0)         = 3 0
ioctl(0x3, 0x80086804, 0xBFFFF540)       = 0 0
close(0x3)       = 0 0
__sysctl(0xBFFFF1FC, 0x2, 0xBFFFF1F4)        = 0 0
bsdthread_register(0x92C9F6BC, 0x92C9F6E0, 0x1000)       = 0 0
thread_selfid(0x92C9F6BC, 0x92C9F6E0, 0x1000)        = 2500945 0
mmap(0x0, 0x2000, 0x3, 0x1002, 0x1000000, 0xAC308375)        = 0x4D8000 0
mprotect(0x4D8000, 0x44, 0x1)        = 0 0
mmap(0x0, 0xD000, 0x3, 0x1002, 0x1000000, 0x4D8034)      = 0x4DA000 0
mprotect(0x4DA000, 0x1000, 0x0)      = 0 0
mprotect(0x4E6000, 0x1000, 0x0)      = 0 0
mmap(0x0, 0xD000, 0x3, 0x1002, 0x1000000, 0x4DB000)      = 0x4E7000 0
mprotect(0x4E7000, 0x1000, 0x0)      = 0 0
mprotect(0x4F3000, 0x1000, 0x0)      = 0 0
mmap(0x0, 0x1000, 0x3, 0x1002, 0x1000000, 0x4E8000)      = 0x4F4000 0
mprotect(0x4F4000, 0x1000, 0x1)      = 0 0
mprotect(0x4D8000, 0x44, 0x3)        = 0 0
mmap(0x0, 0x200000, 0x3, 0x1002, 0x7000000, 0x4F4000)        = 0x4F5000 0
munmap(0x4F5000, 0xB000)         = 0 0
munmap(0x600000, 0xF5000)        = 0 0
mprotect(0x4D8000, 0x44, 0x1)        = 0 0
getpid(0x4D8000, 0x44, 0x1)      = 32993 0
__mac_syscall(0x973E8E8E, 0x2, 0xBFFFF0C8)       = 0 0
stat64("/AppleInternal\0", 0xBFFFF130, 0xBFFFF0C8)       = -1 Err#2
audit_session_self(0x92C1F4B6, 0xBFFFF130, 0xBFFFF0C8)       = 5635 0
geteuid(0x92C1F4B6, 0xBFFFF130, 0xBFFFF0C8)      = 0 0
getegid(0x92C1F4B6, 0xBFFFF130, 0xBFFFF0C8)      = 0 0
getaudit_addr(0xBFFFF0A8, 0x30, 0xBFFFF0C8)      = 0 0
csops(0x80E1, 0x7, 0xBFFFECF8)       = 0 0
mmap(0x0, 0x2000, 0x3, 0x1002, 0x1000000, 0xACA5EB00)        = 0x4F5000 0
mprotect(0x4F5000, 0x44, 0x1)        = 0 0
mmap(0x0, 0xD000, 0x3, 0x1002, 0x1000000, 0x4F5034)      = 0x600000 0
mprotect(0x600000, 0x1000, 0x0)      = 0 0
mprotect(0x60C000, 0x1000, 0x0)      = 0 0
mmap(0x0, 0xD000, 0x3, 0x1002, 0x1000000, 0x601000)      = 0x60D000 0
mprotect(0x60D000, 0x1000, 0x0)      = 0 0
mprotect(0x619000, 0x1000, 0x0)      = 0 0
mprotect(0x4F4000, 0x1000, 0x3)      = 0 0
mprotect(0x4F4000, 0x1000, 0x1)      = 0 0
mprotect(0x4F5000, 0x44, 0x3)        = 0 0
mmap(0x0, 0x200000, 0x3, 0x1002, 0x7000000, 0x4F4004)        = 0x61A000 0
munmap(0x61A000, 0xE6000)        = 0 0
munmap(0x800000, 0x1A000)        = 0 0
mprotect(0x4F5000, 0x44, 0x1)        = 0 0
getrlimit(0x1003, 0xBFFFF8DC, 0x1)       = 0 0
setrlimit(0x1003, 0xBFFFF8DC, 0x1)       = -1 Err#22
getrlimit(0x1008, 0xBF835C60, 0x1)       = 0 0
fstat64(0x1, 0xBF836090, 0x1F)       = 0 0
mmap(0x0, 0x1000000, 0x3, 0x1002, 0x2000000, 0xACA5B3E0)         = 0x800000 0
munmap(0x1000000, 0x800000)      = 0 0

PS2:如果我删除之前提到的链接标志,程序会运行而不出错。但是当我向程序输入真实数据时,就会出现

Segmentation fault: 11

我记得这个程序在使用堆栈时出现了问题,所以需要增加堆栈。在Linux上我进行了此操作并且成功了。

       const rlim_t kStackSize = 256L * 1024L * 1024L;   // min stack size = 64 Mb
    struct rlimit rl;
    int result;

    result = getrlimit(RLIMIT_STACK, &rl);
    if (result == 0)
    {
            if (rl.rlim_cur < kStackSize)
            {
                    rl.rlim_cur = kStackSize;
                    result = setrlimit(RLIMIT_STACK, &rl);
                    if (result != 0)
                    {
                            fprintf(stderr, "setrlimit returned result = %d\n", result);
                    }
            }
    }

但在OS X中,由于那并不起作用,我使用了先前提到的链接标志,在OS X Snow Leopard中没有问题,所以看来我仍然在OS X Lion中遇到堆栈溢出问题,但链接标志无法解决这个问题。我该怎么办?


在truss/dtrace中,此行setrlimit(0x1003, 0xBFFFF8DC, 0x1) = -1 Err#22显示setrlimit调用失败,并出现了EINVAL“无效参数”(在/usr/include/sys/errno.h中查找的22)。虽然在输出顶部显示了失败的fprintf(...)错误消息,但由于在fprintf之后没有exit(1),因此程序将继续运行,而堆栈大小未被修改。 - Brian Swift
缺少返回值可能会导致“非法指令:4”。我昨天遇到了这个问题。注意编译器的警告让我找到了正确的解决方法。 - rsp1984
3个回答

19

我在Mountain Lion(10.8)上构建产品,然后在Lion(10.7)上运行时遇到了这个问题。原因是我对构建环境进行了一些更改。(我使用mkbundle来打包使用Mono的产品。)

解决方法很简单,我需要告诉clang生成的二进制文件需要在OSX 10.6上运行。我向clang添加了以下参数:

-mmacosx-version-min=10.6

问题已解决!


在 MacOS Sierra 10.12.6 上遇到了相同的问题 - 尝试使用 clang 来构建 nim 编程语言编译器和工具。将此内容添加到配置中解决了问题 - 谢谢! - user208769

8

在OS X Lion(但也适用于10.5),堆栈大小的硬限制为65532 kbytes(略小于64 MiB)。

可以通过以下方式查看:

bswift$ ulimit -Hs
65532

即使是root用户,我也无法增加此值。

软限制默认仅为8 MiB:

bswift$ ulimit -Ss
8192

尝试在启动您的应用程序之前将值提高到此最大值:
bswift$ ulimit -Ss unlimited
bswift$ ulimit -Ss
65532

注意:你观察到的“分段错误(SIGSEGV)”(数字11)是进程超出栈限制时发送给该进程的信号,根据“man setrlimit”。
注意:由于“ulimit”命令需要作为shell内置命令,因此你会在“man bash”中找到它的文档。

0

这可能是一个权限问题

为了进一步诊断,可以在终端中使用sudo dtruss前缀运行程序。查看它在抛出错误之前运行的系统调用。

例如:sudo dtruss /path/to/application

您还可以使用Xcode或GDB调试器进行诊断。


我做到了,但是我得到了很多与内存相关的信息,这些信息我无法理解。后来,在查看编译选项时,我现在发现错误可能是由于增加堆栈大小造成的。但在Snow Leopard中,我从未遇到过这个问题。 - Open the way
Lion为32位应用程序添加了ASLR和堆内存保护...我没有看到其他与内存相关的更改。 - lunixbochs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接