Beispiel #1
0
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);
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
VOID ExitThread(DWORD dwExitCode)
{
	DWORD rc;
	pthread_t tid = pthread_self();

	if (!thread_list)
	{
		WLog_ERR(TAG, "function called without existing thread list!");
#if defined(WITH_DEBUG_THREADS)
		DumpThreadHandles();
#endif
		pthread_exit(0);
	}
	else if (!ListDictionary_Contains(thread_list, &tid))
	{
		WLog_ERR(TAG, "function called, but no matching entry in thread list!");
#if defined(WITH_DEBUG_THREADS)
		DumpThreadHandles();
#endif
		pthread_exit(0);
	}
	else
	{
		WINPR_THREAD* thread;

		ListDictionary_Lock(thread_list);
		thread = ListDictionary_GetItemValue(thread_list, &tid);

		assert(thread);
		thread->exited = TRUE;
		thread->dwExitCode = dwExitCode;
#if defined(WITH_DEBUG_THREADS)
		thread->exit_stack = winpr_backtrace(20);
#endif
		ListDictionary_Unlock(thread_list);
		set_event(thread);

		rc = thread->dwExitCode;
		if (thread->detached || !thread->started)
			cleanup_handle(thread);

		pthread_exit((void*) (size_t) rc);
	}
}
Beispiel #6
0
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
}
Beispiel #7
0
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);
}
Beispiel #8
0
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;
}
Beispiel #9
0
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 -------------");
}
Beispiel #10
0
HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,
                    SIZE_T dwStackSize,
                    LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter,
                    DWORD dwCreationFlags, LPDWORD lpThreadId)
{
	HANDLE handle;
	WINPR_THREAD* thread;
	thread = (WINPR_THREAD*) calloc(1, sizeof(WINPR_THREAD));

	if (!thread)
		return NULL;

	thread->dwStackSize = dwStackSize;
	thread->lpParameter = lpParameter;
	thread->lpStartAddress = lpStartAddress;
	thread->lpThreadAttributes = lpThreadAttributes;
	thread->ops = &ops;
#if defined(WITH_DEBUG_THREADS)
	thread->create_stack = winpr_backtrace(20);
	dump_thread(thread);
#endif
	thread->pipe_fd[0] = -1;
	thread->pipe_fd[1] = -1;
#ifdef HAVE_EVENTFD_H
	thread->pipe_fd[0] = eventfd(0, EFD_NONBLOCK);

	if (thread->pipe_fd[0] < 0)
	{
		WLog_ERR(TAG, "failed to create thread pipe fd 0");
		goto error_pipefd0;
	}

#else

	if (pipe(thread->pipe_fd) < 0)
	{
		WLog_ERR(TAG, "failed to create thread pipe");
		goto error_pipefd0;
	}

	{
		int flags = fcntl(thread->pipe_fd[0], F_GETFL);
		fcntl(thread->pipe_fd[0], F_SETFL, flags | O_NONBLOCK);
	}

#endif

	if (pthread_mutex_init(&thread->mutex, 0) != 0)
	{
		WLog_ERR(TAG, "failed to initialize thread mutex");
		goto error_mutex;
	}

	if (pthread_mutex_init(&thread->threadIsReadyMutex, NULL) != 0)
	{
		WLog_ERR(TAG, "failed to initialize a mutex for a condition variable");
		goto error_thread_ready_mutex;
	}

	if (pthread_cond_init(&thread->threadIsReady, NULL) != 0)
	{
		WLog_ERR(TAG, "failed to initialize a condition variable");
		goto error_thread_ready;
	}

	WINPR_HANDLE_SET_TYPE_AND_MODE(thread, HANDLE_TYPE_THREAD, WINPR_FD_READ);
	handle = (HANDLE) thread;

	if (!thread_list)
	{
		thread_list = ListDictionary_New(TRUE);

		if (!thread_list)
		{
			WLog_ERR(TAG, "Couldn't create global thread list");
			goto error_thread_list;
		}

		thread_list->objectKey.fnObjectEquals = thread_compare;
	}

	if (!(dwCreationFlags & CREATE_SUSPENDED))
	{
		if (!winpr_StartThread(thread))
			goto error_thread_list;
	}
	else
	{
		if (!set_event(thread))
			goto error_thread_list;
	}

	return handle;
error_thread_list:
	pthread_cond_destroy(&thread->threadIsReady);
error_thread_ready:
	pthread_mutex_destroy(&thread->threadIsReadyMutex);
error_thread_ready_mutex:
	pthread_mutex_destroy(&thread->mutex);
error_mutex:

	if (thread->pipe_fd[1] >= 0)
		close(thread->pipe_fd[1]);

	if (thread->pipe_fd[0] >= 0)
		close(thread->pipe_fd[0]);

error_pipefd0:
	free(thread);
	return NULL;
}