Debugging NetCF apps with CorDbg - Part VII - Walking the Stack

This installment of the debugging NetCF apps with cordbg series is going to talk about the stack - viewing, walking, etc. Past debugger series posts can be found here.

Commands used
b[reak]
d[own]
p[rint]
sh[ow]
w[here]
u[p]

Modes used
ShowArgs
ShowModules

Just about everyone who has debugged a troublesome application has needed to walk the stack. Most times, when your application (or something it calls) misbehaves, you need to trace back to find who caused the bad data to get to where your code sits, broken in the debugger. 

CorDbg makes this pretty easy using the stack walking commands: u[p] and d[own] . As you can tell by their names, u[p] walks you up the stack and d[own] brings you back down. The w[here] command displays the stack trace (10 frames, by default).  Once you have navigated to your desired frame, you can view source (sh[ow] ), display contents of variables (p[rint] ), set some breakpoints (b[reak] ), etc.

So, how about an example?

In this example, I hit a breakpoint in my code which produced the following stack.
break at #1 <path>\TestDebuggee.exe!<path>\SecondaryClasses.cs:71 TestMethod1+0x0(il) [active]
071: Console.WriteLine("Base: TestMethod1");
(cordbg) w
Thread 0xf1681176 Current State:Normal
0)* NetCF.Test.TestBaseClass::TestMethod1 +0000[IL] in <path>\SecondaryClasses.cs:71
1) NetCF.Test.TestDerivedClass::TestMethod2 +0012[IL] in <path>\SecondaryClasses.cs:122
2) NetCF.Test.TestDebuggee::Main +0241[IL] in <path>\TestDebuggee.cs:93

If we display the source at the current location, we see the source for the currently executing method.
(cordbg) sh 3
068:
069: protected virtual String TestMethod1(Int32 i)
070: {
071:* Console.WriteLine("Base: TestMethod1");
072:
073: String s = i.ToString();
074: s += this.m_AString;

If we walk up the stack, we can display the contents of the arguments passed to the the method. The * symbol indicates the frame the debugger is currently examining.
(cordbg) u
122: Int32 retVal = base.TestMethod1(i).Length;
(cordbg) w
Thread 0xf1681176 Current State:Normal
0) NetCF.Test.TestBaseClass::TestMethod1 +0000[IL] in <path>\SecondaryClasses.cs:71
1)* NetCF.Test.TestDerivedClass::TestMethod2 +0012[IL] in <path>\SecondaryClasses.cs:122
2) NetCF.Test.TestDebuggee::Main +0241[IL] in <path>\TestDebuggee.cs:93
(cordbg) p i
i=2

We can continue on up the stack until we run out of frames.
(cordbg) u
093: i = tdc.TestMethod2(i % 3);
(cordbg) w
Thread 0xf1681176 Current State:Normal
0) NetCF.Test.TestBaseClass::TestMethod1 +0000[IL] in <path>\SecondaryClasses.cs:71
1) NetCF.Test.TestDerivedClass::TestMethod2 +0012[IL] in <path>\SecondaryClasses.cs:122
2)* NetCF.Test.TestDebuggee::Main +0241[IL] in <path>\TestDebuggee.cs:93
(cordbg) u
Cannot go up farther: at top of call stack.

Walking back down is just as simple as going up. Both the u[p] and the d[own] commands accept an optional frame count argument, allowing you to move up and down the stack by more than one frame at a time. For example, if we continue debugging from where we left off (in stack frame #2), issuing a d 2 command will return us back to where we started (frame #0).
(cordbg) d 2
071: Console.WriteLine("Base: TestMethod1");
(cordbg) w
Thread 0xf1681176 Current State:Normal
0)* NetCF.Test.TestBaseClass::TestMethod1 +0000[IL] in <path>\SecondaryClasses.cs:71
1) NetCF.Test.TestDerivedClass::TestMethod2 +0012[IL] in <path>\SecondaryClasses.cs:122
2) NetCF.Test.TestDebuggee::Main +0241[IL] in <path>\TestDebuggee.cs:93

That's really all there is to it. 

Enjoy!
-- DK

Disclaimers:
This posting is provided "AS IS" with no warranties, and confers no rights.
Some of the information contained within this post may be in relation to beta software. Any and all details are subject to change.