调试对父函数"belonging"内存的意外使用
Debug unintended use of memory "belonging" to parent function
假设我有一个从给定软件工具调用的函数foo
(在 C/C++ 中)。
函数foo
只允许写入foo
分配的内存或foo
调用的函数之一,但不允许写入在调用foo
之前已执行的函数分配的内存。
我强烈怀疑,在某些地方foo
写入内存是不允许的。
有没有办法系统地调试此行为?也许是瓦尔格林德的一些花哨的旗帜?
Valgrind 手册有一些 Valgrind 函数,您的程序可以调用这些函数。
看起来VALGRIND_MAKE_MEM_NOACCESS
可能是你想要的。
您可以使用自定义分配器(想到加速池)来确保连续分配要"保护"的所有内存。
接下来,在该内存区域中的任何数据发生更改时设置硬件断点。
我会编写一个 GDB 脚本,在您的函数上设置断点,然后在您怀疑正在更改的内存上设置硬件监视,然后继续。
如果函数 foo
正在修改该内存,则硬件手表将在执行该指令时触发该内存。
GDB 脚本可能如下所示:
break foo
commands
up
watch array
down
continue
end
我没有测试,它可能需要调整,尤其是手表表达式。您可能只能监视一个数组元素。我相信硬件观察点实际上只能监视一个整数大小块:32 位上的 4 个字节或 64 位上的 8 个字节。
foo() 可以写入其范围之外的内存的唯一方法是,如果该内存是全局的,即 extern 变量,或者如果 foo() 有一个或多个参数,这些参数本来是只读的,但不知何故它们被修改了。
要验证调用参数是否被修改,您可以创建一个结构来保存参数,并在返回之前将原始参数与保存的参数进行比较。
struct foo_args {
int a;
char *b;
};
void
foo(int a, char *b)
{
struct foo_args args;
args.a = a
args.b = strdup(b);
/* The rest of the foo() code. */
if (args.a != a || strcmp(args.b, b) != 0) {
printf("error - args got modifiedn");
}
free(args.b);
}
如果上述内容没有捕获它,那么可能的情况是全局、堆栈或堆内存已损坏。
要让 valgrind 运行该工具可能不切实际,在这种情况下,您需要为 foo() 创建一个"包装器",并确保使用 valgrind 或类似的东西,它不会做它不应该做的事情。 另一种选择是使用调试库来跟踪/监视内存使用情况,并在发生内存错误时标记它们。
- 将字符串存储在c++中的稳定内存中
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- Win32编译器选项和内存分配
- 当vector是tje全局变量时,c++中vector的内存管理
- 带内存和隔离功能的SQLite
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 迭代时从向量和内存中删除对象
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 在C++中对T*类型执行std::move的意外行为
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 多线程程序中出现意外的内存泄漏
- 调试对父函数"belonging"内存的意外使用
- 带有标准容器和常量引用的c++代码显示出意外的内存
- C++意外的内存错误
- 内存仅在gcc上发生意外更改
- C++、内存和数组.创建我自己的练习哈希图.内存中留下的意外数据
- 发布版本工作意外-内存竞争和奇怪的QThread行为
- 尝试从xml文件训练CvANN_MLP ann时出现意外的内存错误
- 如果其中一个进程意外死亡,进程间内存会发生什么情况