如何有效检查地址的VM映射?

问题描述:

我正在写一个跟踪工具,需要处理JIT的输出,所以这个堆栈有时候看起来很奇怪。我想尝试将一些启发式方法应用于地址,以确定它们是代码,数据还是垃圾。 (如果我在某些时候出错了,这没什么大不了的;但是如果进程崩溃了,没有那么多)。如何有效检查地址的VM映射?

我可以cat /proc/«pid»/maps获得Linux中进程的VM映射列表。是否有可能在不解析该文件的情况下从进程内部访问此信息(或任何子集)?检查地址的rwx位应该是理想的。基本上,我想要一个“读取”版本mprotect(2)

如果我不能这样做,那么如何确定访问某个地址是否会导致分段错误? (已经有一个SIGSEGV处理程序安装在这种情况下,我不能轻易覆盖它,或者我只是这么做)。

翻阅所有与内存相关的功能,我发现我可以使用munlock()来确定是否该页面有效。

bool is_address_valid(ADDRINT addr) { 
    static int pagesize = getpagesize(); 

    const void *foo = (const void *)(addr/pagesize * pagesize); 

    if (munlock(foo, 1) == -1) { 
    fprintf(stderr, "munlock(%p=>%p, 1) failed: %s\n", addr, foo, 
      strerror(errno)); 
    return false; 
    } 
    return true; 
} 

非常恶心,但它确实可以防止我的代码崩溃。