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; }
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); }
void winpr_backtrace_symbols_fd(void* buffer, int fd) { if (!buffer) { LOGF(support_msg); return; } #if defined(HAVE_EXECINFO_H) t_execinfo* data = (t_execinfo*) buffer; if (!data) return; backtrace_symbols_fd(data->buffer, data->used, fd); #elif defined(_WIN32) || defined(_WIN64) || defined(ANDROID) { DWORD i; size_t used; char** lines; lines = winpr_backtrace_symbols(buffer, &used); if (lines) { for (i = 0; i < used; i++) write(fd, lines[i], strlen(lines[i])); } } #else LOGF(support_msg); #endif }
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; }
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 }
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; }
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); }
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 -------------"); }