0

I have not found answer for this question but I'm almost 100% sure there is laying out somewhere.

I have a normal C++ class, and I'm using a 3rd party logging system. Unfortunately I have 2 requirements and 3 facts which I can't match:

Requirements:

  1. Log something in destructor
  2. Handle the program termination clean (without crash)

Facts:

  1. 3rd party logging system crashes on program termination, because it calls pthread_mutex_lock.
  2. I don't want to change this logging system
  3. I also don't want to deepdive into it

Here is the code:

class myClass {
public:
  myClass() {}
  ~myClass() {
    LOG << "Destructor called!";
  }
};

int main() {
  myClass c;
  sleep(1);
  return 0;
}

When program finishes, there is a segmentation fault because of the LOG command (i.e: if I remove it, there is no segfault).

In normal circumstances I'd need this log function to show when myClass is destructed, so here comes the straightforward question:

Can I somehow detect in the destructor of a class (myClass) if program is terminating (or something else is the reason for destruction)?

Daniel
  • 2,318
  • 2
  • 22
  • 53
  • Shouldn't your `main()` function return something? – vahancho Jul 20 '20 at 12:17
  • 4
    @vahancho No, `main()` is special and compiler will add `return 0;` implicitly if control reaches the end of this function. – Yksisarvinen Jul 20 '20 at 12:18
  • @Yksisarvinen, really? Could you point the documentation that states that? – vahancho Jul 20 '20 at 12:21
  • To put this question back on track I've updated `main`. – Daniel Jul 20 '20 at 12:23
  • 1
    @vahancho It's in [the standard](http://eel.is/c++draft/basic.start.main#5) – Blastfurnace Jul 20 '20 at 12:24
  • 2
    @vahancho From [C++17 draft](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf) 6.6.1: "5. A return statement in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling std::exit with the return value as the argument. If control flows off the end of the compound-statement of main, the effect is equivalent to a return with operand 0 (see also 18.3)." – Yksisarvinen Jul 20 '20 at 12:24
  • @Blastfurnace, Yksisarvinen thanks. – vahancho Jul 20 '20 at 12:26
  • 1
    May be related to the [static initialization fiasco](https://stackoverflow.com/questions/29822181/prevent-static-initialization-order-fiasco-c). – François Andrieux Jul 20 '20 at 12:34
  • Trying to detect termination and altering the behaviour is just patching the symptom. The problem is likely to reemerge later. It isn't normal for a destructor to crash when the progran ends. There is an error somewhere in your code and you need to find it. It might be a destruction ordre problem, see the link in my previous comment. – François Andrieux Jul 20 '20 at 12:39
  • `bool global_program_is_terminating = false;` When the program is terminating, set that global variable to `true`. Objects are destructed because: local variable going out of scope; `new` or `new[]` variable that has been `delete` or `delete[]`; global variable being destructed (probaby by `std::atexit` mechanism). For global variables, order-of-construction and order-of-destruction can be particularly annoying bugs to rectify -- I try to avoid global variables as much as possible. – Eljay Jul 20 '20 at 12:41
  • actually a 1 second sleep put into *end* of destructor "fixes" this. – Daniel Jul 20 '20 at 12:49
  • Sounds like this "3rd party logging library" is a buggy pile of garbage. The correct solution here is to get rid of it, and replace it with something that actually contains well-formed C++ code. Otherwise you'll just have to keep coming up with these ugly, hacky workarounds forever. Except for repeating the advice to get rid of it, there's nothing that anyone on stackoverlfow.com will be able to help you with. That would require direct knowledge and familiarity with this "3rd party logging library", and a complete and full understanding of all of its bugs and ways to work around them. – Sam Varshavchik Jul 20 '20 at 13:05
  • @Daniel *actually a 1 second sleep put into end of destructor "fixes" this.* -- This is not a fix. It would help if you mentioned the name of this "third-party logging system" . Maybe someone here already uses it, and thus can give you an answer. – PaulMcKenzie Jul 20 '20 at 13:15
  • Paul, Sam: Thank you both, currently I don't really have time to change that library, it's *easyloggingpp* anyway, but will look into it once. – Daniel Jul 20 '20 at 13:45

1 Answers1

2

Can I somehow detect in the destructor of a class (myClass) if program is terminating

Yes, if the instance has static storage. You can register a function that will be executed during destruction of static objects using std::atexit. This function can be used to set a namespace scope variable that signifies whether the program is exiting or not. The destructor of your class can check the state of that variable.

You must make sure that the instance whose destructor relies on the variable is created before std::atexit is called.

eerorika
  • 232,697
  • 12
  • 197
  • 326