Восстановление после переполнения стека в Mac OS X - PullRequest
2 голосов
/ 19 ноября 2009

Я внедряю кроссплатформенный язык сценариев для нашего продукта. Существует требование обнаружить и правильно обработать условие переполнения стека в языке VM. Прежде чем перейти и сказать, что в первую очередь убедитесь, что стек не переполнен, перечитайте мое первое предложение - это язык сценариев, и конечные пользователи могут писать неправильные программы на этом языке, которые могут переполнять стек, например, бесконечно. рекурсии.

Теперь я знаю, как обнаружить и устранить переполнение стека в Windows (см. http://support.microsoft.com/kb/315937). Однако я не могу найти решение для Mac OS X.

ВМ реализована на C ++: MSVC ++ в Windows, GCC в Mac OS X.

В идеале механизм должен быть основан на возможностях UNIX, поскольку мы также планируем портировать на Linux.

Спасибо.

Ответы [ 3 ]

3 голосов
/ 19 ноября 2009

OCaml имеет те же ограничения, что и вы (язык сценариев, где программист может вызвать переполнение стека). Его собственный компилятор использует системный стек для вызовов функций - как и вы - и обрабатывает переполнения стека (материализуя их как исключения).

Если вы не получили более четкого ответа, я предлагаю вам посмотреть, как это делается в источниках OCaml .

~/ppc $ cat >> t.ml

let rec f x = (f x) + (f x) ;;

f 0 ;;

~/ppc $ ocamlopt t.ml
~/ppc $ ./a.out 
Fatal error: exception Stack_overflow

Выше приведено для Mac OS X Leopard. Искать #ifdef HAS_STACK_OVERFLOW_DETECTION в исходных файлах.

0 голосов
/ 20 ноября 2009

Посмотрите на libsigsegv . Это библиотека C с подпрограммами, помогающими, среди прочего, реализовать обработчик переполнения стека.

0 голосов
/ 19 ноября 2009

Не можете ли вы определить максимальный размер стека для вашей программы, начало стека, а затем вычислить адрес конца стека? Перед каждой операцией в vm вы можете проверить переполнение стека (увеличение по максимальному адресу) и затем вызвать исключение. Другой способ - написать идентификатор после конца стека (например, DEADBEEF или около того) и проверять его значение после каждой операции стека.


Я до сих пор не понимаю, почему вы не можете добавить проверки (именно так обычно определяется манипуляция со стеком). Но вы все равно можете добавить аппаратную точку останова (при записи) в конце вашей стековой области. Когда он ломается, вы знаете, что у вас есть стекопоток. Я бы не советовал, хотя это может испортить вашу среду отладки.

Но в основном - если у вас есть виртуальная машина, у вас также есть место, которое читает код (например, байт-код) и компилирует / интерпретирует его. Это место, где вы можете проверить метку (сравнимо с проверками для обнаружения переполнения буфера стека).

...