www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - v0.91 changes order of static constructors

reply "Kris" <someidiot earthlink.dot.dot.dot.net> writes:
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)
May 31 2004
parent reply "Walter" <newshound digitalmars.com> writes:
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)
Jun 01 2004
next sibling parent reply "Kris" <someidiot earthlink.dot.dot.dot.net> writes:
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)
Jun 01 2004
parent "Walter" <newshound digitalmars.com> writes:
"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.
Jun 01 2004
prev sibling parent reply "Kris" <someidiot earthlink.dot.dot.dot.net> writes:
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)
begin 666 test.d M:6, 8V]N<W1R=6-T;W)<;B(I.PT*"0E/=&AE<B!O(#T ;F5W($]T:&5R.PD) 697-T('0 /2!N97< 5&5S=#L-"GT-" `` ` end begin 666 other.d M3W1H97( ;6]D=6QE(&-O;G-T<G5C=&]R7&XB*3L-"GT-" T*8VQA<W, 3W1H M=&%T:6, 8V]N<W1R=6-T;W)<;B(I.PT*"0E4:&ER9"!T:&ER9" ](&YE=R!4 M:&ER9#L- ` end begin 666 third.d M<W1A=&EC('1H:7,H*0T*>PT*"7!R:6YT9B H(E1H:7)D(&UO9'5L92!C;VYS M:7,H*0T*"7L-" D)<')I;G1F(" B5&AI<F0 <W1A=&EC(&-O;G-T<G5C=&]R ` end
Jun 01 2004
next sibling parent reply "Kris" <someidiot earthlink.dot.dot.dot.net> writes:
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)
Jul 05 2004
parent reply "Walter" <newshound digitalmars.com> writes:
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)
Jul 19 2004
parent "Walter" <newshound digitalmars.com> writes:
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.
Aug 29 2004
prev sibling parent "Walter" <newshound digitalmars.com> writes:
"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.
Jul 19 2004