Thread overview
v0.91 changes order of static constructors
Jun 01, 2004
Kris
Jun 01, 2004
Walter
Jun 01, 2004
Kris
Jun 01, 2004
Walter
Jun 01, 2004
Kris
Jul 05, 2004
Kris
Jul 19, 2004
Walter
Aug 29, 2004
Walter
Jul 19, 2004
Walter
June 01, 2004
Well, I just got bitten by the "unspecified" order of static constructors. In compiler versions prior to 0.91 (or perhaps 0.90) the mango.examples.Servlets would execute just fine. With 0.91 it fails miserably. This is due to the fact it has a static constructor that creates an instance of mango.io.socket.InternetAddress, and the static *module level* constructor of latter file had not yet been executed.

In other words, mango.io.Socket had not yet initialized the windows socket lib before the InternetAddress was created.  This is purely a dependency on static constructor ordering, with a twist regarding module-level constructors such as that in socket.d

Please, please, please, can we get this static constructor 'ordering' business resolved? Module level constructors seem to be particularly vulnerable ...

(I changed servlets.d to use a good old-fashioned class constructor instead of the static variety, although the original static approach was the "right way" to deal with the class design)



June 01, 2004
Can I be boring and request a canonical example?

"Kris" <someidiot@earthlink.dot.dot.dot.net> wrote in message news:c9h3us$2qjl$1@digitaldaemon.com...
> Well, I just got bitten by the "unspecified" order of static constructors. In compiler versions prior to 0.91 (or perhaps 0.90) the mango.examples.Servlets would execute just fine. With 0.91 it fails miserably. This is due to the fact it has a static constructor that
creates
> an instance of mango.io.socket.InternetAddress, and the static *module level* constructor of latter file had not yet been executed.
>
> In other words, mango.io.Socket had not yet initialized the windows socket lib before the InternetAddress was created.  This is purely a dependency
on
> static constructor ordering, with a twist regarding module-level constructors such as that in socket.d
>
> Please, please, please, can we get this static constructor 'ordering' business resolved? Module level constructors seem to be particularly vulnerable ...
>
> (I changed servlets.d to use a good old-fashioned class constructor
instead
> of the static variety, although the original static approach was the
"right
> way" to deal with the class design)
>
>
>


June 01, 2004
Dash it all! I thought I might get away scot-free ...

I'll have a go Walter. Can you perhaps note how module level static-constructors are invoked, in relation to their class brethren?

- Kris

"Walter" <newshound@digitalmars.com> wrote in message news:c9ienm$1oii$1@digitaldaemon.com...
> Can I be boring and request a canonical example?
>
> "Kris" <someidiot@earthlink.dot.dot.dot.net> wrote in message news:c9h3us$2qjl$1@digitaldaemon.com...
> > Well, I just got bitten by the "unspecified" order of static
constructors.
> > In compiler versions prior to 0.91 (or perhaps 0.90) the mango.examples.Servlets would execute just fine. With 0.91 it fails miserably. This is due to the fact it has a static constructor that
> creates
> > an instance of mango.io.socket.InternetAddress, and the static *module level* constructor of latter file had not yet been executed.
> >
> > In other words, mango.io.Socket had not yet initialized the windows
socket
> > lib before the InternetAddress was created.  This is purely a dependency
> on
> > static constructor ordering, with a twist regarding module-level constructors such as that in socket.d
> >
> > Please, please, please, can we get this static constructor 'ordering' business resolved? Module level constructors seem to be particularly vulnerable ...
> >
> > (I changed servlets.d to use a good old-fashioned class constructor
> instead
> > of the static variety, although the original static approach was the
> "right
> > way" to deal with the class design)
> >
> >
> >
>
>


June 01, 2004
"Kris" <someidiot@earthlink.dot.dot.dot.net> wrote in message news:c9igfc$1r64$1@digitaldaemon.com...
> Dash it all! I thought I might get away scot-free ...
>
> I'll have a go Walter. Can you perhaps note how module level static-constructors are invoked, in relation to their class brethren?

The lexical order in which they appear.


June 01, 2004
I tried some simple examples with the three files attached: test, other, and third. Couldn't get it to fail at all regardless of ordering. Here's the consistent output from that test:

Third module constructor
Third static constructor
Other module constructor
Other static constructor
Third class constructor
Test module constructor
Test static constructor
Other class constructor
Test class constructor

So, going back to the original code I put in some printfs. This is what happens when things go right:

Socket module constructor
Servlet class constructor
Client class constructor
InternetAddress class constructor
Server http::Servlet started on 0.0.0.0:80 with 1 threads, 10 backlogs

Servlet is the main class (also has main() signature in that module). It has a class constructor which turns around and creates an HttpClient class (via an intermediate party) which then creates an InternetAddress instance. The latter resides in the socket.d module, which contains the only module-level constructor in all of Mango.

Everything looks good in the above list. Note that the Socket module constructor is invoked first.

Now, I add the static keyword to the Servlet constructor:

Servlet static constructor
Client class constructor
InternetAddress class constructor
Error: Invalid internet address.

See what happens? The Socket module constructor is not invoked at all, so InternetAddress fails.

I really don't know how I can shrink this down to a tiny size Walter ... I'm missing something crucial when trying to emulate the issue, and can't see what it is. Would it help if I sent you the 3 or 4 files involved just so you could scan them visually? That might turn up something that I could put into a test case ...

- Kris


"Walter" <newshound@digitalmars.com> wrote in message news:c9ienm$1oii$1@digitaldaemon.com...
> Can I be boring and request a canonical example?
>
> "Kris" <someidiot@earthlink.dot.dot.dot.net> wrote in message news:c9h3us$2qjl$1@digitaldaemon.com...
> > Well, I just got bitten by the "unspecified" order of static
constructors.
> > In compiler versions prior to 0.91 (or perhaps 0.90) the mango.examples.Servlets would execute just fine. With 0.91 it fails miserably. This is due to the fact it has a static constructor that
> creates
> > an instance of mango.io.socket.InternetAddress, and the static *module level* constructor of latter file had not yet been executed.
> >
> > In other words, mango.io.Socket had not yet initialized the windows
socket
> > lib before the InternetAddress was created.  This is purely a dependency
> on
> > static constructor ordering, with a twist regarding module-level constructors such as that in socket.d
> >
> > Please, please, please, can we get this static constructor 'ordering' business resolved? Module level constructors seem to be particularly vulnerable ...
> >
> > (I changed servlets.d to use a good old-fashioned class constructor
> instead
> > of the static variety, although the original static approach was the
> "right
> > way" to deal with the class design)
> >
> >
> >
>
>





July 05, 2004
Ran into this same issue again with dmd v0.94, where the static (module-level) constructor for Socket.d is not invoked at the appropriate time. The workarounds for this kind of thing are ugly and fragile at best, so please can we get some traction on the issue?

Since the problem is not reproducible in a small contrived example (the ones I've tried), perhaps the best way to identify the issue is to download Mango, compile it with the provided makefile, and I'll point out exactly how to cause said issue to manifest itself ... that may be a bit more trouble than working with a contrived test, but at least it will identify the problem; yes?

- Kris

p.s. you'll need Mango-9, which will be posted later today ...


"Kris" <someidiot@earthlink.dot.dot.dot.net> wrote in message news:c9j0lk$2i1a$1@digitaldaemon.com...
> I tried some simple examples with the three files attached: test, other,
and
> third. Couldn't get it to fail at all regardless of ordering. Here's the consistent output from that test:
>
> Third module constructor
> Third static constructor
> Other module constructor
> Other static constructor
> Third class constructor
> Test module constructor
> Test static constructor
> Other class constructor
> Test class constructor
>
> So, going back to the original code I put in some printfs. This is what happens when things go right:
>
> Socket module constructor
> Servlet class constructor
> Client class constructor
> InternetAddress class constructor
> Server http::Servlet started on 0.0.0.0:80 with 1 threads, 10 backlogs
>
> Servlet is the main class (also has main() signature in that module). It
has
> a class constructor which turns around and creates an HttpClient class
(via
> an intermediate party) which then creates an InternetAddress instance. The latter resides in the socket.d module, which contains the only
module-level
> constructor in all of Mango.
>
> Everything looks good in the above list. Note that the Socket module constructor is invoked first.
>
> Now, I add the static keyword to the Servlet constructor:
>
> Servlet static constructor
> Client class constructor
> InternetAddress class constructor
> Error: Invalid internet address.
>
> See what happens? The Socket module constructor is not invoked at all, so InternetAddress fails.
>
> I really don't know how I can shrink this down to a tiny size Walter ...
I'm
> missing something crucial when trying to emulate the issue, and can't see what it is. Would it help if I sent you the 3 or 4 files involved just so you could scan them visually? That might turn up something that I could
put
> into a test case ...
>
> - Kris
>
>
> "Walter" <newshound@digitalmars.com> wrote in message news:c9ienm$1oii$1@digitaldaemon.com...
> > Can I be boring and request a canonical example?
> >
> > "Kris" <someidiot@earthlink.dot.dot.dot.net> wrote in message news:c9h3us$2qjl$1@digitaldaemon.com...
> > > Well, I just got bitten by the "unspecified" order of static
> constructors.
> > > In compiler versions prior to 0.91 (or perhaps 0.90) the mango.examples.Servlets would execute just fine. With 0.91 it fails miserably. This is due to the fact it has a static constructor that
> > creates
> > > an instance of mango.io.socket.InternetAddress, and the static *module level* constructor of latter file had not yet been executed.
> > >
> > > In other words, mango.io.Socket had not yet initialized the windows
> socket
> > > lib before the InternetAddress was created.  This is purely a
dependency
> > on
> > > static constructor ordering, with a twist regarding module-level constructors such as that in socket.d
> > >
> > > Please, please, please, can we get this static constructor 'ordering' business resolved? Module level constructors seem to be particularly vulnerable ...
> > >
> > > (I changed servlets.d to use a good old-fashioned class constructor
> > instead
> > > of the static variety, although the original static approach was the
> > "right
> > > way" to deal with the class design)
> > >
> > >
> > >
> >
> >
>
>
>


July 19, 2004
The way to go about this is to not try and develop a canonical example from scratch, but to whittle down the existing example to the minimum by removing everything, and I mean everything, bit by bit until only what causes the problem is left. For example, get rid of the makefile is the first step, replace it with a .bat file. Then, for each module, delete stuff, line by line if necessary, until the minimum is found. It's not just for me, being able to do this is an invaluable skill in debugging apps, and will serve you well. Very often, such whittling away layers of obfuscation uncovers a user bug, and at the least usually suggests a workaround while you wait for a compiler fix.

It's like paleontology, you gotta remove all the dirt from around the bones in order to understand them <g>.

99% of the time, the problem will reduce down to 10 or 15 lines of code.


"Kris" <someidiot@earthlink.dot.dot.dot.net> wrote in message news:ccc8kc$306m$1@digitaldaemon.com...
> Ran into this same issue again with dmd v0.94, where the static (module-level) constructor for Socket.d is not invoked at the appropriate time. The workarounds for this kind of thing are ugly and fragile at best, so please can we get some traction on the issue?
>
> Since the problem is not reproducible in a small contrived example (the
ones
> I've tried), perhaps the best way to identify the issue is to download Mango, compile it with the provided makefile, and I'll point out exactly
how
> to cause said issue to manifest itself ... that may be a bit more trouble than working with a contrived test, but at least it will identify the problem; yes?
>
> - Kris
>
> p.s. you'll need Mango-9, which will be posted later today ...
>
>
> "Kris" <someidiot@earthlink.dot.dot.dot.net> wrote in message news:c9j0lk$2i1a$1@digitaldaemon.com...
> > I tried some simple examples with the three files attached: test, other,
> and
> > third. Couldn't get it to fail at all regardless of ordering. Here's the consistent output from that test:
> >
> > Third module constructor
> > Third static constructor
> > Other module constructor
> > Other static constructor
> > Third class constructor
> > Test module constructor
> > Test static constructor
> > Other class constructor
> > Test class constructor
> >
> > So, going back to the original code I put in some printfs. This is what happens when things go right:
> >
> > Socket module constructor
> > Servlet class constructor
> > Client class constructor
> > InternetAddress class constructor
> > Server http::Servlet started on 0.0.0.0:80 with 1 threads, 10 backlogs
> >
> > Servlet is the main class (also has main() signature in that module). It
> has
> > a class constructor which turns around and creates an HttpClient class
> (via
> > an intermediate party) which then creates an InternetAddress instance.
The
> > latter resides in the socket.d module, which contains the only
> module-level
> > constructor in all of Mango.
> >
> > Everything looks good in the above list. Note that the Socket module constructor is invoked first.
> >
> > Now, I add the static keyword to the Servlet constructor:
> >
> > Servlet static constructor
> > Client class constructor
> > InternetAddress class constructor
> > Error: Invalid internet address.
> >
> > See what happens? The Socket module constructor is not invoked at all,
so
> > InternetAddress fails.
> >
> > I really don't know how I can shrink this down to a tiny size Walter ...
> I'm
> > missing something crucial when trying to emulate the issue, and can't
see
> > what it is. Would it help if I sent you the 3 or 4 files involved just
so
> > you could scan them visually? That might turn up something that I could
> put
> > into a test case ...
> >
> > - Kris
> >
> >
> > "Walter" <newshound@digitalmars.com> wrote in message news:c9ienm$1oii$1@digitaldaemon.com...
> > > Can I be boring and request a canonical example?
> > >
> > > "Kris" <someidiot@earthlink.dot.dot.dot.net> wrote in message news:c9h3us$2qjl$1@digitaldaemon.com...
> > > > Well, I just got bitten by the "unspecified" order of static
> > constructors.
> > > > In compiler versions prior to 0.91 (or perhaps 0.90) the mango.examples.Servlets would execute just fine. With 0.91 it fails miserably. This is due to the fact it has a static constructor that
> > > creates
> > > > an instance of mango.io.socket.InternetAddress, and the static
*module
> > > > level* constructor of latter file had not yet been executed.
> > > >
> > > > In other words, mango.io.Socket had not yet initialized the windows
> > socket
> > > > lib before the InternetAddress was created.  This is purely a
> dependency
> > > on
> > > > static constructor ordering, with a twist regarding module-level constructors such as that in socket.d
> > > >
> > > > Please, please, please, can we get this static constructor
'ordering'
> > > > business resolved? Module level constructors seem to be particularly vulnerable ...
> > > >
> > > > (I changed servlets.d to use a good old-fashioned class constructor
> > > instead
> > > > of the static variety, although the original static approach was the
> > > "right
> > > > way" to deal with the class design)
> > > >
> > > >
> > > >
> > >
> > >
> >
> >
> >
>
>


July 19, 2004
"Kris" <someidiot@earthlink.dot.dot.dot.net> wrote in message news:c9j0lk$2i1a$1@digitaldaemon.com...
> I really don't know how I can shrink this down to a tiny size Walter ...

Start by putting printf's in the static constructors and removing everything else that's in them.

> I'm
> missing something crucial when trying to emulate the issue, and can't see
> what it is.

Removing all the cruft will expose the crucial something.


August 29, 2004
If you do this, I can fix it. -Walter

"Walter" <newshound@digitalmars.com> wrote in message news:cdh9p5$ndb$1@digitaldaemon.com...
> The way to go about this is to not try and develop a canonical example
from
> scratch, but to whittle down the existing example to the minimum by
removing
> everything, and I mean everything, bit by bit until only what causes the problem is left. For example, get rid of the makefile is the first step, replace it with a .bat file. Then, for each module, delete stuff, line by line if necessary, until the minimum is found. It's not just for me, being able to do this is an invaluable skill in debugging apps, and will serve
you
> well. Very often, such whittling away layers of obfuscation uncovers a
user
> bug, and at the least usually suggests a workaround while you wait for a compiler fix.
>
> It's like paleontology, you gotta remove all the dirt from around the
bones
> in order to understand them <g>.
>
> 99% of the time, the problem will reduce down to 10 or 15 lines of code.