Пример #1
0
void
loader_thread_exit(dcontext_t *dcontext)
{
    privmod_t *mod;
    /* assuming context swap have happened when entered DR */
    if (privload_has_thread_entry() &&
        /* Only call if we're cleaning up the currently executing thread, as
         * that's what the entry routine is going to do!  Calling on other
         * threads results in problems like double frees (i#969).  Exiting
         * another thread should only happen on process exit or forced thread
         * termination.  The former can technically continue (app could call
         * NtTerminateProcess(0) but then keep going) but we have never seen
         * that; and the latter doesn't do full native cleanups anyway.  Thus
         * we're not worried about leaks from not calling DLL_THREAD_EXIT.
         * (We can't check get_thread_private_dcontext() b/c it's already cleared.)
         */
        dcontext->owning_thread == get_thread_id()) {
        acquire_recursive_lock(&privload_lock);
        /* Walk forward and call independent libs last */
        for (mod = modlist; mod != NULL; mod = mod->next) {
            if (!mod->externally_loaded)
                privload_call_entry(mod, DLL_THREAD_EXIT);
        }
        release_recursive_lock(&privload_lock);
    }
    /* os specific thread exit for loader, holding no lock */
    os_loader_thread_exit(dcontext);
}
Пример #2
0
void
loader_thread_exit(dcontext_t *dcontext)
{
    privmod_t *mod;
    /* assuming context swap have happened when entered DR */
    if (privload_has_thread_entry()) {
        acquire_recursive_lock(&privload_lock);
        /* Walk forward and call independent libs last */
         for (mod = modlist; mod != NULL; mod = mod->next) {
            if (!mod->externally_loaded)
                privload_call_entry(mod, DLL_THREAD_EXIT);
        }
        release_recursive_lock(&privload_lock);
    }
    /* os specific thread exit for loader, holding no lock */
    os_loader_thread_exit(dcontext);
}