#不定な位置でクラッシュする・・・
クラッシュが発生するけど、発生位置が不安定、メモリの解放時にエラーに引っかかるなどの場合、 メモリ破壊 が起こっていることがあります。
こういうコードで発生します。
void AStompSampleCharacter::Jump()
{
Super::Jump();
const int32 ArraySize = 32;
TArray<int32> Array;
Array.SetNum(ArraySize);
Array.Shrink();
const int32 ArraySizeAsByte = sizeof(int32) * ArraySize;
int32 *Top = Array.GetData();
for (int32 Index = 0; Index < ArraySizeAsByte/*おおっ*/; Index++)
{
Top[Index] = Index;
}
}
このような不正な処理をおこなった位置で止まってくれれば簡単に修正が可能ですが、
全く関連性のないところで突然で不正な処理が報告されるとなかなか追跡が難しかったりします。
そんなときに役にたつのが StompAllocator です!
#まずは関連情報です
この機能をpullrequestしてくれたPabloさんのブログ
https://pzurita.wordpress.com/2015/06/29/memory-stomp-allocator-for-unreal-engine-4/
メモリ破壊:見つけにくいクラッシュを見つけて修正
https://www.unrealengine.com/ja/blog/memory-corruption-finding-and-fixing-elusive-crashes
[UE4] Memory Allocationについて
https://qiita.com/EGJ-Yutaro_Sawada/items/4983d0ebfa945611d324
#どんなアロケータなの?
ひとつのメモリアロケーション要求に対してひとつの仮想ページを割り当てます。
そしてOSにメモリを開放するときに物理メモリだけを返却して仮想アドレスは予約状態を維持します。
これらの動作を図にすると以下のようなイメージです。
水色の部分、赤い部分を読み込んだり、書き込んだりすると例外が発生します。
赤くなった部分(予約済みの部分)はそれ以降OSのアロケータが利用することはありません。
これらの動作によって不正なメモリアクセスを捕捉します。
#使い方
基本的には起動する際にコマンドラインオプションに -stompmalloc
というオプションを追加することでアロケータを切り替えることが出来ます。
##Visual Studioから起動する場合
デバッガをつないだ状態で例外をトラップしたいのでこの方法がおすすめです。
UnrealVSがインストールしてあればVisualStudioのツールバーにこのようなCommandLineオプションの入力窓があるとおもいますので
ここに -stompmalloc
を追加してあげるのが簡単です。
注意としては大量のメモリを消費するため、PCに多めにメモリを積んであげてください。
メモリが少ないPCでこれを有効にすると大量のページアウト(スワップ)が発生して極端に動作が重くなってしまいます。
##エディタからのスダンドアローン実行
スタンドアローンボタンをぽちっとする前にオプションの詳細設定を開いて、追加の起動パラメータに追記します。
起動した後にVisualStudioからアタッチするのを忘れずに!
#結果
stompallocatorが有効になったあとはテストプレイを行うだけです。
うまく再現できるとこんな感じで不正アクセスの瞬間をとらえることができます!
#参考ソースファイル
WindowsPlatformMemory.cpp
MallocStomp.cpp/.h