我试图检测用C / C ++编写的每个访问程序在运行时正在进行,特别是动态分配的内存。另外,我想了解一下访问的位置。进行访问的函数名称就是我要找的。 p>
例如,对于以下代码:
void MemoryAccess(int* my_vector) {
int x = my_vector[0]; // Read access from 0xFFFF0000.
my_vector[0] = x + 1; // Write access to 0XFFFF0000.
}
int main(void) {
// Assume that the address returned by malloc is 0xFFFF0000.
int* vec = malloc(VEC_SIZE * sizeof(int));
if (!vec) {
return MEMORY_ALLOCATION_FAIL;
}
MemoryAccess(vec);
int second_elem = vec[1]; // Read access from 0xFFFF0004.
v[1] = 10; // Write access to 0xFFFF0004.
return 0;
}
我想记录一个日志文件,其中包含以下内容:已访问的地址,进行访问的函数名称。对于上面的示例,我的日志应该类似于:
{Read} {MemoryAccess} {0xFFFF0000}
{Write} {MemoryAccess} {0xFFFF0000}
{Read} {main} {0xFFFF0004}
{Write} {main} {0xFFFF0004}
我已经能够在Windows上使用异常过滤器执行类似的操作,并修改受监视内存块的页面保护。我无法获取进行访问的函数名,只有引发异常时才有指令指针值,而我无法知道如何使用它来获取函数名。
注意:我的目标是在基于Linux的系统(主要是Debian / Ubuntu)上监控内存访问,而不是Windows。
答案 0 :(得分:2)
(我专注于Linux)
如果天真地完成,你想要做的就是非常慢并且需要不可移植的代码。我想你想要一个通用的解决方案(处理许多C ++程序,而不是某些特定的程序)。
你可以修补一些模拟器,即la Qemu。
也许您只想使用valgrind或GCC debugging options地址清理程序(搜索-fsanitize=address
)。或使用 gdb
观察点。请注意,最近的GDB可以在Python或Guile中编写脚本。
也许你可以从valgrind
技巧中获取灵感。
同时查看ptrace(2)
如果您不想要灾难性的表现(即,天真地解释每台机器指令和/或为每次内存访问处理SIGSEGV,请参阅this了解更多信息),您需要处理它。
您可以考虑自定义GCC编译器(例如使用MELT),以便某些(相关的)加载& store在编译器中得到了检测。
如果你采取天真的方法(解释每个机器指令和/或粗略的SIGSEGV处理),你可能会使你的程序减慢超过千分之一,并且“半天真”的方法仍然需要数月工作的。你会遇到Heisenbugs。
如果你想要一个认真的方法,你需要修改你的GCC编译器(例如用MELT),这样编译器发出的一些检测代码另外 ,重新编译要检测的程序(以及它正在使用的所有库),这可能至少花费你一年的时间(除非你已经熟悉GCC内部)。
如果您是认真的,请学习更多计算机科学(computer architecture,operating systems,compilers),并让您的博士学位。你需要几年的努力。