Win a copy of OCP Oracle Certified Professional Java SE 11 Developer Practice Tests this week in the OCP forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Jeanne Boyarsky
  • Ron McLeod
  • Tim Cooke
Sheriffs:
  • Devaka Cooray
  • paul wheaton
  • Mark Herschberg
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Stephan van Hulst
  • Frits Walraven
  • Jj Roberts
Bartenders:
  • Carey Brown
  • salvin francis
  • Piet Souris

shared library destructor doesn't get called

 
Ranch Hand
Posts: 51
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So, after I managed to get my little C/++ project going (at least I started working on it), about writing a new extension for the game ArmA3, I looked up shared library constructors and destructors.
So far, my few lines work as intented, except the destructor. As far as I figured out it seems even executing the proper shutdown command via the console just kills it the same as pressing ctrl-c. I guess that's an issue with the implementation of the server binary - but the result is that the destructor of my lib doesn't get called. Although it's only supposed to correctly tear down the socket connection (the other end is some Java which will just throw an IOException from the blocking read() call) it's also supposed to send some final commands to let the Java backend just right before the connection terminates (at least that's my current plan).
Is there any other way to have something like the destructor called even if the main binary just crashes (for the lack of a better term - maybe "the application fails to correctly shutdown" fits better)?
I also tried to look up if there's a way using the in-game scripting engine - but that also just gets killed without any termination hooks like a shutdownhook in Java.
 
Ranch Hand
Posts: 158
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You need to catch Ctrl+C using a signal handler, and then do the cleanup there, which should include shared library shutdown or any other cleanup recommended by the shared library developers.
 
Saloon Keeper
Posts: 23252
158
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The default action on Ctrl-C is that the OS will terminate the process immediately, close all files and network connections and de-allocate memory as a unit (instead of de-constructing all the elements in the program memory space). As Salil says, you can set up a handler to allow application logic to deal with signals more gracefully.

In the case of spontaneous abnormal termination (like a SEGFAULT), it could be trickier, since the internal application state could have very likely already been corrupted and thus be the cause of the fault, and it's therefore going to be harder to clean up.

One thing that will help, of course, is to ensure that no memory allocation request happens without checking to see if the allocation succeeded and other such preventative methods.
 
Matthew Bendford
Ranch Hand
Posts: 51
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, the issue is that I'm only developing an extension. I'm not a dev of the binary itself.
I also asked on the devs forums if I do something wrong and what's maybe the "preferred" or "correct" way of shutting down a running server instance, but even using the shutdown command, which the doc says is to shutdown the server remotely as logged in admin, ends up in the binary just seem to "crash" - as no matter how I shut it down it always results in "failed to write coredump". I guess it's just very poor design and implementation they chose.
 
Marshal
Posts: 3398
493
Android Eclipse IDE TypeScript Redhat MicroProfile Quarkus Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Is there anything in the extension API which lets you register a callback to receive system events, like one that might give you an indication that things are being shut down?
 
Matthew Bendford
Ranch Hand
Posts: 51
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Unfortunately it doesn't look like it.
The API defines 4 functions:

This is my current code:

When the extension is first loaded by the engine the constructor gets called first printing the "setup" line. Next, although the doc says otherwise, the callback pointer is set, and finally the RVExtensionVersion is called as the final initialization of the extension.
After first init only the two functions RVExtension and RVExtensionArgs are called, depending on if one calls the extension by just one single string or with an array of strings.
The callback pointer only allows to execute script code in the scripting engine as an a-sync external "event", as it require a listener to be registered to the specific event in the scripting language as part of the init script.
At least to my knowledge there's no way to hook any further into the actual engine or its shutdown procedure.
It sure would be possible to try some "hacks" by abusing the callback pointer - but I'm so not into that low-level C stuff and try to stay as far away as I can.
My goal in the end is just a small "interface" which takes the strings sent by the game engine and send them out over a socket to a Java backend - and vice-versa re-inject the replies comming from said backend into the scripting language. So, it's totally fine if it's a mess of copy/paste from several sources.
I just tried what I found on the net so far and noticed, that the destructor never prints this "teardown" line. As what I read about dynamlic libraries in general, it seems that the binary never actually calls that dlclose() function which in turn would call the destructor - but I can only assume on this one.
 
Matthew Bendford
Ranch Hand
Posts: 51
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Just as an update: The ArmA3 community wasn't able to give me any useful input to my questions about this issue. I also tried to to look up similar questions like mine, but found only one, which never got any reply to it.
To me it seems weird that some application designed with user created content in mind and an official modding api seem not to care to correct shutdown the loaded extensions, and that noone yet seem to have reported that issue.
 
Tim Holloway
Saloon Keeper
Posts: 23252
158
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Matthew Bendford wrote:
To me it seems weird that some application designed with user created content in mind and an official modding api seem not to care to correct shutdown the loaded extensions, and that noone yet seem to have reported that issue.


To me it doesn't.
 
Matthew Bendford
Ranch Hand
Posts: 51
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, some news about that issue:

I just got a reply of some of the devs on their bug tracker: As by my report they checked what's happening when the #shutdown command is called. The main game loop is just "crashed to console" by calling exit(0) on it, and they rely on the OS and/or the runtime to clean up the allocated resources.
As the game ArmA3 was first developed for Windows only and was later ported to Linux, they rely on stuff like Windows' DLL framework calling the destructor when a thread is detached and the ref-counter is decremented. On Linux this doesn't work the same as, from what I read, POSIX require the caller to explicit call dlclose(), which is only is required to invalidate the handle given, and it's up to the sepcfic implementation if dlclose() actually calls a dynamic library destructor. They may consider to "fix" that in some later patch - but I already came up with some other ways to achieve my goal by doing the shutdown somewhat "backwards".

@Tim
Why?
 
Who among you feels worthy enough to be my best friend? Test 1 is to read this tiny ad:
the value of filler advertising in 2021
https://coderanch.com/t/730886/filler-advertising
reply
    Bookmark Topic Watch Topic
  • New Topic