View previous topic :: View next topic |
Author |
Message |
Carlos
Joined: 19 Mar 2004 Posts: 396 Location: Canyon, TX
|
Posted: Fri Feb 11, 2005 9:52 pm Post subject: problem with static ctors |
|
|
I'm not sure under what circumstances exactly, but on Windows, mango.servlet.ServletContext.static this() is executed before mango.log.Manager.Manager.static this(), which has the effect that mango.log.Manager.Manager.getLogger() is called, but mango.log.Manager.Manager.base is null, which produces an access violation.
I don't know what exactly triggers this, but I think it could be when using a WinMain that manually calls the module ctors, because the exact same code (obviously versioning out WinMain for a main) works on linux. |
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Fri Feb 11, 2005 10:06 pm Post subject: Re: problem with static ctors |
|
|
Carlos wrote: | I'm not sure under what circumstances exactly, but on Windows, mango.servlet.ServletContext.static this() is executed before mango.log.Manager.Manager.static this(), which has the effect that mango.log.Manager.Manager.getLogger() is called, but mango.log.Manager.Manager.base is null, which produces an access violation.
I don't know what exactly triggers this, but I think it could be when using a WinMain that manually calls the module ctors, because the exact same code (obviously versioning out WinMain for a main) works on linux. |
This problem was supposedly fixed in the compiler around v0.98 ... it had been a frustrating issue for a long time before that (all decorated imports were ignored: package, private, etc). Would you also post on the D buglist please, Carlos? I believe you're the first to try WinMain with Mango ...
I should note that the traditional main() version operates correctly under Windows also, so it does look like the WinMain is somehow related. |
|
Back to top |
|
|
Carlos
Joined: 19 Mar 2004 Posts: 396 Location: Canyon, TX
|
Posted: Fri Feb 11, 2005 10:18 pm Post subject: |
|
|
The problem would be to reduce it: I'm using mango and minwin and 25+ files, and (as you know) all problems disappear when doing the trivial cases.
Maybe asking Walter if the static initialization is done differently with and without WinMain. |
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Fri Feb 11, 2005 10:39 pm Post subject: |
|
|
Carlos wrote: | The problem would be to reduce it: I'm using mango and minwin and 25+ files, and (as you know) all problems disappear when doing the trivial cases.
Maybe asking Walter if the static initialization is done differently with and without WinMain. |
Sounds good. I used to have a little code-snippet that printed out the static-constructor tree ... I'll see if I can find it again ... |
|
Back to top |
|
|
Carlos
Joined: 19 Mar 2004 Posts: 396 Location: Canyon, TX
|
Posted: Sat Feb 12, 2005 8:45 am Post subject: |
|
|
Done. The offending line seems to be _minit(), but I have no idea what it does. However, it's not present on linux, and the problem seems to have disappeared when commenting it on Windows. But I still need to test it more. |
|
Back to top |
|
|
Carlos
Joined: 19 Mar 2004 Posts: 396 Location: Canyon, TX
|
Posted: Sat Feb 12, 2005 9:24 am Post subject: |
|
|
Carlos wrote: | Done. The offending line seems to be _minit(), but I have no idea what it does. However, it's not present on linux, and the problem seems to have disappeared when commenting it on Windows. But I still need to test it more. |
"Seems" was correct: now the problem isn't before the application starts, but later when getLogger is called, causing the same AV as before.
I'm going to check on linux to see exactly what's happening there. |
|
Back to top |
|
|
Carlos
Joined: 19 Mar 2004 Posts: 396 Location: Canyon, TX
|
Posted: Sat Feb 12, 2005 9:57 am Post subject: |
|
|
Confirmed: the problem is on Windows, because on linux everything goes as it's supposed to. |
|
Back to top |
|
|
teqdruid
Joined: 11 May 2004 Posts: 390 Location: UMD
|
Posted: Sat Feb 12, 2005 12:56 pm Post subject: |
|
|
Actually, I've been having the same problem on Linux. Again, not sure what's causing it. |
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Sat Feb 12, 2005 2:16 pm Post subject: |
|
|
Here's a link to the old thread about this: http://dsource.org/forums/viewtopic.php?t=334
Also, here's some code that Pragma posted to list the imports and their dependency order:
Code: | import std.stdio;
import std.moduleinit;
void main(){
writefln("\n--MODULE INFO--\n");
foreach(ModuleInfo info; _moduleinfo_array){
writefln("?s", info.name);
foreach(ModuleInfo imported; info.importedModules){
writefln("\timport ?s",imported.name);
}
}
} |
Run this for a console-version of your application, and pipe the output to a file. Then do the same from your WinMain() version, and compare the output of the two. I imagine the lists will be quite different.
The linux version should also be identical to the windows console version. |
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Sat Feb 12, 2005 2:29 pm Post subject: |
|
|
Here's the output from a win32 console servlets. This is the list of modules which have some kind of static constructor or static destructor (either at the module or class level).
This list is traversed recursively by the startup code, and the module-constructor is called for each. A flag is set during the process, such that a module is initialized once only.
The list itself is build by the compiler.
Code: | --MODULE INFO--
servlets
import string
import thread
import Uri
import Socket
import System
import Admin
import Configurator
import ServletContext
HttpHeaders
import Token
import Tokenizer
import HttpTokens
System
import thread
Uri
import ctype
import Buffer
Socket
import System
ServletContext
import FileStyle
Admin
import Uri
import Manager
import ServletContext
Configurator
import Layout
import ConsoleAppender
AbstractWriter
Manager
Tokenizer
import ctype
import Token
import regexp
Buffer
HttpCookies
import ctype
import Token
import Buffer
import Tokenizer
import HttpHeaders
HttpParams
import Token
import Tokenizer
import HttpTokens
HttpTokens
import Token
import Buffer
import Tokenizer
Token
import ctype
Utf8
FileStyle
import ConduitStyle
HttpResponse
import Buffer
import HttpParams
import HttpCookies
import HttpHeaders
Layout
import Event
ConsoleAppender
import Stdout
ConduitStyle
HttpRequest
import Uri
import Token
import Buffer
import Socket
import Tokenizer
import HttpParams
import HttpCookies
import HttpHeaders
Event
Stdout
import ConduitStyle
thread
string
import utf
import format
import ctype
adi
import string
ctype
regexp
import string
import ctype
import outbuffer
date
import dateparse
switch
import string
format
import utf
import string
utf
outbuffer
import string
dateparse
import string
import date
gcbits
import string |
Edit: this is the full list of modules (for servlets.exe) with either static dtors or static ctors. The subset of modules actually constructed, and the order in which that is performed, is shown on page 2.
Last edited by kris on Sat Feb 12, 2005 11:41 pm; edited 1 time in total |
|
Back to top |
|
|
Carlos
Joined: 19 Mar 2004 Posts: 396 Location: Canyon, TX
|
Posted: Sat Feb 12, 2005 9:24 pm Post subject: |
|
|
Apparently, WinMain is not guilty: replacing it with a regular main also produces an AV before reaching main.
I'd say DMD behaves differently on Windows than it does on linux, and I think this is the proof: following your suggestion, this is what I had:
Code: |
--MODULE INFO (Windows)--
value
import math
import date
import string
protoerror
import value
lexer
import string
import utf
import outbuffer
import ctype
window
import string
dialog
import window
import string
layout
System
import thread
Socket
import System
ServletContext
import FileStyle
Admin
import Uri
import Manager
import ServletContext
Buffer
RollCall
Cluster
import Random
import System
import Buffer
import Socket
import Client
import RollCall
HttpResponse
import Buffer
import HttpParams
import HttpCookies
import HttpHeaders
FileStyle
import ConduitStyle
Manager
Uri
import ctype
import Buffer
Random
AbstractWriter
Client
import System
import Message
HttpRequest
import Uri
import Token
import Buffer
import Socket
import Tokenizer
import HttpParams
import HttpCookies
import HttpHeaders
HttpHeaders
import Token
import Tokenizer
import HttpTokens
HttpCookies
import ctype
import Token
import Buffer
import Tokenizer
import HttpHeaders
HttpParams
import Token
import Tokenizer
import HttpTokens
ConduitStyle
CacheInvalidator
import Client
Message
Tokenizer
import ctype
import Token
import regexp
Token
import ctype
HttpTokens
import Token
import Buffer
import Tokenizer
Utf8
Event
path
import string
file
import path
import string
import utf
string
import utf
import format
import ctype
perf
thread
adi
import string
date
import dateparse
math
utf
format
import utf
import string
qsort
import string
uri
import ctype
import utf
regexp
import string
import ctype
import outbuffer
random
ctype
switch
import string
outbuffer
import string
dateparse
import string
import date
gcbits
import string
--MODULE INFO (linux)--
value
import math
import date
import string
protoerror
import value
lexer
import string
import utf
import outbuffer
import ctype
paint
layout
Admin
import Uri
import Manager
import ServletContext
Manager
RollCall
ServletContext
import FileStyle
Socket
import System
import linux
System
import thread
import linux
Uri
import ctype
import Buffer
AbstractWriter
Buffer
Cluster
import Random
import System
import Buffer
import Socket
import Client
import RollCall
ConduitStyle
FileStyle
import ConduitStyle
HttpHeaders
import Token
import Tokenizer
import HttpTokens
HttpRequest
import Uri
import Token
import Buffer
import Socket
import Tokenizer
import HttpParams
import HttpCookies
import HttpHeaders
HttpResponse
import Buffer
import HttpParams
import HttpCookies
import HttpHeaders
HttpTokens
import Token
import Buffer
import Tokenizer
Random
import linux
Tokenizer
import ctype
import Token
import regexp
Token
import ctype
Utf8
CacheInvalidator
import Client
Client
import System
import Message
Event
import linux
HttpCookies
import ctype
import Token
import Buffer
import Tokenizer
import HttpHeaders
HttpParams
import Token
import Tokenizer
import HttpTokens
Message
switch
import string
adi
import string
path
import string
string
import utf
import format
import ctype
math
outbuffer
import string
ctype
regexp
import string
import ctype
import outbuffer
random
import linux
linux
qsort
import string
thread
import linux
utf
uri
import ctype
import utf
format
import utf
import string
perf
date
import dateparse
import linux
dateparse
import string
import date
gcbits
import string
|
Removing the non-Mango stuff, IMO, this remains:
Code: |
WINDOWS linux
System Admin
Socket Manager
ServletContext RollCall
Admin ServletContext
Buffer Socket
RollCall System
Cluster Uri
HttpResponse AbstractWriter
FileStyle Buffer
Manager Cluster
Uri ConduitStyle
Random FileStyle
AbstractWriter HttpHeaders
Client HttpRequest
HttpRequest HttpResponse
HttpHeaders HttpTokens
HttpCookies Random
HttpParams Tokenizer
ConduitStyle Token
CacheInvalidator Utf8
Message CacheInvalidator
Tokenizer Client
Token Event
HttpTokens HttpCookies
Utf8 HttpParams
Event Message
|
And the key in this particular case is that on linux, ServletContext is called after Manager, while it doesn't hold true on Windows. |
|
Back to top |
|
|
JJR
Joined: 22 Feb 2004 Posts: 1104
|
Posted: Sat Feb 12, 2005 9:34 pm Post subject: |
|
|
Really, I would think this would be a priority for Walter to deal with. Having different load orders of static ctors on different platforms seems like a bad idea.
A question: Do both static module ctors and static class ctors show up in the list output? Both are loaded prior to main, I believe. Which of these two ctor types are called first?
- John R. |
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Sat Feb 12, 2005 9:43 pm Post subject: |
|
|
JJR wrote: | Really, I would think this would be a priority for Walter to deal with. Having different load orders of static ctors on different platforms seems like a bad idea.
A question: Do both static module ctors and static class ctors show up in the list output? Both are loaded prior to main, I believe. Which of these two ctor types are called first?
- John R. |
The class ctors are called from the module ctors. If there are class ctors but no module ctor, the compiler will *add* a module ctor. |
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Sat Feb 12, 2005 9:58 pm Post subject: |
|
|
Carlos wrote: | Apparently, WinMain is not guilty: replacing it with a regular main also produces an AV before reaching main |
Agreed. The windows tree you posted is clearly invalid, whilst the linux one looks correct.
But then, teqDruid says he's having a similar problem on linux ... it may well be fragile on both platforms. |
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Sat Feb 12, 2005 10:17 pm Post subject: |
|
|
Carlos ... you could comment out line 201 in ServletContext, and that should get you going until Walter can resolve this issue.
- Kris |
|
Back to top |
|
|
|