runtime crashes with "rt/sections_elf_shared.d(688) _handleToDSO not in sync with _loadedDSOs"
Jaap Geurts
jaap.geurts at gmail.com
Wed Nov 15 22:41:19 UTC 2023
I apologize if this has been asked before but I couldn't find
help here or anywhere else.
I'm trying to load my code as a dynamic library in a C++ program.
It is working, but I have a problem upon program exit with thread
local storage.
What I'm trying to do:
The c++ loads my dynamic library from a thread (not the main
thread) and when the application exits from the main thread
(without properly unloading the library), the finalizers run in
the main thread and do not know about the loaded library (because
it's kept in TLS `_loadedDSOs` in the thread that loaded the
library) but the handle to the library is recorded in `__global
_handleToDSOs`. When the main thread exits the loaded libraries
is compared to the open handles. Since the main thread thinks
nothing is loaded (`_loadedDSOs` is empty) the code aborts
because the handle `_handleToDSOs` is not empty. This causes the
d runtime to abort. I've reduced the problem to this example code:
```
#include <dlfcn.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void* loadlib(void*);
void main()
{
int counter = 0;
pthread_t thread1;
pthread_attr_t attrs;
pthread_attr_init(&attrs);
pthread_create(&thread1, &attrs, &loadlib, NULL);
while (true) {
printf("Main %d\n", counter++);
usleep(300000);
if (counter == 5)
break;
}
}
void* loadlib(void* args)
{
int counter = 100;
void* dlib = dlopen("libdlibrary.so", RTLD_LAZY |
RTLD_GLOBAL);
if (dlib == NULL) {
printf("Can't open dlib\n");
exit(0);
}
void (*dfunc)() = dlsym(dlib, "dfunc");
dfunc();
while (true) {
printf("Thread %d\n", counter++);
usleep(700000);
}
}
```
Compile with `cc -o app app.c`
And the D code as a library
```
import std.stdio;
import core.runtime;
extern (C) void dfunc() {
writeln("Hello from D");
// rt_init();
}
```
Compile with: `ldc2 -shared dlibrary.d`
And run the app with: `LD_LIBRARY_PATH=. ./app`
This causes the crash.
I realize that this is not the correct way to do things, but the
problem is, I can't change the way the C++ program works which
is: It loads my library from a thread, but when it exits, it just
quits the main thread. Things I can't do on the C++ program:
1. load the lib from the main thread. (My code is a plugin which
only becomes active when it is being loaded by the thread)
2. gracefully stop the thread that loaded the library and unload
the library
3. the c++ program never unloads the lib so
pragma(crt_destructor) doesn't work either
4. rt_init() doesn't help either.
Is there anything I can do to fix this issue on the D side?
Help would be greatly appreciated!
More information about the Digitalmars-d
mailing list