ASでコールスタックを見る

Filed under AS3, Flash
Tagged as ,

ActionScript3.0を駆使したFlashコンテンツを作っていると、関数が呼ばれた時、そのコールスタック(呼び出し元リスト)を見たくなるときがある。スタックトレースと呼ばれる機能ですね。

デバッガで追いかけてもいいのですが、JavaScriptや他のSWFなどと連携していたりしてデバッガが使えない状況では、やっぱりtrace()によるデバッグが基本となるのです。

"Calling Home... from Home" by Jayel Aheram

Error.getStackTrace()

結論から言うと、ErrorオブジェクトのgetStackTrace()メソッドでスタックトレースを文字列として取得することが出来ることが分かりました。

例えば、以下のコードのように、必要なところでErrorオブジェクトを生成し、そこでgetStackTrace()メソッドを呼び出すことになります。

次の例は、「valueパラメータを-1にしているのはどこのどいつだ?」という感じで調べたいときのサンプルコードです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package {
	import flash.display.Sprite;
 
	public class Main extends Sprite {
		private var _value:int	= 0;
 
		public function Main():void {
			trace("TestStackTrace!");
			funcTest1();
			funcTest2();
		}
 
		public function set value( v:int ) :void
		{
			_value	= v;
 
			// _valueを-1にしているときをチェックしたい.
			if ( v == -1 ) {
				var e:Error	= new Error();
				trace("check[-1] @ " + e.getStackTrace() );
			}
		}
 
		private function func1() :void	{ func2(); }
		private function func2() :void	{ setA(); }
		private function func3() :void	{ setC(); }
		private function setA() :void	{ value	= -1; }
		private function setC() :void	{ value	= 12; }
		private function funcTest1() :void	{ func1(); }
		private function funcTest2() :void	{ func3(); }
	}
}

この出力は次のようになります。

TestStackTrace!
check[-1] @ Error
 at Main/set value()[C:\TestStackTrace\src\Main.as:19]
 at Main/setA()[C:\TestStackTrace\src\Main.as:27]
 at Main/func2()[C:\TestStackTrace\src\Main.as:25]
 at Main/func1()[C:\TestStackTrace\src\Main.as:24]
 at Main/funcTest1()[C:\TestStackTrace\src\Main.as:29]
 at Main()[C:\TestStackTrace\src\Main.as:9]

複雑で入り組んだスパゲッティなソースに起因するバグを追いかけているときに、この手法を使うことで一気にデバッグが進むようになります!

calleeは用途が違う

以下は余談。

実は、スタックトレースをどうしたら取れるんだろう?と、ヘルプを見ていて、まず目に付いたのは関数の引数から取れる arguments.callee というパラメータでした。

しかし、これで返ってくるのはFunctionオブジェクトそのもの。

Functionオブジェクトから、自身の名前(関数名)などは取れない模様です。

上記リファレンスページのサンプルを見ても分かるように、calleeは再帰的な処理をうまく使いたいときなどに使用するパラメータのようです。

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*