Если кто-то попадает в ситуацию застревания при использовании setjmp / longjmp (не спрашивайте), то компилятор выдает много хороших предупреждений о том, когда вы можете сделать что-то не так.
Но с -Wall -Wextra -pedantic
сборкой при использовании Address Sanitizer в Clang я получил примерно параллельно:
void outer() {
jmp_buf buf;
ERR error;
if (setjmp(buf) ? helper(&error) : FALSE) {
// process whatever helper decided to write into error
return;
}
// do the stuff you wanted to guard that may longjmp.
// error is never modified
}
В longjmp при просмотре кадра стека helper
указатель ошибки равен нулю. Если я смотрю в outer()
фрейм, он говорит, что ошибка «оптимизирована».
Это озадачивает, потому что я компилирую с -O0
. Так что "оптимизировано" странно, чтобы это говорить. Но, как и в случае с большинством вещей longjmp-y, мне интересно, что мешает компилятору принять решение о том, в какой регистр он будет помещать адрес ошибки раньше времени ... а затем сделать это недействительным.
Меня бьет дезинфицирующее средство адресов, или мне действительно нужно написать что-то вроде:
void outer() {
jmp_buf buf;
ERR error;
volatile ERR* error_ptr = &error;
if (setjmp(buf) ? helper(error_ptr) : FALSE) {
// process whatever helper decided to write into error
return;
}
// do the stuff you wanted to guard that may longjmp.
// error is never modified
}
Изучая это, я заметил, что jmp_buf
не являются местными ни в одном из примеров, которые я вижу. Вы не можете этого сделать? : - /
ПРИМЕЧАНИЕ. См. ответ и комментарии @ AnT ниже по вопросу "language-lawyer", касающемуся конструкции setjmp() ? ... : ...
. Но на самом деле то, что я здесь делал, оказалось неработающим вызовом longjmp, который произошел после выхода из функции. Согласно longjmp()
docs (также: здравый смысл), это определенно сломан; Я просто не понимал, что произошло:
Если функция, которая вызвала setjmp, завершилась, поведение не определено (другими словами, разрешены только длинные прыжки вверх по стеку вызовов)
error
не определено, но переменная все еще должна существовать. Я не думаю, что достаточно смотреть на код, примерно параллельный неисправному; вам нужно будет опубликовать MCVE. - person user2357112 supports Monica   schedule 23.05.2015