删除[]失败,如何查找原因
delete [] failed, how to find out the reason?
我有一大堆代码整天都在运行。每周一次,当试图释放某个指针时,它会崩溃:
delete [] p
反向跟踪(使用gdb):
0x00007f4f709f2885 in raise () from /lib64/libc.so.6
0x00007f4f709f4065 in abort () from /lib64/libc.so.6
0x00007f4f70a2f7a7 in __libc_message () from /lib64/libc.so.6
0x00007f4f70a350c6 in malloc_printerr () from /lib64/libc.so.6
我想找出是什么原因导致删除失败:重复删除或其他东西。我怎么能做到呢?
首先,注意反向跟踪包含一个调用malloc_printerr
。该函数将把原因写入标准错误,因此请记住捕获它!
不管是不匹配的new/delete类型,双删除还是无效指针,实际的错误早在实际检测到它的delete之前就发生了。所以gdb不会有太大用处。你必须记录发生在相关指针上的任何事情,并找出它何时出错。
- 如果它是一个无效的指针,它可能是未初始化的内存或缓冲区溢出覆盖它。检查所有对象是否具有正确的构造函数,这些构造函数将可能涉及的任何指针归零。这两种问题都可以用valgrind捕获,缓冲区溢出也可以用较少的开销(但精度较低)使用DUMA库或mudflap (gcc附带)捕获。
- 如果是double-delete,检查在删除指针后是否将涉及的指针归零,除非是在析构函数中(如果在析构函数中删除指针,请确保在构造函数中初始化它)。为相关指针上的所有操作添加日志消息,当指针崩溃时,在日志中跟踪指针似乎已经复活的位置。您也可以尝试对无效指针执行此操作。
- 如果
[]
不匹配,请确保在分配[]
时始终使用[]
删除,而不是以其他方式删除,并确保始终删除完整类型(c++接受删除不完整类型和未定义行为)。 - 上述任何一种都可能是没有正确调用持有相关指针的任何对象的析构函数的次要影响。未能调用析构函数可能是删除类型不正确的指针、删除类型不完整的指针或new和delete的
[]
不匹配的原因。除了检查,添加日志到任何可能相关的构造函数和析构函数,并检查它们是否正确匹配的日志。
不要忘记总是记录指针的值,这样你就可以实际匹配条目。您可能还需要编写一些脚本来分析日志(查找不匹配的条目)。要有足够的空间;通过这种方式很容易生成许多 gb 字节的日志。
一旦您缩小了一些可疑的操作范围,您可能需要将回溯写入日志中。查看backtrace(3)库函数或libwind
编写好的单元测试,使用valgrind执行它们,并希望您能捕获错误。
除此之外,您可以查看代码并搜索bug(例如,"Good Clues, Easy Bugs"文章解释了调试技术)。
相关文章:
- 正在查找文档以获得PS4平台的C++中的设备信息
- 在C++中查找文件
- 模板元程序查找相似的连续类型名称
- 在UNIX系统中使用DIR查找文件的字节大小
- 查找最接近的大于当前数字的数字的索引
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 查找后更改类变量
- 使用正则表达式regex_search在字符串中查找字符串
- 使用gcc从静态链接的文件中查找可选符号
- 在C++中查找范围的长度
- 算法问题:查找从堆栈中弹出的所有序列
- 在Windows中查找扬声器输出的当前音量级别
- 如何在C++中使用X509证书模在令牌中查找私钥
- 使用.find函数在c++中查找字符和另一个字符之间的大小
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 在 for 循环中查找问题时遇到困难
- 设置::查找和查找之间的性能差异<algorithm>
- 联合查找算法(查找周期),不使用 malloc
- 无法使用查找窗口查找窗口
- clang与gcc在查找声明方面有何不同