diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-25 11:36:14 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-25 11:36:14 +0100 |
| commit | 72ca99051b9ea5786e22214d2cbb0befd70be670 (patch) | |
| tree | 03ff3001d6097a6aa0a7d1cfc4c19ed037fc41c6 /src | |
| parent | 905e3ae583da508c24dbb80628fb08084e62ae80 (diff) | |
| download | box64-72ca99051b9ea5786e22214d2cbb0befd70be670.tar.gz box64-72ca99051b9ea5786e22214d2cbb0befd70be670.zip | |
Improved shutdown sequence
Diffstat (limited to 'src')
| -rwxr-xr-x | src/box64context.c | 10 | ||||
| -rwxr-xr-x | src/elfs/elfloader.c | 2 | ||||
| -rwxr-xr-x | src/include/librarian.h | 2 | ||||
| -rwxr-xr-x | src/include/library.h | 2 | ||||
| -rwxr-xr-x | src/librarian/librarian.c | 6 | ||||
| -rwxr-xr-x | src/librarian/library.c | 19 | ||||
| -rwxr-xr-x | src/main.c | 46 |
7 files changed, 69 insertions, 18 deletions
diff --git a/src/box64context.c b/src/box64context.c index 91aa4fbc..f020191e 100755 --- a/src/box64context.c +++ b/src/box64context.c @@ -129,16 +129,16 @@ void FreeBox64Context(box64context_t** context) box64context_t* ctx = *context; // local copy to do the cleanning + if(ctx->local_maplib) + FreeLibrarian(&ctx->local_maplib, NULL); + if(ctx->maplib) + FreeLibrarian(&ctx->maplib, NULL); + for(int i=0; i<ctx->elfsize; ++i) { FreeElfHeader(&ctx->elfs[i]); } free(ctx->elfs); - if(ctx->maplib) - FreeLibrarian(&ctx->maplib); - if(ctx->local_maplib) - FreeLibrarian(&ctx->local_maplib); - FreeCollection(&ctx->box64_path); FreeCollection(&ctx->box64_ld_lib); FreeCollection(&ctx->box64_emulated_libs); diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c index 52aab63e..652ec253 100755 --- a/src/elfs/elfloader.c +++ b/src/elfs/elfloader.c @@ -1097,7 +1097,7 @@ const char* FindNearestSymbolName(elfheader_t* h, void* p, uintptr_t* start, uin const char* ret = NULL; uintptr_t s = 0; uint32_t size = 0; - if(!h) + if(!h || h->fini_done) return ret; for (int i=0; i<h->numSymTab && distance!=0; ++i) { diff --git a/src/include/librarian.h b/src/include/librarian.h index a25fcd7b..f63b500f 100755 --- a/src/include/librarian.h +++ b/src/include/librarian.h @@ -15,7 +15,7 @@ typedef struct kh_mapoffsets_s kh_mapoffsets_t; typedef char* cstr_t; lib_t *NewLibrarian(box64context_t* context, int ownlibs); -void FreeLibrarian(lib_t **maplib); +void FreeLibrarian(lib_t **maplib, x64emu_t* emu); dlprivate_t *NewDLPrivate(); void FreeDLPrivate(dlprivate_t **lib); diff --git a/src/include/library.h b/src/include/library.h index d33b1126..9af07c34 100755 --- a/src/include/library.h +++ b/src/include/library.h @@ -14,7 +14,7 @@ int AddSymbolsLibrary(lib_t* maplib, library_t* lib, x64emu_t* emu); int FinalizeLibrary(library_t* lib, lib_t* local_maplib, x64emu_t* emu); int ReloadLibrary(library_t* lib, x64emu_t* emu); void InactiveLibrary(library_t* lib); -void Free1Library(library_t **lib); +void Free1Library(library_t **lib, x64emu_t* emu); char* GetNameLib(library_t *lib); int IsSameLib(library_t* lib, const char* path); // check if lib is same (path -> name) diff --git a/src/librarian/librarian.c b/src/librarian/librarian.c index dcfe4754..f7f3756a 100755 --- a/src/librarian/librarian.c +++ b/src/librarian/librarian.c @@ -34,7 +34,7 @@ lib_t *NewLibrarian(box64context_t* context, int ownlibs) return maplib; } -void FreeLibrarian(lib_t **maplib) +void FreeLibrarian(lib_t **maplib, x64emu_t *emu) { // should that be in reverse order? if(!maplib || !*maplib) @@ -42,9 +42,9 @@ void FreeLibrarian(lib_t **maplib) if((*maplib)->ownlibs) { printf_log(LOG_DEBUG, "Closing %d libs from maplib %p\n", (*maplib)->libsz, *maplib); - for (int i=0; i<(*maplib)->libsz; ++i) { + for (int i=(*maplib)->libsz-1; i>=0; --i) { printf_log(LOG_DEBUG, "Unloading %s\n", (*maplib)->libraries[i].lib->name); - Free1Library(&(*maplib)->libraries[i].lib); + Free1Library(&(*maplib)->libraries[i].lib, emu); } } free((*maplib)->libraries); diff --git a/src/librarian/library.c b/src/librarian/library.c index b0be60b4..bd85b8cf 100755 --- a/src/librarian/library.c +++ b/src/librarian/library.c @@ -246,13 +246,13 @@ library_t *NewLibrary(const char* path, box64context_t* context) printf_log(LOG_DEBUG, "Simplified name is \"%s\"\n", lib->name); if(box64_nopulse) { if(strstr(lib->name, "libpulse.so")==lib->name || strstr(lib->name, "libpulse-simple.so")==lib->name) { - Free1Library(&lib); + Free1Library(&lib, NULL); return NULL; } } if(box64_novulkan) { if(strstr(lib->name, "libvulkan.so")==lib->name) { - Free1Library(&lib); + Free1Library(&lib, NULL); return NULL; } } @@ -270,7 +270,7 @@ library_t *NewLibrary(const char* path, box64context_t* context) // nothing loaded, so error... if(lib->type==-1) { - Free1Library(&lib); + Free1Library(&lib, NULL); return NULL; } @@ -375,10 +375,18 @@ void InactiveLibrary(library_t* lib) lib->active = 0; } -void Free1Library(library_t **lib) +void Free1Library(library_t **lib, x64emu_t* emu) { if(!(*lib)) return; + if((*lib)->type==1 && emu) { + elfheader_t *elf_header = (*lib)->context->elfs[(*lib)->priv.n.elf_index]; + RunElfFini(elf_header, emu); + } + + if((*lib)->maplib) + FreeLibrarian(&(*lib)->maplib, emu); + if((*lib)->type!=-1 && (*lib)->fini) { (*lib)->fini(*lib); } @@ -411,9 +419,6 @@ void Free1Library(library_t **lib) kh_destroy(symbol2map, (*lib)->symbol2map); free_neededlib(&(*lib)->needed); - if((*lib)->maplib) - FreeLibrarian(&(*lib)->maplib); - free(*lib); *lib = NULL; } diff --git a/src/main.c b/src/main.c index c14591b0..66bfd94d 100755 --- a/src/main.c +++ b/src/main.c @@ -589,6 +589,52 @@ void endBox64() if(!my_context) return; + x64emu_t* emu = thread_get_emu(); + //atexit first + printf_log(LOG_DEBUG, "Calling atexit registered functions\n"); + CallAllCleanup(emu); + // than call all the Fini (some "smart" ordering of the fini may be needed, but for now, callign in this order should be good enough) + printf_log(LOG_DEBUG, "Calling fini for all loaded elfs and unload native libs\n"); + RunElfFini(my_context->elfs[0], emu); + FreeLibrarian(&my_context->maplib, emu); // unload all libs + FreeLibrarian(&my_context->local_maplib, emu); // unload all libs + // waiting for all thread except this one to finish + int this_thread = GetTID(); + int pid = getpid(); + int running = 1; + int attempt = 0; + printf_log(LOG_DEBUG, "Waiting for all threads to finish before unloading box86context\n"); + while(running) { + DIR *proc_dir; + char dirname[100]; + snprintf(dirname, sizeof dirname, "/proc/self/task"); + proc_dir = opendir(dirname); + running = 0; + if (proc_dir) + { + struct dirent *entry; + while ((entry = readdir(proc_dir)) != NULL && !running) + { + if(entry->d_name[0] == '.') + continue; + + int tid = atoi(entry->d_name); + // tid != pthread_t, so no pthread functions are available here + if(tid!=this_thread) { + if(attempt>4000) { + printf_log(LOG_INFO, "Stop waiting for remaining thread %04d\n", tid); + // enough wait, kill all thread! + syscall(__NR_tgkill, pid, tid, SIGABRT); + } else { + running = 1; + ++attempt; + sched_yield(); + } + } + } + closedir(proc_dir); + } + } // all done, free context FreeBox64Context(&my_context); if(libGL) { |