-
-
Notifications
You must be signed in to change notification settings - Fork 417
Fix issue 7995: D runtime initialization from C fails on OSX in 2.059, worked in 2.058. #228
Conversation
…, worked in 2.058.
@@ -265,6 +295,11 @@ alias void delegate(Throwable) ExceptionHandler; | |||
|
|||
extern (C) bool rt_init(ExceptionHandler dg = null) | |||
{ | |||
static __gshared bool result; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static
or __gshared
? They're mutually exclusive, DMD just doesn't enforce that. What did you intend?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I intended __gshared.
fldcw fpucw; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could use only one function name if you
dispatch the version on the outside.
version (OSX)
void initPlatform() { /*...*/ }
else version (FreeBSD)
void initPlatform() { /*...*/ }
else
void initPlatform() { /* NOOP */ }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, good idea.
What are all these double initialization guards about? |
I thought I would be good idea to prevent the runtime to be initialize/terminated more than once. |
It's not a bad idea, but let's do it in another pull in a thread-safe manner. |
Then you think I should just close this pull request. Open a new one that just fixes issue 7995. After that open an additional pull request that removes the duplicated code, like I've done in this pull request, but in a thread safe manner? |
A couple of follow up questions:
|
I pushed two more commits just to make the pull request complete. |
@@ -296,26 +342,34 @@ void _d_criticalTerm() | |||
} | |||
} | |||
|
|||
extern (C) bool rt_term(ExceptionHandler dg = null) | |||
extern (C) bool rt_term(ExceptionHandler dg = null, bool rethrow = false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing the signature would break all kinds of code.
You could do the same tricks as suggested for rt_init.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking it wouldn't break anything since it's a default argument. It should be source compatible, but it's probably not binary compatible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue is that rt_init and rt_term have been used outside of druntime
for quite a while so we have no way of updating that code.
It should be source compatible, but it's probably not binary compatible.
Yup, adding another parameter will change the argument registers.
By the way dylib_fixes.c is already broken because it declares char rt_init()
, i.e. dg is passed uninitialized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't the default argument kick in for rt_init
when called from dylib_fixes.c?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, default args are not reflected in the ABI.
It's only an issue with a shared runtime library.
We don't yet know exactly how initialization for shared libraries will work. For example dylib_fixes is one approach that would handle this issue automatically. Deferring this means less unused code now and more options later.
Surprisingly yes. Consider libcurl and libfreetype would both use D under the hood and the shared runtime required explicit initialization. |
Is there a point for this pull request staying open? |
First, thanks for your effort, I already wanted to do this for quite some time.
Not sure if I understand you correctly.
If you meant to replace this pull request you could close it |
I'm asking if I should close this pull request and make a new one that only fixes issue 7995 and doesn't do any refactoring. Then initialization guards and the refactoring needs to happen at the same time, at least the way I've done it. I can fix the rt_init/rt_term ABI breakage if you think it's ok to wait with the synchronization of the initialization guards and merge this anyway. |
Looks like this pull request doesn't actually contain the a fix for #7995. I started a branch which contains only the refactorings. The fix for #7995 could then be based on it. |
This pull request should contain a fix. The problem is that
|
OK, I made some tests and it indeed crashes. http://www.opensource.apple.com/source/dyld/dyld-195.6/src/dyld.cpp |
Do you have an example to show? The creator of the issue confirmed it was fixed with my pull request. |
Doesn't the if-statement prevent the callback from being called? |
Yes, your initial pull request solved both Issue 7995 and Issue 8133, so it was very useful in itself (a real blocker otherwise) even if it is not a perfect solution; I posted the code and compilation steps so you can double check before and after. I would also like to see which tests make it crash? |
Ah I've overlooked it
We install callbacks for dyld events but there is no mechanism to uninstall them. |
Would it be possible to use bundles instead of dylibs for libraries that are intended to be unloaded? I couldn't find a definitive answer on the topic but it seems unloading dylibs doesn't do anything since OSX 10.5.7. See also: Here's for example how to unload a bundle:
|
You can simply dlclose what you dlopen'ed. This will unload the shared library from the current process, thus the callbacks become stale pointers. |
I did some tests my self and I noticed this as well. This is some lousy implementation from Apple :( The only difference compared to the implementation we have now is that the callback called when unloading a dylib is not called for the dylib that installed it. In the example above that would mean that |
Oh, I forgot one thing. The problem with the implementation above is that |
I posted about this issue in the d-runtime mailing list. |
Second try.
I also refactored the startup code to remove duplicated code.
This will hopefully reduce this kind of bugs in the future.
I had to remove the call to "runModuleUnitTests" in "rt_init". Meaning the unit tests won't be run if the runtime is just initialized via "rt_init". This basically only happens if you start the D runtime from a C application. The unit tests are still run, just as before, for all D applications with a D main function. Don't know if this is a problem or not.