[D-runtime] win32 regression in exception handling

Jonathan M Davis jmdavisProg at gmx.com
Wed Jan 26 21:59:03 PST 2011

On Wednesday 26 January 2011 21:32:13 Brad Roberts wrote:
> On 1/26/2011 11:19 AM, Brad Roberts wrote:
> > On 1/26/2011 8:51 AM, Jonathan M Davis wrote:
> >> On Wednesday 26 January 2011 04:35:13 Don Clugston wrote:
> >>> On 26 January 2011 12:21, Jonathan M Davis <jmdavisProg at gmx.com> wrote:
> >>>> On Wednesday 26 January 2011 03:02:55 Don Clugston wrote:
> >>>>> On 26 January 2011 11:17, Jonathan M Davis <jmdavisProg at gmx.com> wrote:
> >>>>>> On Wednesday 26 January 2011 01:58:50 Don Clugston wrote:
> >>>>>>> On 26 January 2011 10:32, Jonathan M Davis <jmdavisProg at gmx.com> 
> >>>>>>>> How else would an error be thrown?
> >>>>>>> 
> >>>>>>> In many cases, it's thrown by hardware. The exception object is
> >>>>>>> created long after the throw occurred.
> >>>>>>> There are also 'foreign' exceptions, which are thrown by (say) C++.
> >>>>>>> 
> >>>>>>> (I suspect that Linux DMD can't handle any of those -- but Windows
> >>>>>>> DMD can).
> >>>>>> 
> >>>>>> So, what exactly about that makes it a problem that the file and
> >>>>>> line number have default arguments? If it gives the arguments (like
> >>>>>> it pretty much has to be doing),
> >>>>> 
> >>>>> No, it doesn't give the arguments. It has no way of knowing what they
> >>>>> are (in fact, they may not even exist at all).
> >>>>> 
> >>>>> then it doesn't use the defaults, so they don't cause any problems
> >>>>> 
> >>>>>> there. And is it only file and line number which cause problems if
> >>>>>> they have defaults, or is it everything (e.g. Throwable next)?
> >>>>> 
> >>>>> It's only file and line number that are a problem. next will just be
> >>>>> null. The thing which you're maybe not understanding is that in these
> >>>>> cases, the exception object is created when it is caught, not when it
> >>>>> is thrown.
> >>>> 
> >>>> Well, I certainly I have no clue about what is really going on then,
> >>>> and it would probably take a fair bit of discussion and/or research
> >>>> for me to understand. Obviously, there's stuff going on here that's
> >>>> at a far lower level than I'm used to dealing with.
> >>> 
> >>> Yeah, it's a bit hairy. It took me a few weeks to work out what's going
> >>> on. There's all kinds of weird stuff, where you make function calls
> >>> that never return, because the stack disappears...
> >>> In the end, the whole thing is an elaborate illusion that gives you a
> >>> really nice model to program against.
> >>> Fortunately, all of the weirdness is confined to a very small number
> >>> of functions.
> >>> 
> >>>> Regardless, is it all Throwables that have the problem, or is it just
> >>>> Throwable, Exception, and or Error? Throwable and Error really
> >>>> shouldn't be a problem, since programmers wouldn't normally be
> >>>> creating those (at most, they'd be creating objects derived from
> >>>> them), but you definitely lose something if Exception has the problem
> >>>> as well. And you
> >>>> _definitely_ lose something if _all_ Throwables have the problem. In
> >>>> any case, I need to know which ones are a problem if I'm going to fix
> >>>> them.
> >>> 
> >>> It is only Throwable, and Error. Not anything derived from them.
> >>> (Really, I think both of those should eventually become abstract
> >>> classes anyway. Not right now, because compiler changes are required).
> >> 
> >> Well, that shouldn't be much of a problem then. I really would have
> >> expected them to be abstract anyway. I'll check in a fix shortly.
> >> 
> >> - Jonathan M Davis
> > 
> > Hrm.. the revert didn't make the problem go away:
> > 
> > http://d.puremagic.com/test-results/test.ghtml?runid=6631
> > 
> > You can see from the checkout log that the object files were updated, but
> > from the dmd test run, the same test failed in the same way.
> Fixed enough to not crash any more.  The problem is that while there are
> default args on the function, the caller is always responsible for setting
> up the stack correctly.  The calls to the HiddenFuncError code are all
> compiler generated and only generates the one original parameter right
> now.  So I reverted back to the version before the changes.
> I don't know that we're done with this discussion.. but at least the tests
> are passing once again.

Well, I'm not sure that I entirely understand what the problem is, but it sounds 
like the problem relates to the extern(C) functions in particular. So, perhaps 
all of those should be reverted. Proper D code can use the Error types directly 
if it likes, and then I would expect that the default arguments would work just 
fine. It sounds like the default arguments are causing problems in cases where 
what we're dealing with is on a low enough level that the normal D rules don't 
necessarily apply. I did verify that default arguments worked with extern(C) 
before checking in those changes, but apparently what I tested wasn't good 
enough. Perhaps it's because I then called the extern(C) functions from D rather 
than C or C++. That might explain why I missed it.

So, does it sound like it would just be a good idea to revert the changes on the 
extern(C) functions? I'd rather be safe than sorry, and while I do think that in 
general, it's best to have the file and line arguments for exception types have 
default arguments, if we're talking about low level and/or C/C++ code which is 
dealing with it, it might be best to just play it safe and not have the default 
arguments on the extern(C) functions.

- Jonathan M Davis

More information about the D-runtime mailing list