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

Некоторое приложение 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). Сообщение об ошибке failed fprintf(...) отображается в верхней части вывода, но поскольку после fprintf нет exit(1), программа продолжает работу с неизмененным размером стека.   -  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 кбайт (чуть меньше 64 МБ). Это можно увидеть с помощью:

bswift$ ulimit -Hs
65532

Даже будучи пользователем root, я не мог увеличить это значение.

Мягкий предел по умолчанию составляет всего 8 МБ:

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. Посмотрите, какой системный вызов он запускает, прежде чем выдавать ошибку.

Пример: 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