Внезапно ощутил серьезное сопротивление SBCL к запуску на моих машинах с седьмой freebsd. Разбор проблемы у меня занял достаточно продолжительное время, поэтому запишу здесь howto для индексации гуглом, глядишь, кому еще вдруг пригодится.
Ситуация один: количество памяти
Впаялся на одной из машин, i386 32-bit с 3Gb ram. Беда выглядит так:
`--> sh run-sbcl.sh
(running SBCL from: /home/swizard/distr/sbcl/sbcl-1.0.22-x86-freebsd)
mmap: Invalid argument
ensure_space: failed to validate 1073741824 bytes at 0x58000000
(hint: Try "ulimit -a"; maybe you should increase memory limits.)
Hint: "hint" тут совсем не в тему :) Непонятно, с чего вдруг лисп решил, что волен захавать сразу гигабайт, но факт налицо: система ему этого не дает. Пропустим мою возню с ulimit и kern.maxdsiz (говорят, последний для jemalloc более неактуален), перейдем сразу к решению:
`--> sh run-sbcl.sh --dynamic-space-size 512
Половины гигабайта ему вполне хватит.
Update: сделал
патч, который лечит эту проблему
Ситуация два: защита памяти
Впаялся на обеих машинах. Выглядит так:
`--> sh run-sbcl.sh
(running SBCL from: /home/swizard/distr/sbcl-1.0.22-x86-freebsd)
This is SBCL 1.0.22, an implementation of ANSI Common Lisp.
More information about SBCL is available at .
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
Bus error
Эта гадость куда как серьезней. Пришлось и strace'ом гонять, и отладчиком, и вдумчиво читать sbcl internals.
Итак, самые полезные ссылки:
CLIKI:stack exhaustion,
KERNELTRAP:Serious compatibility breakage in -current.
Вкрадце, самое главное:
Из первой -- sbcl на самой вершине стека откусывает контрольный кусочек памяти и закрывает его через mprotects с read/exec. Как только данных в стеке набирается настолько дохрена, что они залезают в этот защищенный участок, возмущенная система кидает SIGSEGV (linux, solaris, netbsd, etc) или SIGBUS (только freebsd). SBCL этот сигнал ловит своим специальным хендлером, и запускает отладчик.
Из второй -- в freebsd7, наконец-то, решили не переть против течения, и теперь попытка залезть в защищенный участок тоже кидает SIGSEGV, как и в других юниксах. Но, тем не менее, это место подперли в sbcl (и cmucl), плюс еще в самой freebsd: /sys/i386/i386/trap.c: в зависимости от релиза операционки либо ловится что-то свое, либо кидается.
Итого, проблема моя заключается в следующем: несмотря на то, что у меня седьмая фряха, в качестве сигнала SBCL, почему-то, все равно получает в морду SIGBUS. Засада в том, что его рантайм определил у меня седьмую версию на машине, и расставил ловушку на SIGSEGV, поэтому от неожиданного сигнала рушится :(
Почему так получается, я так и не понял. Возможно, лисповый бинарник что-то потащил из compat-6x, и ядро решило сохранить ему ABI. Короче, проблема у меня решилась следующим хаком:
sudo sysctl machdep.prot_fault_translation=2
prot_fault_translation == 0 означает: "пытаться определить версию системы, на семерке кидать SIGSEGV, на более старых -- SIGBUS", prot_fault_translation == 1 означает: "всегда кидать SIGBUS", а любое другое значение: "всегда кидать SIGSEGV".
В итоге, приходит тот сигнал, который лисп и ожидает.