FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Throwing Exceptions from a Module Constructor (Linux)

 
Post new topic   Reply to topic     Forum Index -> Derelict
View previous topic :: View next topic  
Author Message
JJR



Joined: 22 Feb 2004
Posts: 1104

PostPosted: Mon Oct 18, 2004 10:03 am    Post subject: Throwing Exceptions from a Module Constructor (Linux) Reply with quote

Was this issue discussed before? I was surprised to read about it in the Derelict project readme file. It seems that this is the one thing keeping derelict from automatic shared library loading on startup.
Back to top
View user's profile Send private message
aldacron



Joined: 05 May 2004
Posts: 1322
Location: Seoul, South Korea

PostPosted: Mon Oct 18, 2004 7:42 pm    Post subject: Reply with quote

It hasn't been discussed in the forums, no. But yes, it is the one reason why I implemented the *Load functions. The thing is, on Linux (and Windows console apps), if a module constructor throws an ecxception there is currently no way (that I am aware of) to catch it. That means the default exception handling mechanism kicks in, defeating the purpose of doing the explicit loading (the ability to handle missing/corrupt shared libs in an app-specific manner).

If there is a solution for this I would love to hear it. I asked on the NG some time ago, but as I recall there wasn't much discussion.
Back to top
View user's profile Send private message Send e-mail
JJR



Joined: 22 Feb 2004
Posts: 1104

PostPosted: Tue Oct 19, 2004 4:57 pm    Post subject: Reply with quote

Well, this looks to be a tricky problem. I decided to take a peek at the phobos source to see what's going on. It looks like dmain2.d may indicate why (although, I'm not really sure how it all works). It looks like this:

Code:
version (linux)
    {
   _STI_monitor_staticctor();
   _STI_critical_init();
   gc_init();
   am = cast(char[] *) malloc(argc * (char[]).sizeof);
   // BUG: alloca() conflicts with try-catch-finally stack unwinding
   //am = (char[] *) alloca(argc * (char[]).sizeof);
    }


Notice the BUG reference about "alloca" (allocate from stack frame) and try-catch-finally stack unwinding. Linux comments out alloca and uses malloc instead to fix this. On the other hand, the windows version still uses "alloca" which might explain why the bug still exists on windows console apps as well:

Code:
version (Win32)
    {
   gc_init();
   _minit();
   am = cast(char[] *) alloca(argc * (char[]).sizeof);
    }


But you said WinMain still works (probably because we have to manually set these things up)...

The next part of dmain2.d actually calls the programmer's d main from within a try/catch block. But first, the _moduleCtor is called within this same block:

Code:
try
    {
   _moduleCtor();       // <-- module constructor called
   _moduleUnitTests();

   for (i = 0; i < argc; i++)
   {
       int len = strlen(argv[i]);
       am[i] = argv[i][0 .. len];
   }

   args = am[0 .. argc];

   result = main(args);   // <-- d main() called
    }
    catch (Object o)
    {
   printf("Error: ");
   o.print();
   result = EXIT_FAILURE;
    }


Why does the alloca() call cause so much grief with try/catch? How does a try/catch within the module constructor inter-operate with the higher level try/catch (above)?

Later,

John
Back to top
View user's profile Send private message
aldacron



Joined: 05 May 2004
Posts: 1322
Location: Seoul, South Korea

PostPosted: Tue Oct 19, 2004 10:27 pm    Post subject: Reply with quote

Any problems with alloca have no bearing on this, as I see it. The problem is that _moduleCtor is called from within that function. Any exceptions thrown are passed to the catch block there, with no way to be handled by the application itself. With the WinMain function, we have to call _moduleCtor manually and are able to deal with any exceptions thrown in our own way.

A solution I proposed on the NG a while back was to allow the app to implement an optional module constructor exception handler. Then the catch block would call out to that if it has been implemented, and would resort to the default behavior if not. I never saw a response. It would be a really useful feature to have though. I find the default exception handler rather lacking, particularly in end-user terms.
Back to top
View user's profile Send private message Send e-mail
JJR



Joined: 22 Feb 2004
Posts: 1104

PostPosted: Tue Nov 23, 2004 8:14 am    Post subject: Reply with quote

Returning to this topic:

If exception handling within a module constructor currently doesn't work, why is this a problem? I mean why can't we just do the exception handling the old fashioned way here: check for dll, error code if missing, display windows dialogue of our choice, and exit program nicely.

In this case, isn't the D exception system just a fancier, cleaner way of handling things ... something that would be nice, but isn't absolutely necessary?

Just curious...

Later,

John
Back to top
View user's profile Send private message
aldacron



Joined: 05 May 2004
Posts: 1322
Location: Seoul, South Korea

PostPosted: Tue Nov 23, 2004 10:03 am    Post subject: Reply with quote

JJR wrote:
Returning to this topic:

If exception handling within a module constructor currently doesn't work, why is this a problem? I mean why can't we just do the exception handling the old fashioned way here: check for dll, error code if missing, display windows dialogue of our choice, and exit program nicely.

In this case, isn't the D exception system just a fancier, cleaner way of handling things ... something that would be nice, but isn't absolutely necessary?



It's not just exceptions - there is absolutely no way to for an application with a main function to effectively handle errors in the module ctors of third party libraries. You can do whatever you like in your own module ctors, but when linking to the Derelict libs, how are you going to know if a DLL failed to load in a module ctor? The only way to do so currently in a main function would be for Derelict to implement some sort of isLoaded variable/function for each lib. But that means the app must call isLoaded for each Derelict library used - something more error prone. It would be easy to forget and release production code that breaks in the wild on a few systems. So for now, requiring manual loading of the libraries with the Derelict*Load functions is a more robust solution.

If it were possible to catch exceptions thrown from module ctors, then it doesn't matter if the programmer forgets to, and there is no need to load things manually.
Back to top
View user's profile Send private message Send e-mail
JJR



Joined: 22 Feb 2004
Posts: 1104

PostPosted: Tue Nov 23, 2004 11:36 am    Post subject: Reply with quote

I see what your saying. I don't think I was thinking deep enough about the problem. Embarassed

When you think of it, a manual loader isn't so bad. It can be included as part of a packages initialization process easily enough and checked there. Trully seemless operation may be preferred, but it's not critical.
Back to top
View user's profile Send private message
sean



Joined: 24 Jun 2004
Posts: 609
Location: Bay Area, CA

PostPosted: Tue Nov 23, 2004 1:14 pm    Post subject: Reply with quote

I've been mucking about with low-level stuff in Phobos and one of the things I've been playing with are hooks for various errors. But I'm not sure it would help in this case because the error might occur before your custom handler is even loaded. But I think the DLL loader should handle module initialization and probably propogate exceptions back into the application.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> Derelict All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group