【发布时间】:2010-11-14 01:07:57
【问题描述】:
各位,能否推荐一个用于在使用 c++ 构建并在 linux x86_64 下运行的生产多线程服务器上发现内存损坏的工具?我目前面临以下问题:每隔几个小时,我的服务器就会因段错误而崩溃,核心转储显示 malloc/calloc 中发生错误,这绝对是某处内存损坏的迹象。
实际上我已经尝试了一些工具,但运气不佳。以下是我目前的经验:
Valgrind 是一个很棒的(我什至可以说是最好的)工具,但它会大大降低服务器速度,使其无法在生产中使用。我在舞台服务器上尝试过,它确实帮助我找到了一些与内存相关的问题,但即使在修复它们之后,我仍然会在生产服务器上崩溃。我在 Valgrind 下运行了我的舞台服务器几个小时,但仍然没有发现任何严重的错误。
ElectricFence 据说是一个真正的内存猪,但我什至无法让它正常工作。它几乎立即在舞台服务器上随机奇怪的地方出现段错误,而 Valgrind 根本没有显示任何问题。也许 ElectricFence 不支持线程?...我不知道。
DUMA - 与 ElectricFence 的故事相同,但更糟。虽然 EF 生成了带有可读回溯的核心转储,但 DUMA 只向我显示“?????”(是的,服务器肯定是使用 -g 标志构建的)
dmalloc - 我将服务器配置为使用它而不是标准的 malloc 例程,但是它在几分钟后挂起。将 gdb 附加到进程表明它挂在 dmalloc 的某个位置:(
我逐渐变得疯狂,根本不知道下一步该做什么。我有以下工具可供尝试:mtrace、mpatrol 但也许有人有更好的主意?
非常感谢您对此问题的任何帮助。
更新:我设法找到了错误的根源。但是,我在舞台服务器上发现它不是使用 helgrind/DRD/tsan 的生产服务器 - 多个线程之间存在数据竞争,导致内存损坏。关键是使用适当的 valgrind 抑制,因为这些工具显示了太多的误报。仍然我真的不知道如何在生产服务器上发现它而不会显着减速...
【问题讨论】:
-
你是编译 libefence 还是使用 LD_PRELOAD 环境变量?如果用 -DUSE_SEMAPHORE 编译,electricfence 应该是线程安全的
-
我使用的是 libefense.a 而不是 .so。而且我没有自己编译,我在Gentoo上使用emerge安装的。您是否建议使用此标志手动安装它?
-
可能有帮助的一件事是查看 +/- 200 字节的 seg 错误表示数据已损坏的位置。通过查看数据,您可能会了解导致内存损坏的原因。
-
能否请您详细说明一下或提供一个链接,我可以在其中找到更多信息?我怎样才能用 gdb 做到这一点?
-
如果异常addr的值为x,则计算y为x-200,然后在gdb中执行x/400xb y(将y替换为上面计算的地址)
标签: c++ linux memory production corruption