2011-11-29 94 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')。其他編譯器將需要不同的選項。 –