c# - How to walk the .NET try/catch chain to decide to generate a minidump -


we've hit snag mixing tasks our top-level crash handler , trying find workaround. i'm hoping has ideas.

our tools have top-level crash handler (from appdomain's unhandledexception event) use file bug reports minidumps. works wonderfully. unfortunately, tasks throw wrench in this.

we started using 4.0 tasks , discovered internally in task action execution code, there try/catch grabs exception , stores passing down task chain. unfortunately, existence of catch (exception) unwinds stack , when create minidump call site lost. means have none of local variables @ time of crash, or have been collected, etc.

exception filters seem right tool job. wrap task action code in filter via extension method, , on exception getting thrown call our crash handler code report bug minidump. however, don't want on every exception, because there may try-catch in our own code ignoring specific exceptions. want crash report if catch in task going handle it.

is there way walk chain of try/catch handlers? think if this, walk upwards looking catches until hitting task, , firing crash handler if true.

(this seems long shot figured i'd ask anyway.)

or if has better ideas, i'd love hear them!

update

i created small sample program demonstrates problem. apologies, tried make short possible it's still big. :/

in below example, can #define usetask or #define useworkitem (or none) test out 1 of 3 options.

in non-async case , useworkitem case, minidump generated built @ call site, how need. can load in vs , (after browsing find right thread), see have snapshot taken @ call site. awesome.

in usetask case, snapshot gets taken within finalizer thread, cleaning task. long after exception has been thrown , grabbing minidump @ point useless. can wait() on task make exception handled sooner, or can access exception directly, or can create minidump within wrapper around testcrash itself, of still have same problem: it's late because stack has been unwound 1 catch or another.

note deliberately put try/catch in testcrash demonstrate how want exceptions processed normally, , others caught. useworkitem , non-async cases work how need. tasks right! if somehow use exception filter lets me walk chain of try/catch (without unwinding) until hit catch inside of task, necessary tests myself see if need run crash handler or not. hence original question.

here's sample.

using system; using system.diagnostics; using system.io; using system.net; using system.runtime.interopservices; using system.threading; using system.threading.tasks; using system.collections.generic; using system.linq;  class program {     static void main()     {         appdomain.currentdomain.unhandledexception += (_, __) =>             {                 using (var stream = file.create(@"c:\temp\test.dmp"))                 {                     var process = process.getcurrentprocess();                     minidumpwritedump(                         process.handle,                         process.id,                         stream.safefilehandle.dangerousgethandle(),                         minidumptype.minidumpwithfullmemory,                         intptr.zero,                         intptr.zero,                         intptr.zero);                 }                 process.getcurrentprocess().kill();             };         taskscheduler.unobservedtaskexception += (_, __) =>             debug.writeline("if called, call site has been lost!");          // must in separate func permit collecting task         runtest();          gc.collect();         gc.waitforpendingfinalizers();     }      static void runtest()     {  #if usetask         var t = new task(testcrash);         t.runsynchronously(); #elif useworkitem         var done = false;         threadpool.queueuserworkitem(_ => { testcrash(); done = true; });         while (!done) { } #else         testcrash(); #endif     }      static void testcrash()     {         try         {             new webclient().downloaddata("http://filenoexist");         }         catch (webexception)         {             debug.writeline("caught webexception!");         }         throw new invalidoperationexception("test");     }      enum minidumptype     {         //...         minidumpwithfullmemory = 0x00000002,         //...     }      [dllimport("dbghelp.dll")]     static extern bool minidumpwritedump(         intptr hprocess,         int processid,         intptr hfile,         minidumptype dumptype,         intptr exceptionparam,         intptr userstreamparam,         intptr callbackparam); } 

it sounds if can wrap top-level tasks in exception filter (written in vb.net?) able want. since filter run before task's own exception filter, invoked if nothing else within task handles exception before task gets ahold of it.

here's working sample. create vb library project called exceptionfilter in vb file:

imports system.io imports system.diagnostics imports system.runtime.compilerservices imports system.runtime.interopservices  public module exceptionfilter     private enum minidump_type         minidumpwithfullmemory = 2     end enum      <dllimport("dbghelp.dll")>     private function minidumpwritedump(             byval hprocess intptr,             byval processid int32,             byval hfile intptr,             byval dumptype minidump_type,             byval exceptionparam intptr,             byval userstreamparam intptr,             byval callackparam intptr) boolean     end function      function failfastfilter() boolean         dim proc = process.getcurrentprocess()         using stream filestream = file.create("c:\temp\test.dmp")             minidumpwritedump(proc.handle, proc.id, stream.safefilehandle.dangerousgethandle(),                               minidump_type.minidumpwithfullmemory, intptr.zero, intptr.zero, intptr.zero)         end using         proc.kill()         return false     end function      <extension()>     public function crashfilter(byval task action) action         return sub()                    try                        task()                    catch ex exception when _                        failfastfilter()                    end try                end sub     end function end module 

then create c# project , add reference exceptionfilter. here's program used:

using system; using system.diagnostics; using system.net; using system.threading.tasks; using exceptionfilter;  class program {     static void main()     {         new task(new action(testcrash).crashfilter()).runsynchronously();     }      static void testcrash()     {         try         {             new webclient().downloaddata("http://filenoexist");         }         catch (webexception)         {             debug.writeline("caught webexception!");         }         throw new invalidoperationexception("test");     } } 

i ran c# program, opened dmp file, , checked out call stack. testcrash function on stack (a few frames up) throw new current line.

fyi, think use environment.failfast() on minidump/kill operation, might not work in workflow.


Comments

Popular posts from this blog

c# - how to write client side events functions for the combobox items -

exception - Python, pyPdf OCR error: pyPdf.utils.PdfReadError: EOF marker not found -