Share via


Windbg QuickStart guide (Part 4 - Debugging unexpected program behavior)

First Chance Exceptions 

Let’s assume I have written some really ugly code like what you see here:

 1:  int i = 0;  
 2:  try  
 3:  {  
 4:      i = int.Parse(args[0]);  
 5:  }  
 6:  catch  
 7:  {  
 8:      Console.WriteLine("Invalid Argument");  
 9:  }  
 10: Console.WriteLine(i);  

 

When the user executes the program with invalid arguments, all he will see is an error that the argument is invalid, let’s execute the program with “1”, the user is expecting the output to be 1, but he gets a zero, yet there is no error or exception.

In this case you need to catch the first chance exception, i.e. you want to break when an exception happens even if it is handled in the code.

 

To break on first change exception you use the sx command, From MSDN documentation:

The sx* commands control the action that the debugger takes when an exception occurs in the application that is being debugged, or when certain events occur.

 In this case we want to break on an exception, so we use sxe and since we are interested in CLR exceptions we do sxe clr

0:000> sxe clr

0:000> g

 

Once I enter my input I see this:

(182c.163c): CLR exception - code e0434352 (first chance)

First chance exceptions are reported before any exception handling.

This exception may be expected and handled.

eax=001aedc4 ebx=00000005 ecx=00000005 edx=00000000 esi=001aee84 edi=00000001

eip=7613b9bc esp=001aedc4 ebp=001aee14 iopl=0 nv up ei pl nz ac po nc

cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000212

KERNELBASE!RaiseException+0x58:

7613b9bc c9 leave

 

If I do !pe – this is what I get:

 

0:000> !pe

Exception object: 02563754

Exception type: System.FormatException

Message: Input string was not in a correct format.

InnerException: <none>

StackTrace (generated):

<none>

StackTraceString: <none>

HResult: 80131537

 

To see the stack, I do !clrstack

 

0:000> !clrstack

OS Thread Id: 0x163c (0)

Child SP IP Call Site

001aeed8 7613b9bc [HelperMethodFrame: 001aeed8]

001aef94 6be0d5b4 System.Number.StringToNumber(System.String, System.Globalization.NumberStyles, NumberBuffer ByRef, System.Globalization.NumberFormatInfo, Boolean) [f:\dd\ndp\clr\src\BCL\System\Number.cs @ 1029]

001aefbc 6b41bad2 System.Number.ParseInt32(System.String, System.Globalization.NumberStyles, System.Globalization.NumberFormatInfo) [f:\dd\ndp\clr\src\BCL\System\Number.cs @ 712]

001af088 6b48bc20 System.Int32.Parse(System.String) [f:\dd\ndp\clr\src\BCL\System\Int32.cs @ 140]

001af094 002e008a BuggyApp.Program.Main(System.String[]) [d:\Projects\BuggyApp\Program.cs @ 15]

001af23c 6f5855e2 [GCFrame: 001af23c]

 

Another way to do this is to tell the debugger the execute !pe and !clrstack immediately after seeing the exception:

This is the debugger input:

0:000> sxe -c "!pe;!clrstack" clr

0:000> g

(828.d2c): C++ EH exception - code e06d7363 (first chance)

(828.d2c): CLR exception - code e0434352 (first chance)

Exception object: 025e2268

Exception type: System.IndexOutOfRangeException

Message: Index was outside the bounds of the array.

InnerException: <none>

StackTrace (generated):

<none>

StackTraceString: <none>

HResult: 80131508

OS Thread Id: 0xd2c (0)

Child SP IP Call Site

0028ed84 7613b9bc [HelperMethodFrame: 0028ed84]

0028edf4 00320082 *** WARNING: Unable to verify checksum for BuggyApp.exe

BuggyApp.Program.Main(System.String[]) [d:\Projects\BuggyApp\Program.cs @ 15]

0028ef9c 6f5855e2 [GCFrame: 0028ef9c]

First chance exceptions are reported before any exception handling.

This exception may be expected and handled.

eax=0028ec44 ebx=00000005 ecx=00000005 edx=00000000 esi=0028ed04 edi=00000001

eip=7613b9bc esp=0028ec44 ebp=0028ec94 iopl=0 nv up ei pl nz ac pe nc

cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000216

KERNELBASE!RaiseException+0x58:

7613b9bc c9 leave

 

Breaking on unexpected module load

Another common scenario is when a dll is loaded and you have no idea who is loading it, in this case you want to break when a dll is loaded

0:000> sxe ld mydll

0:000> g

 

When the module is loaded 

ModLoad: 6f580000 6fc03000   C:\path\mydll.dll

eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=7efdd000 edi=003cf400

eip=77d7fc42 esp=003cf2d4 ebp=003cf328 iopl=0         nv up ei pl zr na pe nc

cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246

ntdll!NtMapViewOfSection+0x12:

77d7fc42 83c404          add     esp,4

 Now you can check the stack to see who is responsible for loading it

 

Placing a managed breakpoint

!Name2EEMicrosoft_TeamFoundation_Framework_Server!Microsoft.TeamFoundation.Framework.Server.TeamFoundationApplication

!DumpMT -MD 000007ff0030fe28 <-- From the output of the previous command

!bpmd -md 000007ff0030fd50 <-- From the output of the previous command

Hope you find that helpful, feel free to post any questions!

Comments

  • Anonymous
    March 15, 2012
    Did you mean to do the following? i = int.Parse(args[0]);   Instead of just int.Parse(args[0]); ? In any case, I love learning about windbg. Thanks for this series!

  • Anonymous
    March 15, 2012
    Hi Matt, thanks for the correction, I fixed the post:) Feel free to let me know if there is anything you would like to see covered in this series:)

  • Anonymous
    April 22, 2012
    Hi, I wanted to know if we can take full memory dump of a single module (say a loaded driver) using windbg kernel debugging.

  • Anonymous
    June 27, 2012
    Hi abhijit , I don't know of a way to do that.

  • Anonymous
    June 28, 2016
    Just wanted to say thank you for your Windbg 'tutorials', they have proved most helpful in my gaining a fundamental understanding of debugging and Windbg.