Exemplo n.º 1
0
VOID
BtrUninitializeStack(
	VOID
	)
{
	PLIST_ENTRY ListEntry;
	PLIST_ENTRY ListHead;
	PBTR_STACK_PAGE Page;

	//
	// Close stack file
	//

	BtrCloseStackFile();

	//
	// N.B. BtrFlushStackRecord() can not be called after this routine
	//

	ListHead = &BtrStackPageRetireList;

	__try {

		while (IsListEmpty(ListHead) != TRUE) {
			ListEntry = RemoveHeadList(ListHead);
			Page = CONTAINING_RECORD(ListEntry, BTR_STACK_PAGE, ListEntry);
			VirtualFree(Page, 0, MEM_RELEASE);
		}

		if (BtrStackPageFree != NULL) {
			VirtualFree(BtrStackPageFree, 0, MEM_RELEASE);
		}
	}

	__except(EXCEPTION_EXECUTE_HANDLER) {
	}

	__try {
		BtrDeleteLock(&BtrStackPageLock);
	}

	__except(EXCEPTION_EXECUTE_HANDLER) {
	}

}
Exemplo n.º 2
0
ULONG
BtrUnloadRuntime(
	VOID
	)
{
	PBTR_THREAD Thread;
	LIST_ENTRY ListHead;
	PLIST_ENTRY ListEntry;
	LIST_ENTRY RangeListHead;
	LIST_ENTRY PendingListHead;
	LIST_ENTRY CompleteListHead;
	PBTR_ADDRESS_RANGE Range;

	//
	// Scan pending thread list, note that we only need scan once,
	// because all probes are unregistered, new thread don't get
	// a chance to enter runtime.
	//
	
	BtrAcquireLock(&BtrThreadLock);
	BtrScanPendingThreads(&PendingListHead, &CompleteListHead);
	BtrReleaseLock(&BtrThreadLock);

	//
	// Repeatly query until all pending frames are completed, in some
	// special cases, this will run forever, e.g. a thread is probing
	// a top level routine, which is always pending before the thread exit, 
	// we have no chance to immediately unload runtime in this case,
	// technically we have method to walk the stack frame and hijack
	// its return address, but it's very complicated to do so, it's after
	// all a rare case.
	//

	while (IsListEmpty(&PendingListHead) != TRUE) {

		ListEntry = RemoveHeadList(&PendingListHead);
		Thread = CONTAINING_RECORD(ListEntry, BTR_THREAD, ListEntry);

		if (BtrIsPendingFrameExist(Thread)) {
			InsertTailList(&PendingListHead, &Thread->ListEntry);
			Sleep(1000);

		} else {
			InsertTailList(&CompleteListHead, &Thread->ListEntry);
		}
	}

	//
	// Close left threads' file and mapping objects.
	//

	while (IsListEmpty(&CompleteListHead) != TRUE) {

		ListEntry = RemoveHeadList(&CompleteListHead);
		Thread = CONTAINING_RECORD(ListEntry, BTR_THREAD, ListEntry);

		BtrCloseMappingPerThread(Thread);

		if (Thread->RundownHandle != NULL) {

			if (BtrIsThreadTerminated(Thread)) {
				//
				// do nothing, don't worry dirty stack since its deallocated.
				//
			} else {
				BtrClearThreadStack(Thread);
			}
			CloseHandle(Thread->RundownHandle);

		} else {

			//
			// Without rundown handle, we in fact don't know thread state,
			// we have to clear its stack cookie, this is a rare rare case,
			// I never see it till now.
			//

			BtrClearThreadStack(Thread);
		}
	}

	//
	// Ensure all threads are not executing trap code, not executing
	// runtime code
	//

	InitializeListHead(&RangeListHead);

	ListEntry = BtrTrapPageList.Flink;
	while (ListEntry != &BtrTrapPageList) {

		PBTR_TRAP_PAGE Page;
		Page = CONTAINING_RECORD(ListEntry, BTR_TRAP_PAGE, ListEntry);	

		Range = BtrMalloc(sizeof(BTR_ADDRESS_RANGE));
		Range->Address = (ULONG_PTR)Page->StartVa;
		Range->Size = (ULONG_PTR)Page->EndVa - (ULONG_PTR)Page->StartVa;
		InsertTailList(&RangeListHead, &Range->ListEntry);

		ListEntry = ListEntry->Flink;
	}

	//
	// Append runtime address range, note that we don't need check filter
	// address, because there's no pending frame, so the thread pc can not
	// be possible in address range of filters.
	//

	Range = BtrMalloc(sizeof(BTR_ADDRESS_RANGE));
	Range->Address = BtrDllBase;
	Range->Size = BtrDllSize; 
	InsertHeadList(&RangeListHead, &Range->ListEntry);

	InitializeListHead(&ListHead);
	
	while (BtrSuspendProcess(&ListHead) != S_OK) {
		SwitchToThread();
	}

	while (BtrIsExecutingAddress(&ListHead, &RangeListHead)) {
		BtrResumeProcess(&ListHead);
		Sleep(5000);
		BtrSuspendProcess(&ListHead);
	}

	BtrResumeProcess(&ListHead);

	BtrDeleteLock(&BtrThreadLock);

	//
	// Unload all registered filters
	//

	BtrUnregisterFilters();
	
	//
	// Free trap page list, note that this must be done before
	// heap destroy because trap page's bitmap object is allocated
	// from normal heap.
	//

	BtrUninitializeTrap();
	BtrUninitializeProbe();
	BtrUninitializeCounter();
	BtrUninitializeStackTrace();
	BtrUninitializeCache();
	BtrUninitializeHal();
	BtrUninitializeMm();
	
	if (FlagOn(BtrFeatures, FeatureRemote)) {
		BtrExecuteUnloadRoutine();
		ExitThread(0);

		//
		// never reach here
		//
	}

	//
	// local mode, return here
	//

	return S_OK;
}
Exemplo n.º 3
0
ULONG
BtrWriteMarkStream(
	__in PPF_REPORT_HEAD Head,
	__in HANDLE FileHandle,
	__in LARGE_INTEGER Start,
	__out PLARGE_INTEGER End
	)
{
	ULONG Count;
	ULONG Size;
	ULONG Complete;
	ULONG Status;
	PBTR_MARK Mark;
	PBTR_MARK Entry;
	PLIST_ENTRY ListEntry;

	ASSERT(BtrMarkCount != 0);
	ASSERT(!IsListEmpty(&BtrMarkList));

	Count = 0;
	Size = sizeof(BTR_MARK) * BtrMarkCount;
	Mark = (PBTR_MARK)BtrMalloc(Size);

	BtrAcquireLock(&BtrMarkLock);

	//
	// Serialize all marks into stream in memory 
	//

	while (!IsListEmpty(&BtrMarkList)) {

		ListEntry = RemoveHeadList(&BtrMarkList);
		Entry = CONTAINING_RECORD(ListEntry, BTR_MARK, ListEntry);

		Mark[Count] = *Entry;
		BtrFree(Entry);

		Count += 1;
	}

	//
	// Verify mark count match
	//

	ASSERT(Count == BtrMarkCount);
	BtrMarkCount = 0;

	BtrReleaseLock(&BtrMarkLock);

	//
	// Write mark stream to file
	//

	Status = WriteFile(FileHandle, Mark, Size, &Complete, NULL);
	if (Status != TRUE) {
		Status = GetLastError();
	} else {
		End->QuadPart = Start.QuadPart + Size;
		Status = S_OK;
	}

	BtrFree(Mark);

	//
	// Destroy mark lock
	//

	BtrDeleteLock(&BtrMarkLock);
	return Status;
}