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