Skip to content

Commit 0dd96b0

Browse files
authored
Keep DSO file data around after dlsync. NFC (#19378)
Its not generally safe to free this data because some threads might have been alseep when the dlsync occurred. In these cases they need to be able to catchup/sync when they wake at some point in the future. This also happens to fix the issue where new threads that get created after the dlopen didn't have access to the file data. The downside is that, for now, we leak the file data for DSOs that get loaded. Fixes: #19371
1 parent dd4fbbe commit 0dd96b0

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed

system/lib/libc/dynlink.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,10 @@ static void load_library_done(struct dso* p) {
163163
// Block until all other threads have loaded this module.
164164
dlsync();
165165
#endif
166-
if (p->file_data) {
167-
free(p->file_data);
168-
p->file_data_size = 0;
169-
}
166+
// TODO: figure out some way to tell when its safe to free p->file_data. Its
167+
// not safe to do here because some threads could have been alseep then when
168+
// the "dlsync" occurred and those threads will synchronize when they wake,
169+
// which could be an arbitrarily long time in the future.
170170
}
171171

172172
static struct dso* load_library_start(const char* name, int flags) {

test/core/pthread/test_pthread_dlopen.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ int main() {
5252
while (!started) {}
5353

5454
printf("loading dylib\n");
55-
void* handle = dlopen("liblib.so", RTLD_NOW|RTLD_GLOBAL);
55+
void* handle = dlopen("libside.so", RTLD_NOW|RTLD_GLOBAL);
5656
if (!handle) {
5757
printf("dlerror: %s\n", dlerror());
5858
}
@@ -78,6 +78,18 @@ int main() {
7878
assert(rc == 0);
7979
printf("done join\n");
8080

81+
printf("starting second & third thread\n");
82+
pthread_t t2, t3;
83+
rc = pthread_create(&t2, NULL, thread_main, NULL);
84+
assert(rc == 0);
85+
rc = pthread_create(&t3, NULL, thread_main, NULL);
86+
assert(rc == 0);
87+
rc = pthread_join(t2, NULL);
88+
assert(rc == 0);
89+
rc = pthread_join(t3, NULL);
90+
assert(rc == 0);
91+
printf("starting second & third thread\n");
92+
8193
dlclose(handle);
8294
return 0;
8395
}

test/test_core.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9429,6 +9429,7 @@ def test_pthread_dlopen(self):
94299429
self.emcc_args += ['-Wno-experimental', '-pthread']
94309430
self.build_dlfcn_lib(test_file('core/pthread/test_pthread_dlopen_side.c'))
94319431

9432+
self.emcc_args += ['--embed-file', '[email protected]']
94329433
self.prep_dlfcn_main()
94339434
self.set_setting('EXIT_RUNTIME')
94349435
self.set_setting('PROXY_TO_PTHREAD')

0 commit comments

Comments
 (0)