LINUX.ORG.RU
ФорумJob

$1000 за починку SBCL

 , ,


0

2

Вобщем такое дело - SBCL криво работает с Unix сигналами когда в процесс подгружается к-либо еще рантайм. Крешится, в итоге. На линуксе. Надо починить. Вот я на боунтисорс отдал 1000 баксов на починку.

https://www.bountysource.com/issues/75904410-sbcl-crashes-while-net-is-here

★★

Ответ на: комментарий от Harald

Ну а сколько по-твоему? Я не оракл

lovesan ★★
() автор топика
Ответ на: комментарий от novikovag

Да в дефолтной сборке оно так. Я делал патч для винды, аналогичный, недавно приняли, чтобы SBCL не лез в сигналы других рантаймов, но на линуксе судя по всему все чуть сложнее.

lovesan ★★
() автор топика
Ответ на: комментарий от lovesan

А под Линупсом исключения отлавливаются или только под Виндой? Там под Линупс с десяток функций, можно добавить вывод и отловить в какой происходит сбой.

novikovag
()

Хм, похоже, кое-у кого суббота удалась на славу. Мне кажется, это RTFM для начала. Там что-то написано про особенности (ограничения) работы сторонних тредов в SBCL, в т.ч., связанные с сигналами. SBCL что-то там использует для своих нужд, что приличные процессы не используют. Более подробно я никогда это не копал. Я весьма далёк от того уровня знаний, чтобы это починить, это кто-нибудь типа Дмитрия Иванова. Ну или уж сам stassats. И кроме того, я уже нашёл работу.

den73 ★★★★★
()
Последнее исправление: den73 (всего исправлений: 2)
Ответ на: комментарий от den73

Но в целом - так держать, продолжать гордо нести знамя лиспа!

den73 ★★★★★
()

Как этот bounty вообще работает? Деньги у вложившихся уходят сразу? Они могут передумать? Как определяется, достоин ли «починивший» награды?

i-rinat ★★★★★
()

С сигналами много что криво работает. Типичная ошибка следующая. Если там используется fork, то очень важно, чтобы за ним следовал exec(*) в дочернем процессе, а между этими вызовами должны использоваться исключительно «безопасные» относительно сигналов функции. Грубо говоря, нельзя использовать ни мьютексы, ни printf, ни чего такого. Строго ограниченный набор функций - их штук 200 где-то. Иначе в одном случае из ста крашится дочерний процесс, но не всегда, что затрудняет поиск причины. Многие просто не в курсе, что есть такая проблема. В общем, я бы в первую очередь проверил этот сценарий.

dave ★★★★★
()
Последнее исправление: dave (всего исправлений: 1)
Ответ на: комментарий от dave

Подробнее можно? Я не вижу причин для падения. Вызов обработчиков сигналов и fork работают по-разному. Да и утверждение, что fork годится только для exec, странное.

xaizek ★★★★★
()
Последнее исправление: xaizek (всего исправлений: 1)
Ответ на: комментарий от xaizek

Всё нормально у сигналов с процессами форками. А вот с тредами не совсем. Застолбив хендлеры сигналов, ты можешь получить этот сигнал в любом из тредов, включая основной тред процесса. Так вот, чтобы ненароком некорректно не вывалиться из треда при получении сигнала — нужно в хендлере проверять равен ли tid в текущем контексте tid'у основного треда. Если равен — обрабатывать. Если не равен — ничего не делать. А сигнал получат все треды. Просто нет гарантии, что первым его получит основной тред.

Лавсанчик, оно?

deep-purple ★★★★★
()
Ответ на: комментарий от xaizek

man fork:

CAVEATS There are limits to what you can do in the child process. To be totally safe you should restrict yourself to only executing async-signal safe operations until such time as one of the exec functions is called. All APIs, including global data symbols, in any framework or library should be assumed to be unsafe after a fork() unless explicitly documented to be safe or async-signal safe. If you need to use these frame- works in the child process, you must exec. In this situation it is reasonable to exec yourself.

По-моему у Стивенса есть детали в его знаменитой книге. Я же столкнулся на своей практике. Как раз починил регулярные падения одного сервиса. Потом стало работать как часы.

dave ★★★★★
()
Ответ на: комментарий от deep-purple

Если равен — обрабатывать. Если не равен — ничего не делать.

Так же сигналы будут игнорироваться. Мне кажется, что полностью блокировать сигналы не в основном потоке, а в основном оставлять лишь цикл вокруг sigwait() является более правильным решением.

xaizek ★★★★★
()
Ответ на: комментарий от xaizek

будут игнорироваться

Не игнорироваться. Они будут приняты, просто в хендлере какая-либо работа должна пойти только после условия.

полностью блокировать сигналы не в основном потоке

Возможно. Но блокировать — это блокировать.

deep-purple ★★★★★
()
Ответ на: комментарий от dave

У меня нет такого в мане (онлайн версия). Смысл здесь есть и понятно, что общее состояние между процессами остаётся, но safe or async-signal safe очень жёсткое ограничение. Оно нужно для сигналов, так как они могут прервать эти функции в любом месте, а fork() в пользовательском коде этого не делает (если до форка был лишь один поток).

xaizek ★★★★★
()
Ответ на: комментарий от xaizek

Этот кусок мана с макоси, но мне кажется, что все справедливо и для линукса. У нас как раз падения были на линуксе. Потом исправили. Ну, и Стивенс, как я написал.

dave ★★★★★
()
Ответ на: комментарий от xaizek

Да. Там из сишной проги подгружался скриптик на PHP, который дергал базу.

dave ★★★★★
()
Ответ на: комментарий от xaizek

Или я не понял твоего вопроса. В родительском процессе было много потоков. В дочернем до вызова exec - всего один поток.

dave ★★★★★
()
Ответ на: комментарий от xaizek

Причем проблема хорошо так проявлялась при большой нагрузке. Стабильно. Вероятность единичного сбоя была крайне маленькая, но fork делался часто. Поэтому набиралось.

dave ★★★★★
()
Ответ на: комментарий от dave

Всё правильно понял. Только текущая нить переживает fork(), а глобальное состояние в этот момент может нарушать инварианты из-за других нитей, что позже приведёт к проблемам в новом процессе.

xaizek ★★★★★
()

Вот код который воспроизводит баг исключительно средствами SBCL, без моей библиотеки.

https://gist.github.com/Lovesan/d8c184c8a2d286255af03852e3019bb2

Т.е. для воспроизведения бага достаточно оказать нагрузку на GC и сигналы.

Вещь довольно критическая вобщем, я так понимаю, дело до quicklisp не дойдет пока SBCL не починится.

lovesan ★★
() автор топика

Вобщем, stassats намотал воркараунд. Сразу после того как рантайм .Net Core инициализируется и ставит свои сигналы - мы переустанавливаем оригинальные сигналы SBCL.

Смешное, что дотнету это работать дальше не мешает - спокойно и с GC работает, и с эксепшнами. А вот SBCL зато уже не падает.

lovesan ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.