Decrypt my World

Cryptography, Security, Debugging and more!

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

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

  • Comments 2

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) 

  • 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.

  • 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 }" clr

    I hope it helps.

Page 1 of 1 (2 items)
Leave a Comment
  • Please add 6 and 7 and type the answer here:
  • Post
Translate This Page