2011-11-29 96 views
2

如何检测24/7应用程序(例如在线游戏服务器)中的内存溢出?系统和工具是linux + gcc。如何检测内存溢出?

有时,内存溢出的原因是将内存写入阵列之外;有时内存溢出的原因是无效指针。

那么,有没有人有这方面的经验,并知道如何预防它?

+2

恕我直言,检测内存溢出的最佳方法是测试和调试,但也许我的思维方式是主流。 – Hauleth

+0

@Hauleth:http://blog.thirstybear.co.uk/2007/07/i-wouldnt-start-from-here.html –

回答

5

预防(在代码级别):

  • 当心你的编译器
  • 使用静态代码检查
  • 使用的警告强编码规范

检测(在运行 - 时间):

+0

我知道的静态代码检查器是“pc lint”,其他工具? –

+0

下面是工具列表http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis。其实我也使用PC-Lint(或者Flexe-Lint的unix版本),因为它很小,易于使用和配置。到目前为止,夹板和cpplint在功能上并不明显。静态代码检查器的问题在于,您只能看到一个“翻译单元”,而不是整体问题。对于具有固定大小数组的缓冲区溢出,这是可以的,但是如果您使用指针,检查器将难以知道缓冲区有多大。但值得一试... – jdehaan

+0

设置最大可能的警告级别也不错 –

2

您重新定义了您的内存分配函数(例如malloc)以分配比存储分配所需的更大的缓冲区,并且使用已知模式填充额外空间,并且您会定期检查该模式是否已损坏。

+0

像调试器那样:-) – Valmond

1

使用valgrind's memory check运行您的程序。

单元测试你的代码尽可能多,然后再执行,然后使用valgrind's memory check

+0

valgrind会影响服务器的性能,所以我只能在测试环境中使用它;但是只发生一些错误 –

2

的行为,正如其他人所说,使用测试期间valgrind和测试详尽。为了在运行时保护,可以替换全局变量operator newoperator delete:替换应该在返回块的两侧都保留一个保护块:operator new将保护块初始化为预定义模式,并且operator delete验证该模式仍然是当下。 operator delete也应该用独特模式覆盖实际内存(而不是全为0),以增加检测到使用悬空指针的可能性。

使用std::vector,特别是调试版本的std::vector,为所有阵列,应防止所有的覆盖,并立即检测到它,在它发生(而不是当你终于释放内存)的网站。但是,在最终的应用程序中,所有的检查都可能会导致性能下降,但是(值得一试)。

+0

以及如何使用矢量的调试版本? –

+0

我知道,用-D_GLIBCXX_DEBUG编译标志编译应用程序:) –

+0

@markmao它依赖于编译器:它默认在Visual Studio下(至少在调试版本中);对于g ++,就像你说的那样:'-D_GLIBCXX_DEBUG'(也许还有'-D_GLIBCXX_DEBUG_PEDANTIC')。其他编译器将需要不同的选项。 –