[LINUX] [C / C ++] [GCC] __attribute __ ((constructor)) to execute processing before and after main

Verification and usage summary of __attribute__ ((constructor)) Note that this is an extension of GCC and will not work everywhere.

When including in the source

main.c


#include <stdio.h>

__attribute__((constructor))
static void constructor() {
	puts("constructor");
}

__attribute__((destructor))
static void destructor() {
	puts("destructor");
}

int main(int argc, char const* argv[])
{
	puts("call main");
	return 0;
}

Build and execution results


$ gcc main.c && ./a.out
constructor
call main
destructor

When linking as a shared library

main.c


#include <stdio.h>

int main(int argc, char const* argv[])
{
	puts("call main");
	return 0;
}

sharedlib.c


#include <stdio.h>

__attribute__((constructor))
static void constructor() {
	puts("constructor");
}

__attribute__((destructor))
static void destructor() {
	puts("destructor");
}

Build and execution results


$ gcc -shared -fPIC sharedlib.c -o libconstructor.so
$ gcc main.c -L . -lconstructor
$ LD_LIBRARY_PATH=. ./a.out
constructor
call main
destructor

When using LD_PRELOAD

By using LD_PRELOAD, it is possible to add processing to any program later.

main.c


#include <stdio.h>

int main(int argc, char const* argv[])
{
	puts("call main");
	return 0;
}

preload.c


#include <stdio.h>

__attribute__((constructor))
static void constructor() {
	puts("constructor");
}

__attribute__((destructor))
static void destructor() {
	puts("destructor");
}

Build and execution results


$ gcc main.c && ./a.out
call main

$ gcc -shared -fPIC preload.c -o preload.so
$ LD_PRELOAD=./preload.so ./a.out
constructor
call main
destructor

When there are multiple __attribute__ ((constructor))

It works fine even if there are multiple __attribute__ ((constructor)). (However, the execution order is unknown, and it seems better to avoid processes that depend on the execution order.)

main.c


#include <stdio.h>

__attribute__((constructor))
static void constructor1() {
	puts("constructor1");
}

__attribute__((destructor))
static void destructor1() {
	puts("destructor1");
}

int main(int argc, char const* argv[])
{
	puts("call main");
	return 0;
}

preload.c


#include <stdio.h>

__attribute__((constructor))
static void constructor2() {
	puts("constructor2");
}

__attribute__((destructor))
static void destructor2() {
	puts("destructor2");
}

Build and execution results


$ gcc main.c && ./a.out
constructor1
call main
destructor1

$ gcc -shared -fPIC preload.c -o preload.so
$ LD_PRELOAD=./preload.so ./a.out
constructor2
constructor1
call main
destructor1
destructor2

reference

Call a function before main ()-bk blog c++ - How exactly does attribute((constructor)) work? - Stack Overflow Try using attribute ((constructor)) from GCC: Book of Days gcc - C++ static initialization vs attribute((constructor)) - Stack Overflow

Recommended Posts

[C / C ++] [GCC] __attribute __ ((constructor)) to execute processing before and after main
Insert processing before and after the view function in Pyramid's own View Decorator