Where is my stack?
In an earlier post I explained why you may get stacks that do not look like what you were expecting when you have FPO optimizations, but even without FPO enabled there are some other scenarios that can cause your application stacks to look somehow “unexpected” in the Concurrency Visualizer. Here are some interesting cases:
- Managed applications running as 64 bit: the stacks are going to be truncated on the first JITed function on the stack. This happens because to unwind stacks on X64 it is necessary to use data that typically lives on the modules themselves. For dynamically generated code, one can provide a callback to expose this information to the stack unwinder. The CLR in fact provides such callback, however, since the mechanism used to collect traces (ETW) runs at the system level it is not safe for it to call arbitrary user code. If you want more details about x64 stack walking, Trey Nash posted a blog entry with the details about it. A workaround for this issue is to NGEN all the target application modules (from the CLR folder just run “ngen install <YourTargetApp.exe>”).
- Sample profile for WOW64 applications: on Vista and Windows 2008 (pre R2) ETW sample stacks are not collected if the profiler interruption happened when the instruction pointer was inside the 32bit application code – so the execution profile is not going to show data of the target application itself. This was fixed on Windows 7 and Windows 2008 R2.
- Blocking (synchronization, I/O, Sleep, etc) inside APCs: this is an atypical usage of APCs but when code blocks when running an APC, the stack is truncated by the Concurrency Analyzer at the call that first put the thread in an alertable state. In a more improbable case your stack may end only with the APC code calling a blocking API (the reverse of what described in the previous sentence!). This unlikely scenario can happen in 64 bit Windows (no matter if running a 32 or 64 bit application) when the same instruction pointer that made the transition to kernel mode is repeated again somewhere in the stack (typically an APC that got blocked in the same function that also put the thread in an alertable state).
I hope that this helps you to understand some of the “unexpected” stacks that you may get. Let us know if you hit some other “strange” stacks in your application.
Paulo Janotti – Parallel Computing Platform