www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Module destructors not called when unhandled exception terminates program

reply James Dunne <jdunne4 bradley.edu> writes:
-------------------- mytest.d -------------------
module mytest;

import  testmodule;

static this() {
printf("mytest: static this()\n");
}

static ~this() {
printf("mytest: static ~this()\n");
}

int main(char[][] args) {
throw new Exception("some error here");
return 0;
}
----------------- testmodule.d ------------------
module  testmodule;

static this() {
printf("testmodule: static this()\n");
}

static ~this() {
printf("testmodule: static ~this()\n");
printf("hey, what if i want to store stuff back to the database on program
termination?\n");
}
-------------------------------------------------

This program results in the following output:

testmodule: static this()
mytest: static this()
Error: some error here

What happened to my static ~this()'s?  On checking Phobos' dmain2.d, I see the
following code:

#    try
#    {
#	_moduleCtor();
#	_moduleUnitTests();
#
# ...
#
#	result = main(args);
#    }
#    catch (Object o)
#    {
#	printf("Error: ");
#	o.print();
#	exit(EXIT_FAILURE);
#    }
#
#    _moduleDtor();
#    gc_term();
#    version (linux)
#    {
#	free(am);
#	_STD_critical_term();
#	_STD_monitor_staticdtor();
#    }

Now... on catching an exception, exit(EXIT_FAILURE) is called, which bypasses
the _moduleDtor() call I'm wanting to happen, as well as other equally important
calls: gc_term(), _STD_critical_term(), and _STD_monitor_staticdtor().

I must inquire - is this just an overlooked, untested bug?  Or this by design?
What happens if you throw an object in a module destructor?

On a quick documentation glance, I read the following about static destructors:

"A static destructor gets called on program termination, but only if the static
constructor completed successfully. Static destructors have empty parameter
lists. Static destructors get called in the reverse order that the static
constructors were called in."

This says nothing about when exceptions are thrown.  I'd suggest some sort of
clarification in the documentation about this issue.  Is the assumption that the
program is not really "terminated" per se when an exception is thrown?

A user-available D function for guaranteed-call-on-program-termination would be
a nice function to have indeed!  We don't seem to currently have any of those
called by Phobos.

Thanks for your consideration if you read this, Walter.

Regards,
James Dunne
Apr 14 2005
next sibling parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"James Dunne" <jdunne4 bradley.edu> wrote in message 
news:d3lfvf$jom$1 digitaldaemon.com...
 This says nothing about when exceptions are thrown.  I'd suggest some sort 
 of
 clarification in the documentation about this issue.  Is the assumption 
 that the
 program is not really "terminated" per se when an exception is thrown?

This could very easily be solved by putting that after-code in a finally bock. I'm surprised that it isn't.
Apr 14 2005
prev sibling next sibling parent "Carlos Santander B." <csantander619 gmail.com> writes:
James Dunne wrote:
 
 [snip]
 
 What happened to my static ~this()'s?  On checking Phobos' dmain2.d, I see the
 following code:
 
 #    try
 #    {
 #	_moduleCtor();
 #	_moduleUnitTests();
 #
 # ...
 #
 #	result = main(args);
 #    }
 #    catch (Object o)
 #    {
 #	printf("Error: ");
 #	o.print();
 #	exit(EXIT_FAILURE);
 #    }
 #
 #    _moduleDtor();
 #    gc_term();
 #    version (linux)
 #    {
 #	free(am);
 #	_STD_critical_term();
 #	_STD_monitor_staticdtor();
 #    }
 
 [snip]
 
 Regards,
 James Dunne

That seems like a bug to me. -- Carlos Santander Bernal JP2, you'll always live in our minds
Apr 14 2005
prev sibling parent "Walter" <newshound digitalmars.com> writes:
"James Dunne" <jdunne4 bradley.edu> wrote in message
news:d3lfvf$jom$1 digitaldaemon.com...
 Now... on catching an exception, exit(EXIT_FAILURE) is called, which

 the _moduleDtor() call I'm wanting to happen, as well as other equally

 calls: gc_term(), _STD_critical_term(), and _STD_monitor_staticdtor().

 I must inquire - is this just an overlooked, untested bug?  Or this by

 What happens if you throw an object in a module destructor?

It's by design. Usually, uncaught exceptions are program bugs. Having more program code be executed can both make the bug harder to find, and can cause more problems than it solves. There isn't much need to clean up system resources, because modern operating systems will clean up resources for you when your process exits. You can achieve the behavior you want, however, simply by adding try-catch to main(): void main() { try { ... my app code ... } catch (Object o) { printf("Error: "); o.print(); } }
Apr 15 2005