Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create/construct a class instance earlier than any other global or static variable?

Tags:

c++

linux

How to create an instance of a particular class earlier than main(), earlier than any other instance (including static and global variables, including in the static and dynamic libraries (including libraries provided by 3rd parties))?


I'm dealing with a project with a number of classes that during construction can cause an error, e.g. access a NULL pointer. Any such error causes a signal to be sent to the app. I have a signal handler that catches the signals, shows the stack trace of the offending thread, and invokes the default signal handler which results in the core dump generated, etc.
However some of such error-causing instances are created as the global variables and static variables of the classes. I.e. they are constructed and cause a signal earlier than main() is entered.

To catch such signals I need to register my signal handler earlier than in main(), i.e. I need to create an instance (that will register the signal handler) also as a global or class-static variable, and I need to guarantee that such an instance is created/constructed earlier than any other instance.

How to get that done?


To register a signal handler I use sigaction().
To show the stack trace I use backtrace(), backtrace_symbols(), abi::__cxa_demangle().

like image 425
Robin Kuzmin Avatar asked Feb 08 '18 00:02

Robin Kuzmin


2 Answers

Standard C++ doesn't provide a way to order initializers between translation units, but gcc does. Example from https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html:

Some_Class A __attribute__((init_priority (2000)));

The lowest value (highest priority) is 101.

like image 82
Todd Fleming Avatar answered Sep 27 '22 21:09

Todd Fleming


Order of calling static constructors depends on their order in a source file, order of linking and order of loading shared libraries. The usual way of doing what you need is to create a separate file with your registration function, and to make sure that the corresponding object appears as the very first one at the linker command line. It should not be a part of any shared or static library.

i.e. first.c

static int first_function() {
    // register your signals
    ...
    return 0;
}
static int status = first_function();


gcc -c first.c -o first.o
gcc -o myexec first.o ... all other files
like image 20
Serge Avatar answered Sep 27 '22 21:09

Serge