void cleanup_handle(void *obj) { WINPR_THREAD* thread = (WINPR_THREAD*) obj; int rc = pthread_mutex_destroy(&thread->mutex); if (rc) WLog_ERR(TAG, "failed to destroy mutex [%d] %s (%d)", rc, strerror(errno), errno); if (thread->pipe_fd[0]) close(thread->pipe_fd[0]); if (thread->pipe_fd[1]) close(thread->pipe_fd[1]); if (thread_list && ListDictionary_Contains(thread_list, &thread->thread)) ListDictionary_Remove(thread_list, &thread->thread); #if defined(WITH_DEBUG_THREADS) if (thread->create_stack) winpr_backtrace_free(thread->create_stack); if (thread->exit_stack) winpr_backtrace_free(thread->exit_stack); #endif free(thread); }
static void log_recursion(const char* file, const char* fkt, int line) { size_t used, i; void* bt = winpr_backtrace(20); char** msg = winpr_backtrace_symbols(bt, &used); #if defined(ANDROID) const char* tag = WINPR_TAG("utils.wlog"); __android_log_print(ANDROID_LOG_FATAL, tag, "Recursion detected!!!"); __android_log_print(ANDROID_LOG_FATAL, tag, "Check %s [%s:%d]", fkt, file, line); for (i=0; i<used; i++) __android_log_print(ANDROID_LOG_FATAL, tag, "%d: %s", msg[i]); #else fprintf(stderr, "[%s]: Recursion detected!\n", fkt); fprintf(stderr, "[%s]: Check %s:%d\n", fkt, file, line); for (i=0; i<used; i++) fprintf(stderr, "%s: %zd: %s\n", fkt, i, msg[i]); #endif if (msg) free(msg); winpr_backtrace_free(bt); }
int TestBacktrace(int argc, char* argv[]) { int rc = -1; size_t used, x; char **msg; void *stack = winpr_backtrace(20); if (!stack) { fprintf(stderr, "winpr_backtrace failed!\n"); return -1; } msg = winpr_backtrace_symbols(stack, &used); if (msg) { for (x=0; x<used; x++) printf("%"PRIuz": %s\n", x, msg[x]); rc = 0; } winpr_backtrace_symbols_fd(stack, fileno(stdout)); winpr_backtrace_free(stack); return rc; }
BOOL MutexCloseHandle(HANDLE handle) { WINPR_MUTEX* mutex = (WINPR_MUTEX*) handle; int rc; if (!MutexIsHandled(handle)) return FALSE; rc = pthread_mutex_trylock(&mutex->mutex); switch(rc) { case 0: /* The mutex is now locked. */ break; /* If we already own the mutex consider it a success. */ case EDEADLK: case EBUSY: break; default: #if defined(WITH_DEBUG_MUTEX) { size_t used = 0, i; void* stack = winpr_backtrace(20); char **msg = NULL; if (stack) msg = winpr_backtrace_symbols(stack, &used); if (msg) { for(i=0; i<used; i++) WLog_ERR(TAG, "%2d: %s", i, msg[i]); } free (msg); winpr_backtrace_free(stack); } #endif WLog_ERR(TAG, "pthread_mutex_trylock failed with %s [%d]", strerror(rc), rc); return FALSE; } rc = pthread_mutex_unlock(&mutex->mutex); if (rc != 0) { WLog_ERR(TAG, "pthread_mutex_unlock failed with %s [%d]", strerror(rc), rc); return FALSE; } rc = pthread_mutex_destroy(&mutex->mutex); if (rc != 0) { WLog_ERR(TAG, "pthread_mutex_destroy failed with %s [%d]", strerror(rc), rc); return FALSE; } free(handle); return TRUE; }
void winpr_log_backtrace(const char* tag, DWORD level, DWORD size) { size_t used, x; char **msg; void *stack = winpr_backtrace(20); if (!stack) { WLog_ERR(tag, "winpr_backtrace failed!\n"); winpr_backtrace_free(stack); return; } msg = winpr_backtrace_symbols(stack, &used); if (msg) { for (x=0; x<used; x++) WLog_LVL(tag, level, "%lu: %s\n", (unsigned long)x, msg[x]); } winpr_backtrace_free(stack); }
static BOOL log_recursion(LPCSTR file, LPCSTR fkt, int line) { char** msg; size_t used, i; void* bt = winpr_backtrace(20); #if defined(ANDROID) LPCSTR tag = WINPR_TAG("utils.wlog"); #endif if (!bt) return FALSE; msg = winpr_backtrace_symbols(bt, &used); if (!msg) return FALSE; #if defined(ANDROID) if (__android_log_print(ANDROID_LOG_FATAL, tag, "Recursion detected!!!") < 0) return FALSE; if (__android_log_print(ANDROID_LOG_FATAL, tag, "Check %s [%s:%d]", fkt, file, line) < 0) return FALSE; for (i = 0; i < used; i++) if (__android_log_print(ANDROID_LOG_FATAL, tag, "%d: %s", i, msg[i]) < 0) return FALSE; #else if (fprintf(stderr, "[%s]: Recursion detected!\n", fkt) < 0) return FALSE; if (fprintf(stderr, "[%s]: Check %s:%d\n", fkt, file, line) < 0) return FALSE; for (i = 0; i < used; i++) if (fprintf(stderr, "%s: %lu: %s\n", fkt, (unsigned long)i, msg[i]) < 0) return FALSE; #endif free(msg); winpr_backtrace_free(bt); return TRUE; }
static void dump_thread(WINPR_THREAD* thread) { #if defined(WITH_DEBUG_THREADS) void* stack = winpr_backtrace(20); char** msg; size_t used, i; WLog_DBG(TAG, "Called from:"); msg = winpr_backtrace_symbols(stack, &used); for (i = 0; i < used; i++) WLog_DBG(TAG, "[%d]: %s", i, msg[i]); free(msg); winpr_backtrace_free(stack); WLog_DBG(TAG, "Thread handle created still not closed!"); msg = winpr_backtrace_symbols(thread->create_stack, &used); for (i = 0; i < used; i++) WLog_DBG(TAG, "[%d]: %s", i, msg[i]); free(msg); if (thread->started) { WLog_DBG(TAG, "Thread still running!"); } else if (!thread->exit_stack) { WLog_DBG(TAG, "Thread suspended."); } else { WLog_DBG(TAG, "Thread exited at:"); msg = winpr_backtrace_symbols(thread->exit_stack, &used); for (i = 0; i < used; i++) WLog_DBG(TAG, "[%d]: %s", i, msg[i]); free(msg); } #endif }
BOOL MutexCloseHandle(HANDLE handle) { WINPR_MUTEX* mutex = (WINPR_MUTEX*) handle; int rc; if (!MutexIsHandled(handle)) return FALSE; if ((rc = pthread_mutex_destroy(&mutex->mutex))) { WLog_ERR(TAG, "pthread_mutex_destroy failed with %s [%d]", strerror(rc), rc); #if defined(WITH_DEBUG_MUTEX) { size_t used = 0, i; void* stack = winpr_backtrace(20); char **msg = NULL; if (stack) msg = winpr_backtrace_symbols(stack, &used); if (msg) { for(i=0; i<used; i++) WLog_ERR(TAG, "%2"PRIdz": %s", i, msg[i]); } free (msg); winpr_backtrace_free(stack); } #endif /** * Note: unfortunately we may not return FALSE here since CloseHandle(hmutex) on * Windows always seems to succeed independently of the mutex object locking state */ } free(handle); return TRUE; }
VOID DumpThreadHandles(void) { char** msg; size_t used, i; void* stack = winpr_backtrace(20); WLog_DBG(TAG, "---------------- Called from ----------------------------"); msg = winpr_backtrace_symbols(stack, &used); for (i = 0; i < used; i++) { WLog_DBG(TAG, "[%d]: %s", i, msg[i]); } free(msg); winpr_backtrace_free(stack); WLog_DBG(TAG, "---------------- Start Dumping thread handles -----------"); if (!thread_list) { WLog_DBG(TAG, "All threads properly shut down and disposed of."); } else { ULONG_PTR* keys = NULL; ListDictionary_Lock(thread_list); int x, count = ListDictionary_GetKeys(thread_list, &keys); WLog_DBG(TAG, "Dumping %d elements", count); for (x = 0; x < count; x++) { WINPR_THREAD* thread = ListDictionary_GetItemValue(thread_list, (void*) keys[x]); WLog_DBG(TAG, "Thread [%d] handle created still not closed!", x); msg = winpr_backtrace_symbols(thread->create_stack, &used); for (i = 0; i < used; i++) { WLog_DBG(TAG, "[%d]: %s", i, msg[i]); } free(msg); if (thread->started) { WLog_DBG(TAG, "Thread [%d] still running!", x); } else { WLog_DBG(TAG, "Thread [%d] exited at:", x); msg = winpr_backtrace_symbols(thread->exit_stack, &used); for (i = 0; i < used; i++) WLog_DBG(TAG, "[%d]: %s", i, msg[i]); free(msg); } } free(keys); ListDictionary_Unlock(thread_list); } WLog_DBG(TAG, "---------------- End Dumping thread handles -------------"); }