Last active
February 11, 2019 04:52
-
-
Save mine260309/3c1a1cba26af1847bc187e4ffae724d6 to your computer and use it in GitHub Desktop.
Demo of bug about init priority in both gcc and clang
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "bar.h" | |
#include <memory> | |
template <typename T> | |
struct Constructor | |
{ | |
Constructor(T&& fn) | |
{ | |
fn(); | |
} | |
Constructor() = delete; | |
~Constructor() = default; | |
}; | |
void on_load(); | |
// Putting this init before barGlobalPtr | |
static Constructor<void(*)(void)> init(on_load); | |
#ifdef BUG | |
std::unique_ptr<bar> barGlobalPtr(new bar(1)); | |
#else | |
std::unique_ptr<bar> barGlobalPtr | |
__attribute__((init_priority(101))) (new bar(1)); | |
#endif | |
//void on_load() __attribute__((constructor)); | |
void on_load() | |
{ | |
barGlobalPtr.reset(new bar(2)); | |
} | |
void bar_func(void) | |
{ | |
printf("bar global ptr %p, value: %d\n", barGlobalPtr.get(), barGlobalPtr->m); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <cstdio> | |
struct bar | |
{ | |
bar(int i) | |
:m(i) | |
{ | |
printf("%s: %p, %d\n", __func__, this, m); | |
} | |
~bar() | |
{ | |
printf("%s: %p, %d\n", __func__, this, m); | |
} | |
int m; | |
}; | |
extern "C" void bar_func(void); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "bar.h" | |
#include <cstdio> | |
#include <cstdlib> | |
#include <cassert> | |
#include <dlfcn.h> | |
using bar_func_type = void(*)(void); | |
int main(void) | |
{ | |
auto h = dlopen("./libbar.so", RTLD_LAZY); | |
if (!h) | |
{ | |
fprintf(stderr, "%s\n", dlerror()); | |
exit(EXIT_FAILURE); | |
} | |
bar_func_type f = nullptr; | |
auto r = dlsym(h, "bar_func"); | |
if (!r) | |
{ | |
fprintf(stderr, "%s\n", dlerror()); | |
goto out; | |
} | |
*reinterpret_cast<void**>(&f) = r; | |
f(); | |
out: | |
dlclose(h); | |
return 0; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CC=g++ | |
#CC=clang++ | |
CFLAGS=-c -Wall -fpic | |
BUGFLAG=-DBUG | |
SOURCES=main.cpp bar.cpp | |
all: main | |
main: main.o libbar.so | |
$(CC) -o main main.o -ldl | |
libbar.so: bar.cpp | |
$(CC) $(BUGFLAG) -shared -fPIC -o $@ $< | |
.cpp.o: | |
$(CC) $(CFLAGS) $< -o $@ | |
clean: | |
@rm -f main main.o bar.o libbar.so | |
### | |
# | |
# To show the bug: | |
# | |
# make | |
# ./main | |
# | |
# Output: | |
# | |
# bar: 0x55e42b836570, 2 | |
# bar: 0x55e42b8369a0, 1 | |
# bar global ptr 0x55e42b8369a0, value: 1 | |
# ~bar: 0x55e42b8369a0, 1 | |
# | |
# To show the fix of the bug: | |
# | |
# make BUGFLAG= | |
# ./main | |
# | |
# Output: | |
# | |
# bar: 0x5592bb9df570, 1 | |
# bar: 0x5592bb9df9a0, 2 | |
# ~bar: 0x5592bb9df570, 1 | |
# bar global ptr 0x5592bb9df9a0, value: 2 | |
# ~bar: 0x5592bb9df9a0, 2 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment