1.19.2011

Stack Walking

Have you ever needed to determine who's calling your methods or merely needed to inspect the call stack?

There's a fairly simple way of doing it by using the StackTrace class. I'll show you an usage example.
First, let's start by creating a small class that creates a stack of 3 method calls just so that we have some to call stack to look into.
This should do it:



Now, let's call Method1 and hook up an event handler that will gather the stack trace and print some information about each stack frame.


You should pay special attention to the boolean parameter of the StackTrace constructor. It defines if file information should be gathered (the file, line and column of the method being called). As we'll see below, gathering this information incurs in a performance penalty! Also, these values will likely be absent from a release build, as it is built without debug symbols.

You may be wondering about the performance of such a feature. I've made some testing and got back the values below. Note that these tests are merely indicative. My laptop had dozens of applications running that could interfere with the processor availability. Anyway, each value from the results below is the best out of three attempts and the average values for a single execution are consistent. Also, for the testing purposes, the Console.WriteLine instructions were removed.
These tests were made using a Debug version of the application.
The graph above shows the time it takes to run several executions of the ShowStackTrace method. The same tests were made with and without gathering file information. As you can see, there is a substantial difference.
The graph below shows the average time of a single execution.
As you can see, a single run, without file information takes in average 0.05 milliseconds! On a debug build! That seems pretty darn fast. It might be interesting to point out that this is the same way that exceptions gather their stack trace.

I wonder how this times stack up against the times achieved in a stack walk using the dbghelp.dll library. Maybe on a future blog post...

Sem comentários: