sbcl on freebsd 7.*

Dec 02, 2008 05:04

Внезапно ощутил серьезное сопротивление 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".

В итоге, приходит тот сигнал, который лисп и ожидает.

sigbus, code, howto, freebsd, sbcl, sigsegv, google it

Previous post Next post
Up