UE4.19 で追加されたコールスタック機能について

UE4.19 preview 1 が公開された。

Unreal Engine 4.19 Preview - Unreal Engine Forums
PREVIEW! Preview 1 of the upcoming 4.19 release is available now on the Launcher and GitHub. We are making this Preview available so that our developer commun...

この中でも、今回は、非常に便利なデバッグ機能であるコールスタック機能について紹介する。

コールスタックとは

コールスタックとは、簡単に言うと、プログラム実行中に、これから処理を実行する関数の情報を蓄えた記録である。
その目的としては、例えば対象の関数を実行し、呼び出し元に戻る際、どこに戻ればいいのかを事前に覚えておくことなどが挙げられる。

プログラマー的には非常に一般的な用語で、Visual Studio のような IDE では、デバッグ用の機能として、その記録の中身をみることができるようになっている。
それによって、関数の実行順や、どこから呼び出されているか簡単に調べることができる。

UE4.19 からは、その機能がUE4 のエディタ上からブループリントに対してコールスタックの中身を閲覧できるようになった

コールスタックタブ

Window → Developer Tools → Call Stack を選択する。

すると、このようなタブが表示される。

デバッグ時は常にこのタブを開いておく。

実際に使ってみる

このようなブループリントがあったとする。
Begin Play にブレイクポイントをはっておき、実行してみる。

すると、このような感じでコールスタックにブレイクポイントを置いた箇所の関数名が表示される。
見方としては、上から順に、

  • 今、中断が起きているのは、BP_MyActor の Begin Play イベント
  • その Begin Play を呼び出したのはエンジン内部の C++ コード

といった具合に、呼び出し順が明確にわかる。

またこのリストは、各項目をダブルクリックすると、その項目に該当するノードにジャンプする機能もあって非常に便利だ。

また、ツールバーをよくみてみると、なにやら見知らぬボタンが。
(UE4.18 時点では Step Into のみで、アイコンも違うものだった)

コールスタック機能の追加に伴い、以下の機能が追加・変更された。

Step Over

ブレイクポイントによる中断時、中断箇所のノードを実行後、次のノードに進んで再び中断する。

試しに、上の状態から Step Over (ショートカット:F10) してみる。
コールスタックの表示もそれに合わせて更新されていることが確認できる。
BP_MyActor の Begin Play イベントが呼び出された結果、BP_MyActor のイベントグラフ内で中断していることがわかる。

Step Into

ブレイクポイントによる中断時、中断箇所のノード内部に入れる場合は、その内部に入って再度中断する。
入れない場合は、Step Over を同じくそのノードを実行後、次のノードで中断する。
ここで、ノード内部に入れる場合というのは、ダブルクリックした際にその内部を閲覧できるノード、つまり、ブループリントで定義された関数を指す。

BPFunction の上で Step Over (ショートカット:F11)すると、BPFunction の関数内部で中断する。
合わせて、コールスタックの表示も BPFunction 内部で中断されていることがわかる。

Step Out

ブレイクポイントによる中断時、今いる関数を全て実行ののち、外に抜けつつ、次のノードで中断する。

先ほどの BPFunction の内部から Step Out (ショートカット:Alt+Shift+F11) してみると、 BPFunction を抜けているのが確認できる。
コールスタックの表示では、 BPFunction の実行が完了したため、リストから削除されている。


これらはどれも、普段からデバッガを使用しているプログラマーならばどれも馴染みのある機能で、デバッグ時は非常によく活躍する。
なので、この機能がエディタ上でブループリントに対して行えるようになったというのは非常に心強く感じる。

Blueprint Debugger にも似たようなのなかったっけ?

たしかに、Blueprint Debugger でも実行中の関数の表示がある。

http://historia.co.jp/archives/2854/

が、こちらの場合、上記のような関数の流れを追う場合には、とにかくみにくいの一言に尽きる。

Blueprint Debugger の場合、あくまで実行されたノードの履歴でしかないので、コールスタックとは表示内容が厳密には異なる。
同じ関数名が複数並ぶし、 Value と書かれた名前は、BP の名前ではなく、ワールド上に置かれた名前でしか表示されない。
また、UE4.18 までの Frame Skip / Step Into では、関数やマクロの内部に必ずジャンプしてしまうので、非常に操作が億劫だった。

今後は、ウォッチ中の値などを一覧で見るときは Blueprint Debugger 、関数の流れ追うときはコールスタック。
そして、関数を 1 ステップずつ進める際は、Step Into / Step Over / Step Out を使い分けて使用することでかなり効率よくデバッグができそうだ。

追記:マクロでの Step Over

現在の中断位置がマクロだった場合、 Step Over しても必ず内部のノードに移動して中断する
ブループリントの実行時、マクロはその仕組み上、その場所にノードを展開されて実行される。
そのため、Step Over したとしても、あくまで 1 ノード進める意味で、表示上はマクロ内部で中断となってしまうのだろう。

追記2:マクロでのブレイクポイント

コールスタック機能が入ったおかげか、マクロでブレイクポイントをはった際の挙動が修正されていた。

以前は、マクロにブレイクポイントをはると、必ずそのマクロの内部に入り込んでから中断していた。
UE4.19 では、関数と同様に、ブレイクポイントが見えるマクロの外側で止まるようになる。

個人的に UE4 デバッグ時での一番のイライラポイントだったので、これが解消されたのはほんとに嬉しい。