Незаконна инструкция: 4 се показва в OS X Lion

Някакво C++ приложение се компилира и работи безпроблемно в OS X Snow Leopard, но наскоро промених на OS X Lion и тук, въпреки че няма грешка при компилиране, когато се опитам да го стартирам, получавам грешката „Незаконна инструкция: 4“, аз нямам представа, каква може да е причината?

PS:

Това са флаговете за свързване, които използвам

-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, но флагът за свързване не решава това. Какво бих могъл да направя?


person Open the way    schedule 16.04.2012    source източник
comment
Този ред setrlimit(0x1003, 0xBFFFF8DC, 0x1) = -1 Err#22 в truss/dtrace показва, че извикването на setrlimit е неуспешно с EINVAL Невалиден аргумент (22 потърсен в /usr/include/sys/errno.h). Неуспешното съобщение за грешка fprintf(...) се показва в горната част на изхода, но тъй като няма exit(1) след fprintf, програмата продължава с непроменен размер на стека.   -  person Brian Swift    schedule 23.04.2012
comment
Липсваща върната стойност може да причини Незаконна инструкция: 4. Попаднах на това вчера. Обръщането на внимание на моите предупреждения на компилатора ме доведе до правилния път.   -  person rsp1984    schedule 20.04.2014


Отговори (3)


Срещнах този проблем, когато създавах продукт на Mountain Lion (10.8,) и след това стартирах на Lion. (10.7). Причината беше, че направих някои промени в моята среда за изграждане.

(Използвам mkbundle, за да изпратя продукт, който използва Mono.)

Поправката беше много проста, трябваше да кажа на clang, че генерираните двоични файлове трябва да работят на OSX 10.6. Добавих следния аргумент към clang:

-mmacosx-version-min=10.6

Проблема решен!

person Andrew Rondeau    schedule 16.10.2012
comment
Имах същия проблем на MacOS Sierra 10.12.6 - опитвайки се да използвам clang за изграждане на компилатора и инструментите на езика за програмиране nim. Добавянето на това към конфигурацията реши проблема - благодаря! - person user208769; 01.08.2017

В 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

Забележка: segmentation fault (SIGSEGV) (номер 11), който наблюдавате, е сигналът, изпратен до процеса, когато ограничението на стека е надвишено според man setrlimit

Забележка: Тъй като командата ulimit трябва да бъде вградена обвивка, ще я намерите документирана в man bash

person Brian Swift    schedule 23.04.2012

Това може да е проблем с разрешенията.

За по-нататъшна диагностика стартирайте програмата си от терминала с префикс sudo dtruss. Вижте кой syscall се изпълнява, преди да хвърлите грешката.

Пример: sudo dtruss /path/to/application

Можете също да го диагностицирате с Xcode или GDB дебъгерите.

person lunixbochs    schedule 16.04.2012
comment
Направих го, но получавам много информация, свързана с паметта, която не мога да разбера. По-късно, разглеждайки опциите за компилиране, сега виждам, че грешката вероятно се дължи на увеличаването на размера на стека. Но при снежния леопард никога не съм имал този проблем. - person Open the way; 17.04.2012
comment
Lion добавя ASLR и защита на паметта към 32-битови приложения... Не виждам други промени, свързани с паметта. - person lunixbochs; 17.04.2012