We don’t allow questions seeking recommendations for software libraries, tutorials, tools, books, or other off-site resources. You can edit the question so it can be answered with facts and citations.
Closed 9 years ago.
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(5)
可以使用mmap(MAP_ANONYMOUS)和mprotect函数来操作虚拟内存系统并使用相应的保护标志。当然,您的变量需要限制为系统页面大小的倍数。许多小变量将带来巨大的开销。
当然,您的应用程序在管理内存区域的访问权限时需要正常工作。您还需要对受保护区域使用 mmap() 而不是 malloc。
这是 MMU 的用户空间接口层,采用相对可移植的方式。
mmap 和 mprotect
You can use the mmap (MAP_ANONYMOUS) and mprotect functions to manipulate the virtual memory system and use the corresponding protection flags. Your variables need to be constrained to a multiple of the system page size of course. Lots of small variables will present a significant overhead.
Of course your application needs to work correctly when managing access rights to the memory regions. You also need to use mmap() instead of malloc for the protected regions.
This is the user space interface layer to the MMU, in a relatively portable fashion.
mmap and mprotect
两个不错的选择:
malloc()
和的库free()
具有广泛的调试版本,能够使用页面边界来检测内存溢出/不足、填充分配和释放的内存、泄漏检查等。Two good options:
malloc()
andfree()
with extensive debugging versions, capable of using page boundaries to detect memory overruns/underruns, filling allocated and freed memory, leak-checking, and more.我认为您能做的最好的事情就是启动一个看门狗线程,该线程保留该值的副本并不断将其副本与工作值进行比较。您将无法准确捕获该值何时被覆盖,但您会在所需的任何粒度内收到通知(即,如果您将线程设置为每 10 毫秒检查一次,您将在 10 毫秒内收到通知)。
I think the best you're going to be able to do is to fire off a watchdog thread that keeps a copy of the value and continually compares its copy to the working value. You won't be able to catch exactly when the value is overwritten, but you'll be notified to within whatever granularity you want (i.e., if you set the thread to check every 10ms you'll be notified within 10ms).
mprotect()
系统调用就是您所追求的。这使您可以更改内存区域的保护。Linux 下 x86 上的内存保护是在页面级别(4096 字节)完成的。因此,您必须安排受保护的变量位于其自己的页面上,而不是与任何其他变量共享。一种安排方法是使用 posix_memalign() 为变量分配内存,使用 4096 作为对齐方式,并将大小向上舍入到 4096 的下一个倍数(实际上,您可以使用 < code>sysconf(_SC_PAGESIZE) 以可移植的方式确定页面大小,而不是使用硬编码值)。另一种方法是在联合体中分配变量,将其填充为页面大小的倍数,并使用 gcc 属性 __attribute__ ((aligned (4096)) 来对齐变量
。您的 MMU IRQ 处理程序,您只需使用传递给
sigaction()
函数的结构体的sa_sigaction
成员为SIGSEGV
信号安装一个信号处理程序您的信号处理程序将传递一个siginfo_t
结构作为其第二个参数,该结构将包含一个具有错误指令地址的成员sa_addr
。The
mprotect()
system call is what you're after. This lets you change the protections on a memory region.Memory protection on x86 under Linux is done at the level of a page - 4096 bytes. So you will have to arrange for your protected variable to live on its own page(s), not sharing with any other variables. One way to arrange for this is to use
posix_memalign()
to allocate the memory for the variable, using 4096 as the alignment and rounding up the size to the next multiple of 4096 (Actually, you can usesysconf(_SC_PAGESIZE)
to determine the page size in a portable manner, rather than using a hardcoded value). Another way to is allocate the variable within a union that pads it out to a multiple of the page size, and use the gcc attribute__attribute__ ((aligned (4096))
to align the variable.In place of your MMU IRQ handler, you simply install a signal handler for the
SIGSEGV
signal using thesa_sigaction
member of the structure passed to thesigaction()
function. Your signal handler will be passed asiginfo_t
structure as its second argument, which will contain a membersa_addr
that has the address of the faulting instruction.电子围栏有点旧,但仍然维护良好且有用。许多人将其用作更复杂调试的起点。它非常容易修改。
我也是 Valgrind 的忠实粉丝,但 Valgrind 并非在所有平台上都可用。
Electric fence is sort of old, but still maintained and useful. A number of people have used it as the starting point for more complex debugging. Its extremely easy to modify.
I am also a huge fan of Valgrind, but Valgrind isn't available on all platforms.