Я использую mprotect, чтобы установить некоторые страницы памяти как защищенные от записи. Когда любая попытка записи выполняется в этой области памяти, программа получает сигнал SIGSEGV. Из обработчика сигнала я знаю, по какому адресу памяти была произведена запись, но я не знаю, как узнать, какая инструкция вызывает нарушение защиты от записи. Поэтому внутри обработчика сигнала я думаю о том, чтобы прочитать регистр счетчика программ (ПК), чтобы получить ошибочную инструкцию. Есть ли простой способ сделать это?
Если вы устанавливаете свой обработчик сигнала, используя sigaction
с SA_SIGINFO
флаг, третий аргумент обработчика сигнала имеет тип void *
но указывает на структуру типа ucontext_t
который в свою очередь содержит структуру типа mcontext_t
, Содержание mcontext_t
определяются реализацией и обычно зависят от архитектуры процессора, но здесь вы найдете счетчик сохраненных программ.
Также возможно, что встроенные функции компилятора (__builtin_return_address
с ненулевым аргументом, я думаю) наряду с таблицами раскрутки может быть в состоянии проследить через обработчик сигнала. Хотя это в некотором смысле более общий характер (он явно не специфичен для cpu-arch), я думаю, что он также более хрупкий, и то, работает ли он на самом деле, может зависеть от cpu-arch- и ABI.
Других решений пока нет …