If broken it is, fix it you should

Using the powers of the debugger to solve the problems of the world - and a bag of chips    by Tess Ferrandez, ASP.NET Escalation Engineer (Microsoft)

ASP.NET 2.0 Crash case study: Unhandled exceptions

ASP.NET 2.0 Crash case study: Unhandled exceptions

Rate This
  • Comments 84

For a long time all my case studies have been on 1.1. it’s time to venture out in 2.0 land and look at what may seem like a 2.0 specific issue.

 

I say “may seem” because this case study will only directly crash if you are using 2.0, but as you’ll learn later the problem existed in 1.1 and 1.0, it was just way harder to track down.

 

Problem description:

 

Once in a while ASP.NET crashes and we see events in the system event log like this one

 

Event Type:       Warning
Event Source:    W3SVC
Event Category: None
Event ID:          1009
Date:               
2006-04-25
Time:               
09:41:22
PM User:           N/A
Computer:        
SUBSPACE1
Description:
A process serving application pool
'ASP.NET V2.0' terminated unexpectedly. The process id was ‘1732’. The process exit code was ‘0xe0434f4d’.

 

Or this one

 

Event Type:       Warning

Event Source:    W3SVC

Event Category: None

Event ID:          1011

Date:                2006-04-25

Time:                09:41:22

User:                N/A

Computer:         SUBSPACE1

Description:

A process serving application pool 'ASP.NET V2.0' suffered a fatal communication error with the World Wide Web Publishing Service. The process id was '6256'. The data field contains the error number.

 

And in the application event log we get a pretty cryptic error message like this one

 

Event Type:       Error

Event Source:    .NET Runtime 2.0 Error Reporting

Event Category: None

Event ID:          5000

Date:                2006-04-25

Time:                09:41:20

User:                N/A

Computer:         SUBSPACE1

Description:

EventType clr20r3, P1 w3wp.exe, P2 6.0.3790.1830, P3 42435be1, P4 app_code.pn5mfdcr, P5 0.0.0.0, P6 444dcf44, P7 5, P8 5, P9 system.dividebyzeroexception, P10 NIL.

 

 

Initial thoughts:

 

Ok, so what do we know about the issue?  We know that asp.net terminated unexpectedly, and that right before this we got a System.DivideByZeroException…. We also know that the process exit code was 0xe0434f4d whatever that means, hmm…

 

Usually when you get a stopped unexpectedly error message the exit code will be the type of exception that caused the crash.  For example a 0xC0000005 means you got a second chance access violation, 0x800703e9 means you suffered a StackOverflowException but what about 0xe0434f4d? 

 

0xe0434f4d is the exception code for CLR (.net) exceptions, so any managed exception like a NullReferenceException or InvalidOperationException or SQLException… basically all managed exception are natively referred to as 0xe0434f4d.  In this case, if we look closer at the application event log entry we can see that it is in fact a System.DivideByZero exception.

 

Trivia: Just a piece of info of no particular value that you might want to pull out of pocket on your next dateJ 0xe0434f4d or at least 43 4f 4d  are the ASCII values for the letters COM.

 

But hey now… should a .net exception cause the asp.net process to crash???  If you divide by zero in your page and don’t have a try catch block around it, surely you will get one of those “nice” white and yellow error pages saying that an exception occurred on your page, but the process doesn’t just exit. 

 

The answer is yes, you will get one of those pages because the asp.net global error handler will eventually catch your exception, format it for you and print it out on the screen.  But what happens if it is not on an asp.net request, so there is no-one to feedback the exception to? It’s the old paradox: If a tree falls in the forest and nobody is there, does it still make a sound? 

 

In 1.0 and 1.1 it didn’t.  For example if you throw an exception in a piece of code called on a timer, or use QueueUserWorkItem and throw an exception in code executing there, or otherwise throw exceptions in code that is not running inside the context of an asp.net request, the framework will swallow the exception and continue. Or rather it will stop that thread of execution but it won’t die.

 

Doesn’t sound all that bad right?  Really??? 

 

That thread could have been doing anything, and we will never be the wiser that it died.  It could have been holding a lock of some sort, or it could have been in the middle of cleaning up resources, or really a number of different things that will now never happen, but that may immediately or eventually have really bad side effects like hangs or crashes or memory issues, but the exception will be long gone so we cant figure out what it was.

 

The policy for unhandled exceptions was changed in ASP.NET 2.0 to the default for .net which is a process exit.  This can be changed back by adding the following to the aspnet.config in the frameworks directory, but I wouldn’t recommend it without putting in some preventive measures to take care of potential unhandled exceptions on non ASP.NET threads.

 

<configuration>

<runtime>

<legacyUnhandledExceptionPolicy enabled="true" />

</runtime>

</configuration>

 

Troubleshooting the issue:

 

The main task here is to find out where this DivideByZero exception is coming from and why it occurred so there are two ways to figure this out (short of complete code inspection). 

 

Strategy #1 – logging the exception

 

The first way, and this is the way I would probably recommend, is to create an UnhandledExceptionHandler to log the exception along with its stack trace in the event log as shown in this article http://support.microsoft.com/?id=911816

 

You add the handler like this to the web.config:

 

    <system.web>

      <httpModules>

        <add type="WebMonitor.UnhandledExceptionModule, <strong name>" name="UnhandledExceptionModule"/>

      </httpModules>

         

    </system.web>

 

And it hooks an eventhandler up to the UnhandledException event of the current app domain.

 

You don’t actually need to strong name it and add it to the GAC, however if you plan it in multiple applications you should to avoid for the dll being loaded multiple times.

 

Now the next time you get one of these unhandled exceptions, the process will still exit (unless you change the unhandled exception policy), but you have a very good chance of fixing the issue.

 

The event for the exception in this particular sample looks like this…

 

Event Type:       Error

Event Source:    ASP.NET 2.0.50727.0

Event Category: None

Event ID:         0

Date:                2006-04-25

Time:                09:41:20

User:                N/A

Computer:         SUBSPACE1

Description:

 

UnhandledException logged by UnhandledExceptionModule.dll:

 

appId=/LM/w3svc/1/ROOT/CrashMe

 

type=System.DivideByZeroException

 

message=Attempted to divide by zero.

 

stack=

   at MyFinalizerClass.Finalize()

 

.

 

Bingo!!! So the exception occurs in MyFinalizerClass.Finalize() in the CrashMe application.

 

In fact the code for the finalizer for this class looks like this, so it is pretty obvious what caused it, and our work here is done…

 

    ~MyFinalizerClass()

    {

        int i = 0;

        int j = 9;

        i = j / i;

    }

 

Setting up an UnhandledException handler like this is not limited to 2.0. You can absolutely do this in 1.1 as well to determine if you are throwing any unhandled exceptions. The only modification you need to do to the code outlined in the article is to choose a different dll to gather the version from. A prime candidate for this would be mscorlib.dll.

 

 

Strategy #2 – debugging with windbg

 

If you have read any of my previous posts you know I have a special place in my heart for debugging. If you don’t have an unhandledexception eventhandler you can still find out what the exception was by running adplus in crash mode to generate dumps when the process exits.

 

In this particular case  doing this will result in the following files being generated.

 

C:\debuggers\Crash_Mode__Date_04-25-2006__Time_10-11-3030>dir

 Volume in drive C has no label.

 Volume Serial Number is 30D7-F806

 

 Directory of C:\debuggers\Crash_Mode__Date_04-25-2006__Time_10-11-3030

 

2006-04-25  10:12    <DIR>          .

2006-04-25  10:12    <DIR>          ..

2006-04-25  10:11                      4 404 ADPlus_report.txt

2006-04-25  10:11    <DIR>          CDBScripts

2006-04-25  10:11                      9 420 059 PID-3368__W3WP.EXE__1st_chance_IntegerDivide__mini_12D8_2006-04-25_10-11-51-487_0D28.dmp

2006-04-25  10:12                      108 142 158 PID-3368__W3WP.EXE__1st_chance_Process_Shut_Down__full_12D8_2006-04-25_10-12-02-440_0D28.dmp

2006-04-25  10:12                      108 294 606 PID-3368__W3WP.EXE__2nd_chance_NET_CLR__full_12D8_2006-04-25_10-11-54-690_0D28.dmp

2006-04-25  10:12                      35 324 PID-3368__W3WP.EXE__Date_04-25-2006__Time_10-11-3030.log

2006-04-25  10:11                      9 014 Process_List.txt

               6 File(s)    225 905 565 bytes

               3 Dir(s)   4 592 435 200 bytes free

 

 

So at 10-11-51 a 1st chance IntegerDivide exception occurred, followed by a 2nd chance .NET exception (2nd chance meaning that it wasn’t handled), and finally this was followed by a process shutdown.

 

Concentrating on the 2nd chance exception dump and loading up sos.dll from the framework directory

 

0:020> .load C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\sos.dll

 

We can run !threads to give us a list of the threads along with info about which thread the exception occurred on (in this case thread 20, the finalizer thread). 

 

0:020> !threads

ThreadCount: 7

UnstartedThread: 0

BackgroundThread: 7

PendingThread: 0

DeadThread: 0

Hosted Runtime: no

                                                        PreEmptive   GC Alloc                          Lock

   ID    OSID    ThreadOBJ       State        GC          Context                  Domain   Count   APT   Exception

   16    1 c20    000b9778      3808220    Enabled  00000000:00000000 000fddc0     1 Ukn (Threadpool Worker)

  20    2 16d8 000e3bd0      b220 Enabled  0242ab08:0242bf94 000caad8     0 MTA (Finalizer) System.DivideByZeroException (02428f60)

  21    3  b2c 000fa588    80a220 Enabled  00000000:00000000 000caad8     0 MTA (Threadpool Completion Port)

  22    4 16c0 000fd690      1220 Enabled  00000000:00000000 000caad8     0 Ukn

  14    6 1570 0014a970   880a220 Enabled  00000000:00000000 000caad8     0 MTA (Threadpool Completion Port)

  23    7 1b44 00145178   180b220 Enabled  00000000:00000000 000caad8     0 MTA (Threadpool Worker)

  24    5  bac 0014a5b0   880b220 Enabled  00000000:00000000 000caad8     0 MTA (Threadpool Completion Port)

 

 

So from this we know that we are looking at an exception happening during finalization.

 

Since this dump was triggered by the exception this will also be the active thread when you load up the dump.

 

If we look at the native and managed callstack it doesn’t really bring us any closer to the solution…

 

 

0:020> kb 2000

ChildEBP RetAddr  Args to Child             

01eaf9fc 79f97065 e0434f4d 00000001 00000001 kernel32!RaiseException+0x53

01eafa5c 7a05b941 02428f60 00000000 00000000 mscorwks!RaiseTheExceptionInternalOnly+0x226

01eafa70 7a05b9b2 02428f60 00000000 01eafb88 mscorwks!RaiseTheException+0x4c

01eafa98 7a05b9ea 00000000 000e3bd0 4914714b mscorwks!RaiseTheException+0xbe

01eafac4 7a05b9f5 02428f60 00000000 7a0e0701 mscorwks!RealCOMPlusThrow+0x37

01eafad0 7a0e0701 02428f60 7740e5f5 7a36a738 mscorwks!RealCOMPlusThrow+0xa

01eafc00 7a0e16e4 00000000 01eafc38 01eafca8 mscorwks!Thread::RaiseCrossContextException+0x63

01eafcb4 79f3a09c 000fddc0 79f3a0a1 01eafeb4 mscorwks!Thread::DoADCallBack+0x25a

01eafcd0 79f3581e 01eafeb4 79f3ab82 000fddc0 mscorwks!Thread::UserResumeThread+0xf3

01eafcd8 79f3ab82 000fddc0 79f3abb0 01eafd08 mscorwks!ManagedThreadBase::FinalizerAppDomain+0x26

01eafd34 79f350ea 000e3bd0 00000000 01eafd5b mscorwks!SVR::CreateGCHeap+0x163

01eafdb0 79f3500e 00000000 00000000 01eafe6c mscorwks!SVR::CreateGCHeap+0x204

01eafdc8 79ecb4a4 01eafeb4 00000000 00000001 mscorwks!SVR::GCHeap::FinalizerThreadWorker+0xe7

01eafdd8 79ecb442 01eafeb4 01eafe60 79f93fe6 mscorwks!Thread::UserResumeThread+0xfb

01eafe6c 79ecb364 01eafeb4 7740e0c9 00000000 mscorwks!Thread::DoADCallBack+0x355

01eafea8 79ed5e8b 01eafeb4 00000000 000fddc0 mscorwks!Thread::DoADCallBack+0x541

01eafed0 79ed5e56 79f34f4a 00000008 79f6fd87 mscorwks!ManagedThreadBase_NoADTransition+0x32

01eafedc 79f6fd87 79f34f4a 7740e175 00000000 mscorwks!ManagedThreadBase::FinalizerBase+0xb

01eaff14 79ecb00b 00000000 00000000 00000000 mscorwks!SVR::GCHeap::FinalizerThreadStart+0xbb

01eaffb8 77e66063 000e4390 00000000 00000000 mscorwks!Thread::intermediateThreadProc+0x49

01eaffec 00000000 79ecafc5 000e4390 00000000 kernel32!BaseThreadStart+0x34

 

 

0:020> !clrstack

OS Thread Id: 0x16d8 (20)

ESP       EIP    

01eafaac 77e55dea [GCFrame: 01eafaac]

01eafb14 77e55dea [GCFrame: 01eafb14]

01eafd14 77e55dea [GCFrame: 01eafd14]

 

But from the !threads output we get the address of the exception (02428f60) and we can take a deeper look…

 

0:020> !do 02428f60

Name: System.DivideByZeroException

MethodTable: 7915e020

EEClass: 791e97f8

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

790fa3e0  40000b5        4        System.String  0 instance 02429e78 _className

79109208  40000b6        8 ...ection.MethodBase  0 instance 00000000 _exceptionMethod

790fa3e0  40000b7        c        System.String  0 instance 0242a18c _exceptionMethodString

790fa3e0  40000b8       10        System.String  0 instance 02429fb4 _message

79113dfc  40000b9       14 ...tions.IDictionary  0 instance 00000000 _data

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

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

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

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

790fa3e0  40000be       28        System.String  0 instance 0242aab0 _remoteStackTraceString

790fed1c  40000bf       34         System.Int32  0 instance        0 _remoteStackIndex

790f9c18  40000c0       2c        System.Object  0 instance 00000000 _dynamicMethods

790fed1c  40000c1       38         System.Int32  0 instance -2147352558 _HResult

790fa3e0  40000c2       30        System.String  0 instance 0242a3c4 _source

790fe160  40000c3       3c        System.IntPtr  0 instance        0 _xptrs

790fed1c  40000c4       40         System.Int32  0 instance        0 _xcode

 

In particular we can dump out the _remoteStackTraceString and find out where exactly the error occurred.

 

0:020> !do 0242aab0

Name: System.String

MethodTable: 790fa3e0

EEClass: 790fa340

Size: 88(0x58) bytes

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

String:    at MyFinalizerClass.Finalize()

 

Fields:

      MT    Field   Offset                 Type VT     Attr    Value Name

790fed1c  4000096        4         System.Int32  0 instance       36 m_arrayLength

790fed1c  4000097        8         System.Int32  0 instance       35 m_stringLength

790fbefc  4000098        c          System.Char  0 instance       20 m_firstChar

790fa3e0  4000099       10        System.String  0   shared   static Empty

    >> Domain:Value  000caad8:790d6584 000fddc0:790d6584 <<

79124670  400009a       14        System.Char[]  0   shared   static WhitespaceChars

    >> Domain:Value  000caad8:023d03f0 000fddc0:023d4374 <<

 

Voila, there we have it again… our MyFinalizerClass.Finalize()

 

If you want to take away just one thing from this post, it should be to be careful with the code running on non ASP.NET threads, making sure that you have proper try / catch blocks around any code that could cause an exception.

 

Until next time…

 





  • Tess really has the best blog I've seen that discusss how to investigate runtime issues with ASP.NET.&amp;nbsp;...
  • Trackback from dotnetkicks.com
  • I came across a great article that discusses how to investigate runtime issues with ASP.NET.&amp;nbsp; Tess&amp;nbsp;is...
  • TCPView

    TCPView is a Windows program that will show you detailed listings of all TCP and UDP endpoints...
  • Hi Tess, I've got a dump from an ASP.NET app that is not crashing, but it becomes extremely slow for apparently no reason. The # of connections to IIS grows, and the users get no response from the server, although CPU and memory comsumption are low, and things only get back to normal with an app pool restart. I've got the dump with IIS Debug&Diag Tools, and the report shows for several (24) threads that "this thread is blocked by an unhandled exception". !threads shows that of the 36 threads listed, 24 have Lock Count = 1 and Exception = "(Threadpool Worker) System.ArgumentException". I've located the exception for one of those threads with !dso and !do to use what you've shown in the post, but _remoteStackTraceString is 0x00000000. What does that mean? And how can a thread be blocked by an unhandled exception? The app is .NET 1.1 SP1. Shouldn't the framework "swallow" the exception as you said? One more thing that could be related: the app is sending e-mail messages to warn some people about unhandled exceptions, via the global ASP.NET exception handler, and this handler has been quite busy with the ThreadAbortExceptions generated by Response.Redirect. Thanks for any help on this....
  • Hi GB,

    Perhaps you can show the stack of one of the blocked threads, that would help determining why it is blocked (both !clrstack and kb, but you can mark out any proprietary information if you want with some suitable marker like ##### or something).  

    Member variables of exceptions (such as remotestacktracestring) are not always filled in, particularly the remote stack trace is not relevant to an ArgumentException, it is just an inherited member.  There should be a _StackTraceString, but if you are in the middle of the exception it might not be filled out yet. If that is the case you can get the stack directly by doing !clrstack or !dumpstack

  • Hi Tess!!!

    Thanks for the atention. The stack is listed bellow:

    0:051> kb
    ChildEBP RetAddr  Args to Child              
    06e0e4e8 7c931b34 7c916b24 ffffffff 79213ebe ntdll!KiFastSystemCallRet
    06e0e4ec 7c916b24 ffffffff 79213ebe 00000000 ntdll!NtQueryVirtualMemory+0xc
    06e0e54c 7c9240b3 79213ebe 00000000 1433329c ntdll!RtlIsValidHandler+0x82
    06e0e5c0 7c93eda4 06e0a000 06e0e5d0 00010007 ntdll!RtlDispatchException+0x78
    06e0e8a0 7c815dea 06e0e8b0 04961118 e0434f4d ntdll!RtlRaiseException+0x3d
    06e0e900 79216aed e0434f4d 00000001 00000000 kernel32!RaiseException+0x53
    06e0e958 7924c8d0 10824018 00000000 00000000 mscorsvr!RaiseTheException+0xa0
    06e0e9c4 0434da75 06e0e9fc 1433329c 10823ed8 mscorsvr!JIT_Throw+0x4d
    WARNING: Frame IP not in any known module. Following frames may be wrong.
    06e0e9c8 06e0e9fc 1433329c 10823ed8 18671934 0x434da75
    06e0e9cc 1433329c 10823ed8 18671934 03f3b330 0x6e0e9fc
    06e0e9fc 03f3b178 06e0ea54 1c889210 18660d04 0x1433329c
    06e0ea00 06e0ea54 1c889210 18660d04 18672bac 0x3f3b178
    06e0ea04 1c889210 18660d04 18672bac 04759350 0x6e0ea54
    06e0ea54 047592ae 0475a675 047580e0 06e0eb08 0x1c889210
    06e0ea58 0475a675 047580e0 06e0eb08 108eb5e4 0x47592ae
    06e0ea5c 047580e0 06e0eb08 108eb5e4 1078f7d8 0x475a675
    06e0ea60 06e0eb08 108eb5e4 1078f7d8 1c72fa10 0x47580e0
    06e0ea64 108eb5e4 1078f7d8 1c72fa10 00000001 0x6e0eb08
    06e0ebcc 799a67a2 108e64d4 108e67d8 799b4168 0x108eb5e4
    06e0ebd8 799b4168 00000002 00000000 020b480c mscorlib_79990000+0x167a2

    0:051> !dumpstack -ee
    Thread 51
    Current frame:
     ChildEBP RetAddr    Caller,Callee
    06e0e920 799a3ed5 (MethodDesc 0x79b96470 +0x115 System.Text.StringBuilder.Append)
    06e0e9b4 0434df05 (MethodDesc 0x424e988 +0x55 System.Data.ExceptionBuilder.ColumnNotInTheTable)
    06e0e9c4 0434da75 (MethodDesc 0x40abb70 +0x7d System.Data.DataRow.IsNull)
    06e0e9d8 03f3b330 (MethodDesc 0x230e650 +0x20 SGI.Common.Library.getInt32)
    06e0e9fc 03f3b178 (MethodDesc 0x230e570 +0x250 SGI.Common.Library.ValidTypeProperty)
    06e0ea10 04759350 (MethodDesc 0x4741370 +0x88 SGI.Common.List.ReadProperties)
    06e0ea24 03f3fa32 (MethodDesc 0x3fbf3b0 +0x62 SGI.BusinessObject.Coorporativo.UnidadeFuncional..ctor)
    06e0ea44 0475d183 (MethodDesc 0x4748bb0 +0x4b SGI.BusinessObject.Academico.Turma..ctor)
    06e0ea54 047592ae (MethodDesc 0x4741380 +0x6 SGI.Common.List.getNext)
    06e0ea58 0475a675 (MethodDesc 0x4749df8 +0x5 SGI.BusinessObject.Academico.MatriculaInscritoList.SGI.Common.IObjectList.getNext)
    06e0ea5c 047580e0 (MethodDesc 0x230be30 +0x1c8 SGI.UI.Matricula.matricula.BindGradeHoraria)
    06e0ea8c 0475412a (MethodDesc 0x230bd30 +0x92 SGI.UI.Matricula.matricula.Page_Load)
    06e0ea9c 03fc3c3c (MethodDesc 0x22efcf0 +0x44 System.Web.UI.Control.OnLoad)
    06e0eab0 03fc3b84 (MethodDesc 0x22efd00 +0x24 System.Web.UI.Control.LoadRecursive)
    06e0eac4 03f49a7f (MethodDesc 0x23814d8 +0x2ef System.Web.UI.Page.ProcessRequestMain)
    06e0eaec 03f49547 (MethodDesc 0x2381368 +0x1f System.Web.UI.Page.set_FileDependencies)
    06e0eaf8 03f30442 (MethodDesc 0x230c708 +0x32 ASP.matricula_aspx.FrameworkInitialize)
    06e0eb08 03f472d7 (MethodDesc 0x2381498 +0x77 System.Web.UI.Page.ProcessRequest)
    06e0eb44 03f46d3b (MethodDesc 0x2381488 +0x13 System.Web.UI.Page.ProcessRequest)
    06e0eb4c 03f46d14 (MethodDesc 0x2387c50 +0xb4 System.Web.HttpApplication/CallHandlerExecutionStep.System.Web.HttpApplication+IExecutionStep.Execute)
    06e0eb5c 03df9838 (MethodDesc 0x217d730 +0x58 System.Web.HttpApplication.ExecuteStep)
    06e0eba0 03df92a2 (MethodDesc 0x217d760 +0xfa System.Web.HttpApplication.ResumeSteps)
    06e0ebcc 799a67a2 (MethodDesc 0x79bc5b08 +0x12 System.Runtime.InteropServices.GCHandle..ctor)
    06e0ebd8 799b4168 (MethodDesc 0x79bc5b28 +0x10 System.Runtime.InteropServices.GCHandle.Alloc)
    06e0ebec 03df9173 (MethodDesc 0x217d800 +0xe3 System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest)
    06e0ec00 01fd68a7 (MethodDesc 0x1b59888 +0x1e7 System.Web.HttpRuntime.ProcessRequestInternal)
    06e0ec44 01fd6458 (MethodDesc 0x1b59988 +0xb0 System.Web.HttpRuntime.ProcessRequest)
    06e0ec50 01fd2fd5 (MethodDesc 0x1b584d0 +0x65 System.Web.Hosting.ISAPIRuntime.ProcessRequest)

    The exception:

    0:051> !do 0x10824018
    Name: System.ArgumentException
    MethodTable 0x79b9edec
    EEClass 0x79b9ee74
    Size 68(0x44) bytes
    GC Generation: 0
    mdToken: 0x0200003a  (c:\windows\microsoft.net\framework\v1.1.4322\mscorlib.dll)
    FieldDesc*: 0x79b9eed8
           MT      Field     Offset                 Type       Attr      Value Name
    0x79b96824 0x400001d      0x4                CLASS   instance 0x00000000 _className
    0x79b96824 0x400001e      0x8                CLASS   instance 0x00000000 _exceptionMethod
    0x79b96824 0x400001f      0xc                CLASS   instance 0x00000000 _exceptionMethodString
    0x79b96824 0x4000020     0x10                CLASS   instance 0x10823f34 _message
    0x79b96824 0x4000021     0x14                CLASS   instance 0x00000000 _innerException
    0x79b96824 0x4000022     0x18                CLASS   instance 0x00000000 _helpURL
    0x79b96824 0x4000023     0x1c                CLASS   instance 0x00000000 _stackTrace
    0x79b96824 0x4000024     0x20                CLASS   instance 0x00000000 _stackTraceString
    0x79b96824 0x4000025     0x24                CLASS   instance 0x00000000 _remoteStackTraceString
    0x79b96824 0x4000026     0x2c         System.Int32   instance 0 _remoteStackIndex
    0x79b96824 0x4000027     0x30         System.Int32   instance -2147024809 _HResult
    0x79b96824 0x4000028     0x28                CLASS   instance 0x00000000 _source
    0x79b96824 0x4000029     0x34         System.Int32   instance 0 _xptrs
    0x79b96824 0x400002a     0x38         System.Int32   instance -532459699 _xcode
    0x79b9edec 0x40000d7     0x3c                CLASS   instance 0x00000000 m_paramName
    -----------------
    Exception 10824018 in MT 79b9edec: System.ArgumentException
    _message: A coluna 'idSituacaoCurso' não pertence à tabela Table.

    [OBS1. the _message means "The column 'idSituacaoCurso' does not belong to table Table".]
    [OBS2. I got the exception by running !dso and then !do on the only object listed by !dso that was an instance of Exception.]

    The customer gave me a PST Outlook file with the messages that the site generates on each unhandled exception. There were 16.000 (sixteen THOUSAND) messages on a five-day interval. So I monitored ".NET CLR Exceptions\# of Exceps Thrown" and ".NET CLR Exceptions\# of Exceps Thrown/s" with perfmon. The # of exceps thrown/s was at an average of 447 on a 9h30min interval, with maximum at 5.700. PER SECOND!!!! So looking at the code I saw that the SGI.Common.List.ReadProperties() method is extremely likely to be the cause of such a high exception count. But could this count be the cause of the blocked threads? I'm proposing a code change that will avoid this high exception count, but just looking at the dump I have no "black & white" explanation to relate the high exception count to the hung threads.

    Sorry to take advantage of your spare time like this.... It's the price one pays for being famous ;) - and kind enough to anwser the questions.

    Thanks again

    Gilberto

  • To be honest, the thread doesnt really appear to be stuck, but perhaps that message you are getting is due to the shear amount of exceptions you are getting.

    I think it is a fair assumption to make that this exception is probably common as the message seems to indicate that there is an error in the code (giving the wrong column name) which would occurr every time you go through this code path.  But to get a better understanding of what exceptions you get, you can run !DumpAllExceptions or !DumpAllExceptions -v to see what types of exceptions you have gotten recently and how many.  

    An educated guess would be that without the high amount of exceptions you will not be hung.  There is no other reason for the hung state on this thread.

    Thanks Tess
  • Ok Tess,

    Thanks a lot. That's was my conclusion too, I'm writing it now on my report. Perhaps I could quote you on this?.....

    ;) just kidding

    Thanks,

    GB
  • Feel free:)
  • This helped us with part of our problem, but IIS keeps crashing over exception 0x00015dea.  I have been trying to figure out what this exception refers to, but I can't find it.
  • Hi TM,

    To be honest that looks more like an address than an exit code or an exception code.  In fact that address often shows up as the faulting address in kernel32 during a fatal exception.

    I would run adplus straight up in crash mode (without any config files to begin with) and look at the dump that gets generated when the process exits, as well as the log files to look for strange exceptions before the exit.  

    HTH
  • I'm a WinDbg newbie and your blog's a life saver! Thanks!

    I've got a question...when I open crash dumps and run the "!threads" command, I see a list of threads along with the one that caused the exception. But unlike the examples stated in this blog, I don't see the address of the function that caused the exception.


    Here's the sample dump:

    0:000> !threads
    succeeded
    Loaded Son of Strike data table version 5 from "C:\WINMD\Microsoft.NET\Framework\v1.1.4322\mscorsvr.dll"
    ThreadCount: 7
    UnstartedThread: 0
    BackgroundThread: 5
    PendingThread: 0
    DeadThread: 2
                                PreEmptive   GC Alloc               Lock    
          ID ThreadOBJ    State     GC       Context       Domain   Count APT Exception
    XXX     0 0c9e0a20      1820 Enabled  00000000:00000000 000b0458     0 Ukn System.FormatException
  • Hi Mash,

    The exception address is only available in sos.dll for 2.0, and just in case you are debugging for the unhandled exception, that only happens in 2.0.

    But... if you are interested in that format exception you should be able to find it using !dumpheap -type FormatException

Page 2 of 6 (84 items) 12345»
Leave a Comment
  • Please add 6 and 5 and type the answer here:
  • Post