如何在 Linux 上调试内存损坏

问题描述 投票:0回答:3

我的 C 应用程序中面临着非常智能的内存损坏。

高负载时会发生损坏。

所以我尝试了purify、valgrind、mprotected,还尝试编写自己的简单保护机制。

Purify / Valgrind - 没有帮助,因为它降低了我的应用程序的性能并且问题没有重现。

mprotected 使用只会将损坏移动到其他内存位置。 (因为它需要将内存与页面大小对齐)。

我的简单保护机制不起作用,因为它还降低了性能。

如何在不降低性能的情况下调试我的应用程序?

c linux memory heap-corruption
3个回答
0
投票

如果您有 64 位,则可以在同一内存上使用始终执行

malloc()
操作的自定义
mmap()
和执行
free()
操作的自定义
munmap()
和另一个
mmap()
。使用互斥体保护这些东西,以避免致命的竞争状况。这会将首次访问已释放内存时出现故障的行为更改为错误。

如果没有找到,请调整自定义

malloc()
,将分配的缓冲区移动到映射区域中尽可能高的位置。

请注意,您不能在 32 位中执行此操作,因为这会疯狂地消耗地址空间。


0
投票

Purify / Valgrind - 没有帮助,因为它降低了我的应用程序的性能并且问题没有重现。

在阅读本文时,我相信您不仅存在内存损坏,还存在一个或多个竞争条件。

所以我会告诉你先用 helgrind 运行来找到比赛条件。但是如果您使用

std::atomic
,helgrind 并不知道内存排序。在这种情况下,它会报告误报并且或多或少无法使用。对于这种情况,我不知道有任何工具可以检查内存顺序,这目前是一个大问题。

如何在不降低性能的情况下调试我的应用程序?

问题是:为什么你的失败取决于表现?您是否有并行 I/O 或运行多个任务/线程?如果是这样,请降低任务或线程或 I/O 的速度,也许您可以强制引发错误。

减慢其他线程/任务速度的提示: 在 Linux 上,您可以将线程/任务绑定到 cpu/核心,并且您希望通过在该核心上添加多个“停止”任务来消耗该单个核心上的更多电量。 任务集。您还可以使用

-O0
或其他技巧来编译代码的特殊部分。

我知道如果您有调试工具,那么找到消失的错误是一场噩梦。但我们真的帮不上什么忙,因为我们没有什么可看的……所以这有点像解读水晶球!


0
投票

使用消毒剂:

在编译标志上添加

-fsanitize=address
-fsanitize=thread
,它可能会指出缺陷。

您还可以添加

-O0
来删除优化(更好的回溯)和
-g
来将符号/调试信息保留在二进制文件中。

© www.soinside.com 2019 - 2024. All rights reserved.