예제 #1
0
파일: Profile.cpp 프로젝트: Gallaecio/0ad
void* calloc(size_t nm, size_t sz)
{
	cpu_AtomicAdd(&alloc_count, 1);

	static void *(*libc_calloc)(size_t, size_t);
	if (libc_calloc == NULL)
	{
		if (alloc_has_called_dlsym && !alloc_bootstrapped)
		{
			ENSURE(nm*sz <= ARRAY_SIZE(alloc_bootstrap_buffer));
#ifdef ALLOC_DEBUG
			printf("### calloc-bs(%d, %d) = %p\n", nm, sz, alloc_bootstrap_buffer);
#endif
			alloc_bootstrapped = true;
			return alloc_bootstrap_buffer;
		}
		alloc_has_called_dlsym = true;
		libc_calloc = (void *(*)(size_t, size_t)) dlsym(RTLD_NEXT, "calloc");
	}
	void* ret = libc_calloc(nm, sz);
#ifdef ALLOC_DEBUG
	printf("### calloc(%d, %d) = %p\n", nm, sz, ret);
#endif
	return ret;
}
예제 #2
0
파일: wseh.cpp 프로젝트: krichter722/0ad
// called when an exception is detected (see below); provides detailed
// debugging information and exits.
//
// note: keep memory allocs and locking to an absolute minimum, because
// they may deadlock the process!
long __stdcall wseh_ExceptionFilter(struct _EXCEPTION_POINTERS* ep)
{
	// OutputDebugString raises an exception, which OUGHT to be swallowed
	// by WaitForDebugEvent but sometimes isn't. if we see it, ignore it.
	if(ep->ExceptionRecord->ExceptionCode == 0x40010006)	// DBG_PRINTEXCEPTION_C
		return EXCEPTION_CONTINUE_EXECUTION;

	// if run in a debugger, let it handle exceptions (tends to be more
	// convenient since it can bring up the crash location)
	if(IsDebuggerPresent())
		return EXCEPTION_CONTINUE_SEARCH;

	// make sure we don't recurse infinitely if this function raises an
	// SEH exception. (we may only have the guard page's 4 KB worth of
	// stack space if the exception is EXCEPTION_STACK_OVERFLOW)
	static intptr_t nestingLevel = 0;
	cpu_AtomicAdd(&nestingLevel, 1);
	if(nestingLevel >= 3)
		return EXCEPTION_CONTINUE_SEARCH;

	// someone is already holding the dbghelp lock - this is bad.
	// we'll report this problem first and then try to display the
	// exception info regardless (maybe dbghelp won't blow up).
	if(wutil_IsLocked(WDBG_SYM_CS) == 1)
		DEBUG_DISPLAY_ERROR(L"Exception raised while critical section is held - may deadlock..");

	// a dump file is essential for debugging, so write it before
	// anything else goes wrong (especially before showing the error
	// dialog because the user could choose to exit immediately)
	wdbg_sym_WriteMinidump(ep);

	// extract details from ExceptionRecord.
	wchar_t descriptionBuf[150];
	const wchar_t* description = GetExceptionDescription(ep, descriptionBuf, ARRAY_SIZE(descriptionBuf));
	wchar_t file[DEBUG_FILE_CHARS] = {0};
	int line = 0;
	wchar_t func[DEBUG_SYMBOL_CHARS] = {0};
	GetExceptionLocus(ep, file, &line, func);

	wchar_t message[500];
	const wchar_t* messageFormat =
		L"Much to our regret we must report the program has encountered an error.\r\n"
		L"\r\n"
		L"Please let us know at http://trac.wildfiregames.com/ and attach the crashlog.txt and crashlog.dmp files.\r\n"
		L"\r\n"
		L"Details: unhandled exception (%ls)\r\n";
	swprintf_s(message, ARRAY_SIZE(message), messageFormat, description);

	size_t flags = 0;
	if(ep->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
		flags = DE_NO_CONTINUE;
	const wchar_t* const lastFuncToSkip = WIDEN(STRINGIZE(DECORATED_NAME(wseh_ExceptionFilter)));
	ErrorReaction er = debug_DisplayError(message, flags, ep->ContextRecord, lastFuncToSkip, file,line,utf8_from_wstring(func).c_str(), 0);
	ENSURE(er == ER_CONTINUE);	// nothing else possible

	// invoke the Win32 default handler - it calls ExitProcess for
	// most exception types.
	return EXCEPTION_CONTINUE_SEARCH;
}
예제 #3
0
	void Deallocate(OVERLAPPED* ovl)
	{
		cpu_AtomicAdd(&extant, -1);

		const uintptr_t address = uintptr_t(ovl);
		ENSURE(uintptr_t(storage) <= address && address < uintptr_t(storage)+storageSize);
		InterlockedPushEntrySList(&freelist, (PSLIST_ENTRY)(address - offsetof(Entry, ovl)));
	}
예제 #4
0
IdxDeleter AddUniqueRangeDeleter(UniqueRangeDeleter deleter)
{
	ENSURE(deleter);
	IdxDeleter idxDeleter = cpu_AtomicAdd(&numDeleters, 1);
	ENSURE(idxDeleter < (IdxDeleter)ARRAY_SIZE(deleters));
	deleters[idxDeleter] = deleter;
	return idxDeleter;
}
예제 #5
0
파일: Profile.cpp 프로젝트: Gallaecio/0ad
void* realloc(void* ptr, size_t sz)
{
	cpu_AtomicAdd(&alloc_count, 1);

	static void *(*libc_realloc)(void*, size_t);
	if (libc_realloc == NULL)
	{
		alloc_has_called_dlsym = true;
		libc_realloc = (void *(*)(void*, size_t)) dlsym(RTLD_NEXT, "realloc");
	}
	void* ret = libc_realloc(ptr, sz);
#ifdef ALLOC_DEBUG
	printf("### realloc(%p, %d) = %p\n", ptr, sz, ret);
#endif
	return ret;
}
예제 #6
0
	// @return OVERLAPPED initialized for I/O starting at offset,
	// or 0 if all available structures have already been allocated.
	OVERLAPPED* Allocate(off_t offset)
	{
		Entry* entry = (Entry*)InterlockedPopEntrySList(&freelist);
		if(!entry)
			return 0;

		OVERLAPPED& ovl = entry->ovl;
		ovl.Internal = 0;
		ovl.InternalHigh = 0;
		ovl.Offset = u64_lo(offset);
		ovl.OffsetHigh = u64_hi(offset);
		ovl.hEvent = 0;	// (notification is via IOCP and/or polling)

		cpu_AtomicAdd(&extant, +1);

		return &ovl;
	}
예제 #7
0
// NB: callers should skip this if *idxDeleterOut != 0 (avoids the overhead
// of an unnecessary indirect function call)
void RegisterUniqueRangeDeleter(UniqueRangeDeleter deleter, volatile IdxDeleter* idxDeleterOut)
{
	ENSURE(deleter);

	if(!cpu_CAS(idxDeleterOut, idxDeleterNone, -1))	// not the first call for this deleter
	{
		// wait until an index has been assigned
		while(*idxDeleterOut <= 0)
			cpu_Pause();
		return;
	}

	const IdxDeleter idxDeleter = cpu_AtomicAdd(&numDeleters, 1);
	ENSURE(idxDeleter < (IdxDeleter)ARRAY_SIZE(deleters));
	deleters[idxDeleter] = deleter;
	COMPILER_FENCE;
	*idxDeleterOut = idxDeleter;
}
예제 #8
0
파일: Profile.cpp 프로젝트: righnatios/0ad
void* malloc(size_t sz)
{
	cpu_AtomicAdd(&alloc_count, 1);

	static void *(*libc_malloc)(size_t);
	if (libc_malloc == NULL)
	{
		alloc_has_called_dlsym = true;
		libc_malloc = (void *(*)(size_t)) dlsym(RTLD_NEXT, "malloc");
	}
	void* ret = libc_malloc(sz);
#ifdef ALLOC_DEBUG
	printf("### malloc(%d) = %p\n", sz, ret);
#endif

	if (libc_free == NULL)
		libc_free = (void (*)(void*)) dlsym(RTLD_NEXT, "free");

	return ret;
}
예제 #9
0
파일: wvm.cpp 프로젝트: Gallaecio/0ad
	void NotifySmallPageCommit()
	{
		cpu_AtomicAdd(&smallPageCommits, +1);
	}