С Сете и Вайзер фактически implemented their GC, то основной источник информации является исходным кодом этой реализации (это с открытым исходным кодом).
Чтобы получить значения регистра, вы можете подорвать функцию setjmp()
, которая сохраняет копию регистров в пользовательской структуре (по крайней мере, те регистры, которые должны быть сохранены во всех вызовах функций). Но эта структура не стандартизирована (ее содержимое номинально непрозрачно), и setjmp()
может быть специально обработан компилятором C, что делает его немного нежным, чтобы использовать что-либо кроме longjmp()
(что уже довольно сложно, как есть). Часть встроенной сборки кажется намного проще и безопаснее.
Первая сложная часть реализации GC, по-видимому, способна надежно определить начало и конец стеков (обратите внимание на множественное число: могут быть потоки, каждая со своим собственным стеком). Это требует углубления в документированные детали OS ABI. Когда моя настольная система была машиной Alpha под управлением FreeBSD, реализация Boehm-Weiser не могла работать на ней (хотя она поддерживала Linux на одном процессоре).
Вторая сложная часть будет заключаться в попытке получить поколение, захватив доступ к записи, играя с правами доступа к странице. Это снова потребует чтения некоторых документов о сомнительном существовании и некоторых встроенных сборок.
Ну, конечно, как только вы можете найти рамку стека, которую вы посвятили достаточно подробным сведениям о реализации, чтобы также знать регистры. –
Я не уверен, что ты прав, Ганс. Возможно, мы можем рассчитывать на структуру среды выполнения C для решения этой проблемы. Если мы вызываем неинтенсивную оболочку malloc, которая сбрасывает регистры в стек (flushrs), возможно, мы сможем использовать адрес любых локальных переменных (локальных для нашего malloc) и перемещаться выше в памяти, пока не нажмем адрес argv [0]. – SetJmp