MANAGED DEBUGGING with WINDBG. Breaking on an Exception. Part 1

Hi all,

This post is a continuation of MANAGED DEBUGGING with WINDBG. Managed Heap. Part 5.

BREAKING ON AN EXCEPTION. Part 1

We can only break on exceptions when doing live debugging, but many of the commands explained here can be used when doing dump analysis, too.

· Exceptions we may get in .NET applications:

§ CLR exception (0xe0434f4d).

§ Stack Overflow exception (0x800703e9).

§ Access Violation (0xc0000005).

§ Integer divide-by-zero exception (0xc0000094).

§ ...

§ Fatal Execution Engine Error (<address of failure>). This normally indicates a bug in CLR or NT Heap corruption when doing P/Invoke with not big enough buffers. The address associated to this exception will tell us where in the code the issue happened.

The debugger will break by default when the process raises most of these exception types, but not on CLR exceptions, for instance.

In ASP.NET, if exceptions are raised in managed threads and they are unhandled, Global Error Handle catches them. But if they are raised in another thread like Timer or Finalizer threads, we will crash the process (it will be recycled).

· We can break on any CLR exception:

When our code raises a CLR exception, we see the following line in the debugger:

(1728.1f58): CLR exception - code e0434f4d (first chance)

Unmanaged world doesn’t know about specific CLR exception types, so all of them are raised with the same exception code: 0xe0434f4d.

As we’ve seen, WinDbg won’t break on any CLR exception by default, as they may be expected. We can break on all CLR exceptions with any of these commands:

0:000> sxe clr

0:000> sxe 0xe0434f4d

And when we break we’ll see something like this:

0:000> g

(1728.1f58): C++ EH exception - code e06d7363 (first chance)

(1728.1f58): CLR exception - code e0434f4d (first chance)

First chance exceptions are reported before any exception handling.

This exception may be expected and handled.

eax=002de8e0 ebx=e0434f4d ecx=00000001 edx=00000000 esi=002de968 edi=0047c600

eip=77a1b09e esp=002de8e0 ebp=002de930 iopl=0 nv up ei pl nz ac po nc

cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000212

KERNEL32!RaiseException+0x58:

77a1b09e c9 leave

· We can break on a specific CLR exception type:

If we know the exact exception type, we can do the following:

0:004> !StopOnException -create System.IndexOutOfRangeException 1

Breakpoint set

0:004> !soe -create System.IndexOutOfRangeException 1

Breakpoint set

And when we break we’ll see something like this:

0:000> g

(1728.1f58): C++ EH exception - code e06d7363 (first chance)

(1728.1f58): CLR exception - code e0434f4d (first chance)

'System.IndexOutOfRangeException hit'

First chance exceptions are reported before any exception handling.

This exception may be expected and handled.

...

77a1b09e c9 leave

We can also stop only on those exceptions which type derives from a given one:

0:004> !soe -derived -create System.SystemException 1

Breakpoint set

· When we break, we can inspect the CLR exception:

Let’s take a look to the call stack of the thread which raised the exception when the debugger breaks:

0:000> kpL

ChildEBP RetAddr

002de930 79f071ac KERNEL32!RaiseException(unsigned long dwExceptionCode = 0xe0434f4d, unsigned long dwExceptionFlags = 1, unsigned long nNumberOfArguments = 1, unsigned long * lpArguments = 0x002de968)+0x58

002de990 79f9293a mscorwks!RaiseTheExceptionInternalOnly(class Object * throwable = 0x01940e4c, int rethrow = 0, int fForStackOverflow = 0)+0x2a8

002de9c8 7a129a34 mscorwks!UnwindAndContinueRethrowHelperAfterCatch(class Frame * pEntryFrame = 0x002dea20, class Exception * pException = 0x004d2aa8)+0x70

002dea68 00b81aad mscorwks!JIT_RngChkFail(void)+0xb0

002deab0 00b819fe WindowsApplication1!WindowsApplication1.Form1.PlayWithArray(<HRESULT 0x80004001>)+0x55

KERNEL32!RaiseException raises the generic CLR exception (0xe0434f4d) to the unmanaged world, but the specific exception we are getting is the one that mscorwks!RaiseTheExceptionInternalOnly raises. We can inspect that specific exception as any other .NET object:

0:000> !DumpObj 0x0195fe94

...

0:000> !do 0x0195fe94

Name: System.IndexOutOfRangeException

MethodTable: 79117f8c

EEClass: 79117f1c

Size: 72(0x48) bytes

(C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)

Fields:

MT Field Offset Type VT Attr Value Name

790fd8c4 40000b5 4 System.String 0 instance 00000000 _className

7910ebc8 40000b6 8 ...ection.MethodBase 0 instance 00000000 _exceptionMethod

790fd8c4 40000b7 c System.String 0 instance 00000000 _exceptionMethodString

790fd8c4 40000b8 10 System.String 0 instance 01935108 _message

79116114 40000b9 14 ...tions.IDictionary 0 instance 00000000 _data

790fdf04 40000ba 18 System.Exception 0 instance 00000000 _innerException

790fd8c4 40000bb 1c System.String 0 instance 00000000 _helpURL

790fd0f0 40000bc 20 System.Object 0 instance 00000000 _stackTrace

790fd8c4 40000bd 24 System.String 0 instance 00000000 _stackTraceString

...

79102290 40000c1 38 System.Int32 0 instance -2146233080 _HResult

790fd8c4 40000c2 30 System.String 0 instance 00000000 _source

...

0:000> !do 01935108

Name: System.String

MethodTable: 790fd8c4

EEClass: 790fd824

Size: 102(0x66) bytes

(C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)

String: Index was outside the bounds of the array.

Fields:

...

Or we can inspect the exception in a more user friendly way:

0:000> !PrintException 0x0195fe94

...

0:000> !pe 0x0195fe94

Exception object: 0195fe94

Exception type: System.IndexOutOfRangeException

Message: Index was outside the bounds of the array.

InnerException: <none>

StackTrace (generated):

<none>

StackTraceString: <none>

HResult: 80131508

We can save some time if we directly inspect the last thrown exception on the current thread:

0:000> !pe

Exception object: 0195fe94

Exception type: System.IndexOutOfRangeException

Message: Index was outside the bounds of the array.

InnerException: <none>

StackTrace (generated):

<none>

StackTraceString: <none>

HResult: 80131508

Next post: MANAGED DEBUGGING with WINDBG. Breaking on an Exception. Part 2.

Index: MANAGED DEBUGGING with WINDBG. Introduction and Index.

Regards,

Alex (Alejandro Campos Magencio)

Comments

  • Anonymous
    May 04, 2011
    Is it also possible to stop on all exceptions but a specific type?I have some code here which throws lots of exceptions of a specific type but catches them. I am looking for another problem which is not analyzed yet, so I need all other exceptins.
  • Anonymous
    May 04, 2011
    This command will make Windbg to break on all .NET exceptions except System.IndexOutOfRangeException:sxe -c "!soe System.IndexOutOfRangeException 3; .if(@$t3==1) {g} .else { !pe }" clrI hope it helps.