当程序对可配置存储区进行写访问时,程序如何发出信号?
这与某些调试器中的数据断点功能类似。需要POSIX兼容性,但只要它适用于Linux就不需要。
这里有一个我想要的说明性代码:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void configure_trap(void *FROM, void *TO){
/*
Set a trap on write access to any memory location from
address FROM to address TO.
When the trap is triggered, send SIGTRAP to the process.
There is no need for an answer to have the full code, just
an indication on how to proceed.
*/
}
char *ptr;
void trap_signal_handler(int signum){
if(ptr[123] == 'x'){
printf("Invalid value in ptr[123] !!!\n");
/*
Print a backtrace using libunwind. (Not part of this question.)
*/
}
}
void some_function(){
ptr[123] = 'x';
/*
This write access could be performed directly in this function or
another function called directly or indirectly by this one and it
could reside in this program or in an external library or could even
be performed in a system call.
trap_signal_handler should be called at this point.
After the signal handler has been executed, program should resume
normal operation.
*/
}
int main(){
struct sigaction sa = { .sa_handler = trap_signal_handler };
sigaction(SIGTRAP, &sa, NULL);
ptr = malloc(1024);
configure_trap(&ptr[123], &ptr[123]);
some_function();
return(0);
}
谢谢!
答案 0 :(得分:2)
首先,使用mprotect()
将页面标记为只读。然后在编写时,SIGSEGV
将被提升。您将为此安装信号处理程序,如果使用sigaction
完成,您可以通过检查si_addr
来了解访问了哪个地址。有关详情,请参阅:C SIGSEGV Handler & Mprotect
请注意,mprotect()
的粒度为一页,这意味着如果您尝试保护单个字节,实际上您将保护4 KB(如果这是您的页面大小)。
答案 1 :(得分:1)
使用https://github.com/vicencb/qdbp项目。
mprotect
将内存页面设为只读。SIGSEGV
时,它会一次向程序执行一条指令,直到导致写入只读存储器的指令为止。