December 13, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=1513



--- Comment #10 from Don <clugdbug@yahoo.com.au> 2010-12-13 13:20:36 PST ---
I'm not sure that this is a compiler bug. It may be druntime.

With this change:

----
deh.c, _d_framehandler(), line 210

+            else if (prev_ndx == -1)
+            {   // Exception didn't get caught.
+                // Call all the finally blocks skipped in this frame
+                _d_local_unwind(handler_table, frame, ndx);
+            }
        }
    }
    return ExceptionContinueSearch;
----

the finally clauses are called correctly. This isn't a correct patch,
but I think it demonstrates that the exception tables are set up reasonably
correctly. I couldn't find anything wrong with them.
My limited understanding of exception handling is based on this article:
http://www.microsoft.com/msj/0197/exception/exception.aspx

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 16, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=1513


Don <clugdbug@yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|DMD                         |druntime
         AssignedTo|nobody@puremagic.com        |sean@invisibleduck.org


--- Comment #11 from Don <clugdbug@yahoo.com.au> 2010-12-15 17:22:58 PST ---
This is definitely a druntime issue (though it could be an issue with the C stdlib). The bug must lie in the druntime/src/rt/deh.c

In the test case, here's my understanding of what happens:

The first exception is thrown.
Every try block is queried (in _d_framehandler() )to see if it's handled.
Nothing in main() handles it, but something else does. (I think in this case,
it's a catch-all block around main).
Then, the unwinding starts. _d_framehandler() runs this:
    // Have system call all finally blocks in intervening frames
    int retval = _global_unwind((ESTABLISHER_FRAME *)frame, exception_record);

_global_unwind is a wrapper around the Windows system function RtlUnwind.
That calls _dframehandler() again, with EXCEPTION_UNWIND this time.
This calls _d_local_unwind(), to run all of the finally blocks

_d_local_unwind() is also in druntime/deh.c.

In the test case, the finally block contains a throw, so the procedure is
repeated. Again it doesn't get caught until the catch-all.
As before, global_unwind and then local_unwind get called.

The first thing _d_local_unwind() does is set up a double-fault exception
handler.

When it begins the unwind, the double-fault handler gets triggered. The double-fault handler basically just does this:

     if (!(ExceptionRecord->ExceptionFlags & EXCEPTION_UNWIND))
        return ExceptionContinueSearch;
     *((ESTABLISHER_FRAME **)DispatcherContext) = EstablisherFrame;
     return ExceptionCollidedUnwind;

Because it returns ExceptionCollidedUnwind, Windows is supposed to abandon the
original unwinding, and the new unwinding
should take over. But that's doesn't seem to be what happens.
No further unwinding occurs. To my suprise, it returns from _global_unwind
into _d_framehandler, back in the original catch handler, and all the variables
seem to be unchanged (so you have no way of detecting what happened).

Dunno where the problem is. Maybe it could be in _global_unwind in the C
runtime?
This stuff is amazingly undocumented by Microsoft.

This is the most detailed info that I've found:
http://www.nynaeve.net/?p=106
See point 7.
And here is more detail about collided unwinds.
http://www.nynaeve.net/?p=107

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 29, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=1513



--- Comment #12 from Don <clugdbug@yahoo.com.au> 2010-12-29 00:25:26 PST ---
On D2, the behaviour is wrong on all platforms, not just Windows. Roughly speaking, Linux does exception chaining incorrectly, and Windows doesn't do it at all.

These two commits are a first step towards fixing the bug: the problematic code in the C runtime is replaced with a D implementation (the buggy behaviour isn't yet changed though).

http://www.dsource.org/projects/druntime/changeset/458 http://www.dsource.org/projects/druntime/changeset/459

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 07, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=1513



--- Comment #13 from Don <clugdbug@yahoo.com.au> 2011-01-07 14:20:12 PST ---
Fixed for D2: http://www.dsource.org/projects/druntime/changeset/482

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 08, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=1513


Don <clugdbug@yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED


--- Comment #14 from Don <clugdbug@yahoo.com.au> 2011-01-08 13:36:42 PST ---
And it's now fixed for D1.

http://www.dsource.org/projects/phobos/changeset/2282

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
1 2
Next ›   Last »