对于内存监控库的实现,我想移动被监控程序的堆栈,并保留上半部分的虚拟内存供监控库使用,遵循TaintTrace、LIFT和Hobbes等工具所使用的" half 'n'half"-model。然而,我似乎并不清楚如何真正做到这一点。只是mmaping所需的内存失败(无法分配内存)。是否需要修改crt?链接器?
发布于 2014-05-07 04:33:09
我不太确定如何分配污染和未污染的内存,以及如何在类似Unix的操作系统中进行优化。
Unix系统中的内存分配是使用brk()和sbrk()完成的。没有比这更多的东西了。对于其他内存空间,您需要使用共享内存分配(您可以通过您的进程将它们设置为只读/写,这样它就可以在您之间“共享”)。
您将遇到的问题是不断增长的内存分配。我不太确定,但根据我对使用共享内存的记忆,您不能轻松地扩展已分配的缓冲区。但较新的界面可能适合您。
-更新:
阅读malloc()文档时,我发现了以下内容:
通常,malloc()从堆中分配内存,并根据需要使用sbrk(2)调整堆的大小。当分配大于MMAP_THRESHOLD字节的内存块时,glibc malloc()实现使用mmap(2)将内存作为私有匿名映射进行分配。默认情况下,MMAP_THRESHOLD为128 kB,但可以使用mallopt(3)进行调整。使用mmap(2)执行的分配不受RLIMIT_DATA资源限制的影响(请参阅getrlimit(2))。
这意味着操作系统已经使用mmap()来分配默认情况下大于128Kb的缓冲区。此外,标准的malloc()还受到此处记录的RLIMIT_DATA的getrlimit()的限制:
进程数据段(初始化数据、未初始化数据和堆)的最大大小。此限制会影响对brk(2)和sbrk(2)的调用,这些调用在遇到此资源的软限制时会失败,并显示错误ENOMEM。
但是,正如malloc()所说,如果您分配大缓冲区(128Kb+),则不会受到该限制的影响。
也就是说,大量内存被分配给内核本身、您的程序、映射到地址的I/O (DMA)、中断表、内存表(MMU管理)和共享内存缓冲区(即,使用共享的mmap()将分配所有进程必须访问的内存地址,即使您还没有使用这些地址,它们也会被保留,以防您要访问它们。)
其中使用共享内存的就是共享库。(二进制文件被加载到共享内存中,因此针对所述共享库运行的所有进程都加载一次。)
https://stackoverflow.com/questions/23494768
复制相似问题