setjmp / обработка ошибок при сбое сигнала - PullRequest
1 голос
/ 24 марта 2009

Я пытаюсь установить "обработчик сбоя" для многопоточного приложения C OSX Carbon . В Windows я могу легко использовать простой и эффективный __ try {} __except {} SEH для Windows , который прекрасно работает. (Обратите внимание, что это несвязанных с C ++ исключений, это конструкции более низкого уровня C!)

Это очень связано с вопросом, который я задавал на SO ранее : а также на более старый вопрос SO .

Ответ, похоже, заключается в том, чтобы использовать setjmp () перед каждой областью кода, а затем использовать обработчик сигнала для longjmp () назад, если произошел сбой.

Но реализация этого нетривиальна .. из-за многопоточности! Идиома __try {} __except {} в Windows является поточно-ориентированной и просто работает. Но, очевидно, setjmp не является потокобезопасным.

Так как бы выглядела реализация? Я продолжаю думать, что мне придется реализовать некоторое локальное хранилище потоков. В начале я инициализирую setjmp, сохраняя состояние среды в локальном буфере потока, затем обработчик сигнала должен будет снова найти данные среды, просматривая локальную область потока. Однако ни Google, ни SO не показывают никаких доказательств того, что это правильная стратегия, тем более что setjmp () задокументирована как небезопасная для потоков. И разве локальному хранилищу потоков не понадобится каждый поток регистрировать себя и выделять память (для хранения данных среды) и освобождать ее при уничтожении потоков?

Я надеюсь, что смогу создать макрос, который обернет все это, так что в OSX мой код __try __except будет работать.

Итак, как мне сделать многопоточный обработчик аварийного восстановления OSX, используя сигналы и setjmp?

Ответы [ 2 ]

1 голос
/ 24 марта 2009

ReactOS имеет SEH-клон под названием PSEH . ROS Newsletter # 49 содержит краткое упоминание об этом, и вы можете увидеть, как это реализовано в / include / crt / excpt.h , / include /actos / lib / pseh / pseh2.h и т. д. Немного грязного хака с макросами и сборкой (в настоящее время только для x86), но это работает.

При этом взаимодействие между сигналами и потоками в UNIX совершенно безобразно, поэтому, если вы хотите использовать SEH для обработки сигналов ... Я бы посоветовал вам найти альтернативное решение.

0 голосов
/ 24 марта 2009

Я использую аналогичную обработку исключений, используя setjmp / longjmp, и у меня есть локальное хранилище потока. Для каждого нового потока я вызываю функцию инициализации, которая является локальным jmpbuf malloc для потока.

NB! Я никогда не проверял его должным образом в многопоточной среде!

...