On 4/14/21 8:25 PM, Adriano dos Santos Fernandes wrote:
Hi!

C++ guarantees the execution order of constructors only inside the same
translation unit (say, a .cpp file) for global objects.

It also guarantees inverse order of destructors in relation to
constructors order.

But constructor order across translation units are undefined.

We used to have problems with that.

Then things like InitInstance and GlobalPtr were born.

As I understand, in "common" (not Firebird code) C++, usage of
new/malloc on library code not paired with delete/free becomes memory
leaks when that library are unloaded.

But in Firebird these goes to default pool with are deallocated at
library exit.

It's good thing, but it's were the problem starts.

I was doing some tests integrating Boost.Test library in Firebird code.
And then it segfaults at exit.

It uses global std objects which in this case have theirs destructors
called after Firebird default pool are already cleaned up.

Yes, that's really a problem. And must say that even forgetting about MemPool implementation details I hardly understand how is it supposed to work with redefined new / delete. One can have global objects in a unit, implementing new and delete, but Ido not know how does standard suppose to have working new/delete before constructors and after destructors of that objects are executed.


In current code, we have re2 C++ library statically linked.

It looks like it works because it does not have global objects, i.e., we
rely on re2 implementation details.

To be precise - not each global object is a problem, only one that can allocate memory itself.


I was looking at better way to solve this problem.

GCC/clang has init_priority attribute:
https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html

It's not well documented. Here we see some implementation details about
default value: https://gcc.gnu.org/legacy-ml/gcc-help/2015-08/msg00027.html

I have tested with common/classes/init.cpp and this solved the specific
problem I had with Boost.Test:

Cleanup global __attribute__ ((init_priority (2000)));

As far as I can see from documentation init_priority works only inside simgle file. It might affect global order as side effect but (correct me if I'm wrong) nobody guarantees cross-file order of ctors (and dtors - actually we care about it).


For MSVC I didn't tested, but found this docs with probably could be
used for similar behavior:

https://docs.microsoft.com/en-us/cpp/preprocessor/init-seg?redirectedfrom=MSDN&view=msvc-160

This one should work cross-file - at least if my understanding of sections in MS tools is correct.





Firebird-Devel mailing list, web interface at 
https://lists.sourceforge.net/lists/listinfo/firebird-devel

Reply via email to