c# - Changing an unhandled exception to a handled one in a finally block -


consider program:

using system; static class program {   static void main(string[] args) {     try {       try { throw new a(); }       { throw new b(); }     }     catch (b) { }     console.writeline("all done!");   } }  class : exception { }  class b : exception { } 

here, exception of type a thrown there no handler. in finally block, exception of type b thrown there handler. normally, exceptions thrown in finally blocks win, it's different unhandled exceptions.

when debugging, debugger stops execution when a thrown, , not allow finally block executed.

when not debugging (running stand-alone command prompt), message shown (printed, , crash dialog) unhandled exception, after that, "all done!" printed.

when adding top-level exception handler nothing more rethrow caught exception, well: there no unexpected messages, , "all done!" printed.

i understand how happening: determination of whether exception has handler happens before finally blocks executed. desirable, , current behaviour makes sense. finally blocks should not throwing exceptions anyway.

but this other stack overflow question cites c# language specification , claims finally block required override a exception. reading specification, agree that requires:

  • in current function member, each try statement encloses throw point examined. each statement s, starting innermost try statement , ending outermost try statement, following steps evaluated:
    • if try block of s encloses throw point , if s has 1 or more catch clauses, catch clauses examined [...]
    • otherwise, if try block or catch block of s encloses throw point , if s has finally block, control transferred finally block. if finally block throws exception, processing of current exception terminated. otherwise, when control reaches end point of finally block, processing of current exception continued.
  • if exception handler not located in current function invocation, function invocation terminated, , 1 of following occurs:
    • [...]
  • if exception processing terminates function member invocations in current thread, indicating thread has no handler exception, thread terminated. impact of such termination implementation-defined.

an exception isn't considered unhandled, according reading of spec, until after function invocations have been terminated, , function invocations aren't terminated until finally handlers have executed.

am missing here, or microsoft's implementation of c# inconsistent own specification?

i think problem how .net exception handling built on top of structured exception handling has different rules throwing inside block.

when exception happens seh tries find first handler able handle exception type , starts running blocks, unwinding it, based on seh logic there no such handlers, cries unhandled exception before .net can enforce own rule.

this explains top level handler (but 1 can handle exception type a) fixing problem.

the il looks valid:

.method private hidebysig static void  main(string[] args) cil managed {   .entrypoint   // code size       49 (0x31)   .maxstack  1   il_0000:  nop   il_0001:  nop   .try   {     il_0002:  nop     .try     {       il_0003:  nop       il_0004:  newobj     instance void a::.ctor()       il_0009:  throw     }  // end .try         {       il_000a:  nop       il_000b:  newobj     instance void b::.ctor()       il_0010:  throw     }  // end handler   }  // end .try   catch b    {     il_0011:  pop     il_0012:  nop     il_0013:  ldstr      "b"     il_0018:  call       void [mscorlib]system.console::writeline(string)     il_001d:  nop     il_001e:  nop     il_001f:  leave.s    il_0021   }  // end handler   il_0021:  nop   il_0022:  nop   il_0023:  nop   il_0024:  ldstr      "a"   il_0029:  call       void [mscorlib]system.console::writeline(string)   il_002e:  nop   il_002f:  nop   il_0030:  ret } // end of method program::main 

mono has same problem http://ideone.com/vvopx6


Comments

Popular posts from this blog

java - Oracle EBS .ClassNotFoundException: oracle.apps.fnd.formsClient.FormsLauncher.class ERROR -

c# - how to use buttonedit in devexpress gridcontrol -

nvd3.js - angularjs-nvd3-directives setting color in legend as well as in chart elements -