View previous topic :: View next topic |
Author |
Message |
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Sat Feb 12, 2005 11:24 pm Post subject: |
|
|
Here's another bit of code to try, which emits the modules in the order they are constructed (adapted from Walter's runtime code):
Code: | import std.stdio;
import std.moduleinit;
void moduleCtor (ModuleInfo[] mi, bool skip, inout bool[char[]] done)
{
foreach (ModuleInfo m; mi)
{
if (! m)
continue;
if (m.name in done)
continue;
if (m.ctor || m.dtor)
{
if (m.flags & MIctorstart)
{
if (skip)
continue;
throw new ModuleCtorError(m);
}
m.flags |= MIctorstart;
moduleCtor (m.importedModules, false, done);
if (m.ctor)
printf("\t?.*s\n", m.name);
m.flags &= ~MIctorstart;
done[m.name] = true;
}
else
{
done[m.name] = true;
moduleCtor (m.importedModules, true, done);
}
}
}
int main ()
{
bool[char[]] done;
moduleCtor (_moduleinfo_array, false, done);
} |
Here's the output from servlets.exe ~ please note that this list is valid, although what Carlos has is not:
Code: | Buffer
Uri
System
Socket
Manager
ConduitStyle
FileStyle
ServletContext
Admin
Event
Layout
Stdout
ConsoleAppender
Configurator
servlets
Token
Tokenizer
HttpTokens
HttpHeaders
AbstractWriter
HttpCookies
HttpParams
Utf8
HttpResponse
HttpRequest
date |
It appears to work as expected, but no guarantees
(Hey Carlos; which version of dmd are you running on Windows? Silly question, I know ...) |
|
Back to top |
|
|
Carlos
Joined: 19 Mar 2004 Posts: 396 Location: Canyon, TX
|
Posted: Sun Feb 13, 2005 12:09 pm Post subject: |
|
|
kris wrote: | Carlos ... you could comment out line 201 in ServletContext, and that should get you going until Walter can resolve this issue.
- Kris |
That worked. But is it "the" solution or just a hack? |
|
Back to top |
|
|
Carlos
Joined: 19 Mar 2004 Posts: 396 Location: Canyon, TX
|
Posted: Sun Feb 13, 2005 12:14 pm Post subject: |
|
|
kris wrote: | Here's another bit of code to try, which emits the modules in the order they are constructed (adapted from Walter's runtime code):
Here's the output from servlets.exe ~ please note that this list is valid, although what Carlos has is not:
Code: | Buffer
Uri
System
Socket
Manager
ConduitStyle
FileStyle
ServletContext
Admin
Event
Layout
Stdout
ConsoleAppender
Configurator
servlets
Token
Tokenizer
HttpTokens
HttpHeaders
AbstractWriter
HttpCookies
HttpParams
Utf8
HttpResponse
HttpRequest
date |
It appears to work as expected, but no guarantees
|
Here are the results:
Code: |
Windows linux
-----------------------------------------------------------
System Buffer
Socket Uri
ConduitStyle Manager
FileStyle ConduitStyle
ServletContext FileStyle
Buffer ServletContext
Uri Admin
Manager RollCall
Admin System
RollCall Socket
Random AbstractWriter
Message Random
Client Message
Cluster Client
Token Cluster
Tokenizer Token
HttpTokens Tokenizer
HttpParams HttpTokens
HttpHeaders HttpHeaders
HttpCookies HttpParams
HttpResponse HttpCookies
AbstractWriter HttpRequest
HttpRequest HttpResponse
CacheInvalidator Utf8
Utf8 CacheInvalidator
Event Event
|
They're different than before, but still Manager is intialized after ServletContext on Windows.
kris wrote: |
(Hey Carlos; which version of dmd are you running on Windows? Silly question, I know ...) |
Right now, DMD 0.113. But the same happened with 0.112 |
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Sun Feb 13, 2005 12:54 pm Post subject: |
|
|
Carlos wrote: | kris wrote: | Carlos ... you could comment out line 201 in ServletContext, and that should get you going until Walter can resolve this issue.
- Kris |
That worked. But is it "the" solution or just a hack? |
Just a hack to let you move on for now ... |
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Sun Feb 13, 2005 1:59 pm Post subject: |
|
|
teqDruid wrote: | Actually, I've been having the same problem on Linux. Again, not sure what's causing it. |
Would you mind posting the 'constructor list' for your application, please John? Via the function posted on page 2? |
|
Back to top |
|
|
teqdruid
Joined: 11 May 2004 Posts: 390 Location: UMD
|
Posted: Sun Feb 13, 2005 2:33 pm Post subject: |
|
|
Sure. If I try to run it without adding some hack code to Manager.d, it segfaults before getting to main. Here's the stacktrace:
Code: | #0 0x08062f06 in _D5mango3log7Manager7Manager9getLoggerFAaZC5mango3log9Hierarchy14LoggerInstance () at mango/log/Manager.d:98
#1 0x08052eb2 in _D5mango3log6Logger6Logger9getLoggerFAaZC5mango3log6Logger6Logger ()
at mango/log/Logger.d:117
#2 0x08052a08 in _D5mango7servlet14ServletContext14ServletContext11_staticCtorFZv ()
#3 0x08052e64 in _modctor_5mango7servlet14ServletContext ()
#4 0x0806a89f in _D3std10moduleinit12_moduleCtor2FAC10ModuleInfoiZv ()
#5 0x0806a7f5 in _moduleCtor ()
#6 0x08069c03 in main ()
|
When I insert the hack, then run it, I get:
Code: | ConduitStyle
FileStyle
Buffer
Stdout
thread
System
Socket
AbstractWriter
ServletContext
ConsoleAppender
UChar
ULocale
UString
DOMException
Element
UNumberFormat
objects
Uri
Utf8
Token
Tokenizer
HttpTokens
HttpParams
HttpHeaders
HttpCookies
HttpResponse
Manager
Event
UConverter
HttpRequest
Layout
date
|
The program I'm trying to run is mango/test/xml.d, if you want to look at the imports. Also of note is that I'm compiling it one file at a time with the -c option. I'm not sure if that makes any difference. |
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Sun Feb 13, 2005 3:20 pm Post subject: |
|
|
teqDruid wrote: | Also of note is that I'm compiling it one file at a time with the -c option. I'm not sure if that makes any difference. |
Thanks ~ the ctor ordering is thoroughly bogus. This is DMD on linux, right? Which compiler version are you running? |
|
Back to top |
|
|
teqdruid
Joined: 11 May 2004 Posts: 390 Location: UMD
|
Posted: Sun Feb 13, 2005 3:28 pm Post subject: |
|
|
Yeah... DMD 0.113 on Linux. |
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Sun Feb 13, 2005 5:40 pm Post subject: Static ctor 'design' is a kludge |
|
|
This is disheartening;
Sooner or later, most D programmers will find the need for a static ctor. In the Mango libraries, they are used to initialize all manner of Singletons; e.g. Stdout & Stdin, various lookup tables (Uri, ServletContext, etc), even instances of exceptions. This is done so the rest of the code can make certain valid assumptions about the environment, which leads to a faster, more manageable, and more maintainable code-base overall.
Static ctors will often form a dependency graph. Therefore, the order in which static ctors are invoked must respect any and all interdependencies. Without this behavior, the utility of static ctors is seriously crippled. Looking at the compiler source-code, there is precious little evidence that it does anything particularly useful with regard to this ordering. Hence, whilst the runtime code (moduleinit.d) tries valiantly to visit the constructors in a valid order, the data-structures it traverses are laid out in a fashion dictated by the order of compilation. This is farcical. As it turns out, Walter has recently added a delicate little footnote to the relevant documentation (â?the order in which they are called is not definedâ?). |
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Sun Feb 13, 2005 6:36 pm Post subject: |
|
|
I've uploaded a mango.servlet.ServletContext which avoids the call to Logger from within the static ctor. This should alleviate the problem in a number of cases, but the underlying issue remains.
You should be OK to download just that one file. |
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Sun Feb 13, 2005 7:48 pm Post subject: |
|
|
Now that I understand what the true issue is, I've uploaded a mango.log.Logger change which persuades the compiler to do the right thing.
edit: hadn't seen this problem since last September, simply because I had my imports ordered in the 'right' fashion. It should be OK from this point on, and Walter will likely patch the compiler to avoid this kind of thing in the future. Sorry for the inconvenience ...
Last edited by kris on Sun Feb 13, 2005 8:09 pm; edited 1 time in total |
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Sun Feb 13, 2005 8:01 pm Post subject: |
|
|
To wrap this up, here's a somewhat deeper look at the problem:
Each object file appears to contain a list of ModuleInfo descriptors, representing those imports which have static ctors ~ where the list order follows that of the module source-code. By maintaining such a list within each module object-file, the design apparently expects to resolve static ctor dependencies at startup time by recursively traversing the ModuleInfo structures across all files linked. I'm guessing there's a little mojo to link the lists together.
The problem occurs when one module acts as a 'proxy' for another in this regard. Specifically:
- module C has a static ctor
- module B imports, and references C, but has no static ctor of its own
- module A imports B, and has a static ctor *indirectly* dependent upon C
In this case, A does not need to import C (doesn't even know it exists), though it must import B. However, the compiler mistakenly drops C from the list belonging to A because the import of B does not expose any static ctors therin. C is orphaned via the lack of a static ctor in B.
Thus, the chain of dependencies is broken. I checked this by adding a dummy static ctor (module-level) to B and, sure enough, the graph was restored.
This whole thing might be resolved by ensuring the compiler does not drop C, just because B does not have a static ctor. The blunt way to do this would be to implicitly inject a static ctor into those modules that don't have one themselves, yet import modules that do (this is already done for class-level static ctors). |
|
Back to top |
|
|
Carlos
Joined: 19 Mar 2004 Posts: 396 Location: Canyon, TX
|
Posted: Wed Mar 02, 2005 8:29 pm Post subject: |
|
|
With DMD 0.114 the problem remains, but now with module Token, in both Windows and linux. You can test it with the lineio sample. |
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Wed Mar 02, 2005 10:07 pm Post subject: |
|
|
Carlos wrote: | With DMD 0.114 the problem remains, but now with module Token, in both Windows and linux. You can test it with the lineio sample. |
Oh, Joy!
Would you mind posting the details the the NG please, Carlos? I'll get the latest compiler and manually add a proxy to resolve this. Expect to see a new Mango release in the next day or two.
- Kris |
|
Back to top |
|
|
Carlos
Joined: 19 Mar 2004 Posts: 396 Location: Canyon, TX
|
Posted: Thu Mar 03, 2005 9:23 am Post subject: |
|
|
kris wrote: | Would you mind posting the details the the NG please, Carlos? I'll get the latest compiler and manually add a proxy to resolve this. Expect to see a new Mango release in the next day or two.
- Kris |
I'm not sure what you mean. Walter said "The dependency stuff got tightened up in 0.114", so maybe this really is a Mango problem that hadn't showed up before. |
|
Back to top |
|
|
|