C++ static destructor guaranteed to be called?

P

Paul J. Lucas

If I'm writing some native code using the C++ JNI API and my
C++ code has a static object with a destructor, is it
guaranteed that said destructor will be called before the
process terminates (as it would be if this were plain C++)?

I would think the answer would be "yes" since this is outside
the purview of the JVM.

- Paul
 
J

Joan

"Paul J. Lucas" <[email protected]>
wrote in message
If I'm writing some native code using the C++ JNI API and my
C++ code has a static object with a destructor, is it
guaranteed that said destructor will be called before the
process terminates (as it would be if this were plain C++)?

I would think the answer would be "yes" since this is outside
the purview of the JVM.

- Paul

Why don't you write a little test program. It is not a waste of
time for you cuz you have to learn jni anyway.
 
P

Paul J. Lucas

Joan said:
"Paul J. Lucas" <[email protected]>
wrote in message


Why don't you write a little test program. It is not a waste of
time for you cuz you have to learn jni anyway.

Just because I write a test program and it does what I want on
my platform doesn't mean it's guaranteed on all platforms.
Hence my question.

I already know JNI, thanks.

- Paul
 
R

Roedy Green

If I'm writing some native code using the C++ JNI API and my
C++ code has a static object with a destructor, is it
guaranteed that said destructor will be called before the
process terminates (as it would be if this were plain C++)?

I would think the answer would be "yes" since this is outside
the purview of the JVM.

I would guess no. In an ordinary C++ app, at some point you call the
C++ equivalent of exit(). At that point C++ can do whatever shutdown
processing it wants.

When a Java app shuts down, exit() has no knowledge of the C++
runtime. There in no hook into the C++ shutdown code. For all exit
knows, you wrote all your JNI in pure assembler and there is no C++
runtime. It does not even know that any JNI code has been run.
 
J

John Perks and Sarah Mount

message > I would guess no. In an ordinary C++ app, at some point you
call the
C++ equivalent of exit(). At that point C++ can do whatever shutdown
processing it wants.

When a Java app shuts down, exit() has no knowledge of the C++
runtime. There in no hook into the C++ shutdown code. For all exit
knows, you wrote all your JNI in pure assembler and there is no C++
runtime. It does not even know that any JNI code has been run.

Assuming by statics the OP means static variables in functions.

I believe things may be slightly better than that. I think most OSes
have a standard way in which a library (.dll/.so/whatever) can execute
some of its own code on first being loaded (when it would run ctors for
any global objects), and then cleanup prior to being unloaded (dtor'ing
the globals and any statics that have been ctor'd).

I've just tested this (on Win98; your milage may vary) by putting a
global object with ctor and dtor in a DLL that is picked up at run-time
by LoadLibrary/GetProcAddress (i.e. the client that "links" to it does
nothing to acknowledge the C++ runtime) and the the ctor and dtor were
both called. I'd imagine similar would hold in Unix, and further that
the mechanism described is similar to how System.loadLibrary causes
native methods to be bound.

I believe exit() quits "gracefully", unloading libraries as it goes,
whereas abort() just destroys the running process with no cleanup.

Hope this helps

John.
 
M

Mike Schilling

Paul J. Lucas said:
If I'm writing some native code using the C++ JNI API and my
C++ code has a static object with a destructor, is it
guaranteed that said destructor will be called before the
process terminates (as it would be if this were plain C++)?

I would think the answer would be "yes" since this is outside
the purview of the JVM.

I would expect this to be platform/compiler-specific. A pure C++
implementation can guarantee this, but whether that guarantee holds with a
non-C++ main and non-C++ exit function will depend upon mechanism. If it
were me, I'd write a test program, observe its behavior, in particular
whether the C++ runtime gets invoked on exit, and proceed from there.
 
T

Thomas Fritsch

Paul J. Lucas said:
Just because I write a test program and it does what I want on
my platform doesn't mean it's guaranteed on all platforms.
Hence my question.
Imagine you would write the test program and it would *not* do what you want
on your platform. Or it would sometimes do what you want, and sometimes not.
If so, that would disprove your preconception. Isn't this enough motivation
for a test?
 
P

Paul J. Lucas

Thomas Fritsch said:
"Paul J. Lucas" wrote:
Imagine you would write the test program and it would *not* do what you want
on your platform.

Then I have my answer.
Or it would sometimes do what you want, and sometimes not.

Again, I have my answer.
Isn't this enough motivation for a test?

How do you know I didn't already write a test for my platform?
Read my original post carefully. I never said one way or the
other.

- Paul
 
T

Thomas Fritsch

Paul J. Lucas said:
Then I have my answer.


Again, I have my answer.


How do you know I didn't already write a test for my platform?
Read my original post carefully. I never said one way or the
other.

Paul,
I actually read your original post carefully and noticed you didn't say it
one way or the other. I noticed you were almost but not absolutely sure,
that the test would always say "yes" (the C++ destructor is called upon
exit). But I interpreted your posts in a way, that your assumption was
mainly based on your JVM knowledge instead of on test-results. So I assumed
(may be wrongly) you didn't test it.
As you said correctly: If the test says "no" one single time, one knows it
doesn't say "yes" every time. This is, what makes the test so valuable, and
why I recommended it.
My answer was not meant as an offence. Sorry, if it could be misunderstood
as such.
 
E

E.J. Pitt

Paul said:
If I'm writing some native code using the C++ JNI API and my
C++ code has a static object with a destructor, is it
guaranteed that said destructor will be called before the
process terminates (as it would be if this were plain C++)?

I would think the answer would be "yes" since this is outside
the purview of the JVM.

This behaviour is mandated by the C++ standard. The only platform I am
aware of where it doesn't happen according to specification is Novell
Netware when you have a C++ NLM that terminates abnormally, and that
information is some years old.
 
M

Mark Thornton

E.J. Pitt said:
This behaviour is mandated by the C++ standard. The only platform I am
aware of where it doesn't happen according to specification is Novell
Netware when you have a C++ NLM that terminates abnormally, and that
information is some years old.

Windows processes which are terminated by TerminateProcess are killed
instantly without any chance to run any further code. It doesn't matter
what language the process is written in.

Mark Thornton
 
R

Roedy Green

If I'm writing some native code using the C++ JNI API and my
C++ code has a static object with a destructor, is it
guaranteed that said destructor will be called before the
process terminates (as it would be if this were plain C++)?

I would think the answer would be "yes" since this is outside
the purview of the JVM.

That presumes C++'s exit is called to trigger shutdown sequences. If
you exited Java that way yes, but then you would lose the Java
shutdown sequences.
 
E

E.J. Pitt

Roedy said:
I would guess no. In an ordinary C++ app, at some point you call the
C++ equivalent of exit(). At that point C++ can do whatever shutdown
processing it wants.

When a Java app shuts down, exit() has no knowledge of the C++
runtime. There in no hook into the C++ shutdown code. For all exit
knows, you wrote all your JNI in pure assembler and there is no C++
runtime. It does not even know that any JNI code has been run.

Any C program which contains C++ gets a C++ version of main() and
exit(), one way or the other. This is organized by the compiler and the
linker between them.
 
C

Chris Uppal

E.J. Pitt said:
Any C program which contains C++ gets a C++ version of main() and
exit(), one way or the other. This is organized by the compiler and the
linker between them.

"the" compiler ? The jvm is packaged as a DLL (or equivalent). There is no
guarantee what compiler was used to generate it, nor indeed what language it
was written in. If that DLL invokes "exit()" then it's difficult to see how
/any/ statement can be made about what that does -- especially in respect to
the expectations of the invoking program.

That -- presumably -- is why JNI has a means for the invoking program to set an
exit hook which will be called by the JVM if/when java code uses System.exit()
(or equivalent). (I'd clean forgotten about that hook, btw, which is why I
didn't mention that it would solve the OP's problem earlier in this thread :-(

-- chris
 
S

Stefan Ram

E.J. Pitt said:
Any C program which contains C++ gets a C++ version of main() and
exit(), one way or the other.

What is a "C programm which contains C++"?
 
M

Mike Schilling

E.J. Pitt said:
Any C program which contains C++ gets a C++ version of main() and exit(),
one way or the other. This is organized by the compiler and the linker
between them.

I'll just observe here that the C++ standard defines the 'extern "C" '
construct for communicating between C and C++, and makes no guarantees of
any kind about what it does, since cross-language behavior is ouitside its
purview.
 
C

Chris Head

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Greetings,
I believe the answer to this question is "yes", at least under Win32. In
Win32, your JNI code is contained in a DLL. In a Win32 DLL, there is a
magic entry point which is automatically invoked by the operating system
immediately after the DLL loads and immediately before it unloads
(INCLUDING if the process is terminated with ExitProcess(), as it would
be even if the main program was written in assembly - but NOT if by
TerminateProcess(), which hardly anyone does anyway). The Visual C++
runtime provides its own definition of this function which initializes
and destroys global (and presumably static) objects. I have tested this
functionality personally: when a DLL containing a global object is
loaded with LoadLibrary(), the global object's constructor runs. When
FreeLibrary() unloads the library, the destructor runs. It doesn't
matter what language or what program loads and unloads the DLL: the
invocation of the load/unload callback (often referred to as DllMain)
occurs as a function of the operating system, and the CRT associated
with the DLL provides the entry point which initializes and destroys
globals.

I think Linux also provides a similar pair of magic functions in .SO files.

Chris
If I'm writing some native code using the C++ JNI API and my
C++ code has a static object with a destructor, is it
guaranteed that said destructor will be called before the
process terminates (as it would be if this were plain C++)?

I would think the answer would be "yes" since this is outside
the purview of the JVM.

- Paul

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (MingW32)
Comment: GnuPT 2.7.2
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFDTfMi6ZGQ8LKA8nwRAgrjAKCVhV3hMrYq8OCT8dc2xaNW4iEVAQCeIRm5
9fmpBjG+hHfs5a02ToziKpQ=
=n6s7
-----END PGP SIGNATURE-----
 
R

Roedy Green

Any C program which contains C++ gets a C++ version of main() and
exit(), one way or the other. This is organized by the compiler and the
linker between them.

That is half the battle. The other half is to make sure that code gets
called when Java shuts down.
 
E

E.J. Pitt

Chris said:
E.J. Pitt wrote:




"the" compiler ? The jvm is packaged as a DLL (or equivalent). There is no
guarantee what compiler was used to generate it, nor indeed what language it
was written in. If that DLL invokes "exit()" then it's difficult to see how
/any/ statement can be made about what that does -- especially in respect to
the expectations of the invoking program.

That -- presumably -- is why JNI has a means for the invoking program to set an
exit hook which will be called by the JVM if/when java code uses System.exit()
(or equivalent). (I'd clean forgotten about that hook, btw, which is why I
didn't mention that it would solve the OP's problem earlier in this thread :-(

-- chris

What I meant was that in a program containing a mixture of C and C++,
the C++ compiler put hooks into the object code such that the C++
runtime library is linked in which in turn will lead to destructors of
static objects being called on exit(). However thinking about it some
more, being about 12 years since I have done it, the requirement was
that main() be compiled by C++. I don't believe that happens in Java JNI
so basically I was probably wrong.
 
R

Roedy Green

In a Win32 DLL, there is a
magic entry point which is automatically invoked by the operating system
immediately after the DLL loads and immediately before it unloads

But DLLs can hang around for a long time after the app closes right?
So how does that work?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top