Example #1
0
// --------------------------------------------------------------------------
int ctkBackTracePrivate::trace(void** array, size_t n) const
{
    if(n>=63)
        n=62;

    if (s_pfnCaptureStackBackTrace == 0)
    {
        const HMODULE hNtDll = ::GetModuleHandleW(L"ntdll.dll");
        reinterpret_cast<void*&>(s_pfnCaptureStackBackTrace) =
            ::GetProcAddress(hNtDll, "RtlCaptureStackBackTrace");
    }

    if (s_pfnCaptureStackBackTrace != 0) {
        return s_pfnCaptureStackBackTrace(0, n, array, 0);
    }
    return 0;
}
// getStackTrace - Traces the stack as far back as possible, or until 'maxdepth'
//   frames have been traced. Populates the CallStack with one entry for each
//   stack frame traced.
//
//   Note: This function uses a very efficient method to walk the stack from
//     frame to frame, so it is quite fast. However, unconventional stack frames
//     (such as those created when frame pointer omission optimization is used)
//     will not be successfully walked by this function and will cause the
//     stack trace to terminate prematurely.
//
//  - maxdepth (IN): Maximum number of frames to trace back.
//
//  - framepointer (IN): Frame (base) pointer at which to begin the stack trace.
//      If NULL, then the stack trace will begin at this function.
//
//  Return Value:
//
//    None.
//
VOID FastCallStack::getStackTrace (UINT32 maxdepth, const context_t& context)
{
    UINT32  count = 0;
    UINT_PTR* framePointer = context.fp;

#if defined(_M_IX86)
    while (count < maxdepth) {
        if (*framePointer < (UINT_PTR)framePointer) {
            if (*framePointer == NULL) {
                // Looks like we reached the end of the stack.
                break;
            }
            else {
                // Invalid frame pointer. Frame pointer addresses should always
                // increase as we move up the stack.
                m_status |= CALLSTACK_STATUS_INCOMPLETE;
                break;
            }
        }
        if (*framePointer & (sizeof(UINT_PTR*) - 1)) {
            // Invalid frame pointer. Frame pointer addresses should always
            // be aligned to the size of a pointer. This probably means that
            // we've encountered a frame that was created by a module built with
            // frame pointer omission (FPO) optimization turned on.
            m_status |= CALLSTACK_STATUS_INCOMPLETE;
            break;
        }
        if (IsBadReadPtr((UINT*)*framePointer, sizeof(UINT_PTR*))) {
            // Bogus frame pointer. Again, this probably means that we've
            // encountered a frame built with FPO optimization.
            m_status |= CALLSTACK_STATUS_INCOMPLETE;
            break;
        }
        count++;
        push_back(*(framePointer + 1));
        framePointer = (UINT_PTR*)*framePointer;
    }
#elif defined(_M_X64)
    UINT32 maxframes = min(62, maxdepth + 10);
    static USHORT (WINAPI *s_pfnCaptureStackBackTrace)(ULONG FramesToSkip, ULONG FramesToCapture, PVOID* BackTrace, PULONG BackTraceHash) = 0;  
    if (s_pfnCaptureStackBackTrace == 0)  
    {  
        const HMODULE hNtDll = GetModuleHandleW(L"ntdll.dll");  
        reinterpret_cast<void*&>(s_pfnCaptureStackBackTrace)
            = ::GetProcAddress(hNtDll, "RtlCaptureStackBackTrace");
        if (s_pfnCaptureStackBackTrace == 0)  
            return;
    }
    UINT_PTR* myFrames = new UINT_PTR[maxframes];
    ZeroMemory(myFrames, sizeof(UINT_PTR) * maxframes);
    s_pfnCaptureStackBackTrace(0, maxframes, (PVOID*)myFrames, NULL);
    UINT32  startIndex = 0;
    while (count < maxframes) {
        if (myFrames[count] == 0)
            break;
        if (myFrames[count] == *(framePointer + 1))
            startIndex = count;
        count++;
    }
    count = startIndex;
    while (count < maxframes) {
        if (myFrames[count] == 0)
            break;
        push_back(myFrames[count]);
        count++;
    }
    delete [] myFrames;
#endif
}
Example #3
0
	xgc_void GetStackTrace( StackFrameSequence& FrameSequence )
	{
		UINT_PTR* fp = (UINT_PTR*) _AddressOfReturnAddress();
		UINT_PTR* framePointer = (UINT_PTR*) fp - 1;

		FrameSequence.Count = 0;

	#if defined(_M_IX86)
		while ( FrameSequence.Count < MAX_FRAME_SAVE) {
			if (*framePointer < (UINT_PTR)framePointer) {
				if (*framePointer == NULL) {
					// Looks like we reached the end of the stack.
					break;
				}
				else {
					// Invalid frame pointer. Frame pointer addresses should always
					// increase as we move up the stack.
					break;
				}
			}
			if (*framePointer & (sizeof(UINT_PTR*) - 1)) {
				// Invalid frame pointer. Frame pointer addresses should always
				// be aligned to the size of a pointer. This probably means that
				// we've encountered a frame that was created by a module built with
				// frame pointer omission (FPO) optimization turned on.
				break;
			}
			if (IsBadReadPtr((UINT*)*framePointer, sizeof(UINT_PTR*))) {
				// Bogus frame pointer. Again, this probably means that we've
				// encountered a frame built with FPO optimization.
				break;
			}
			//push_back(*(framePointer + 1));
			FrameSequence.Frame[ FrameSequence.Count ] = *(framePointer + 1);
			FrameSequence.Count += 1;
			framePointer = (UINT_PTR*)*framePointer;
		}
	#elif defined(_M_X64)
		xgc_uint32 maxframes = XGC_MIN( 62, MAX_FRAME_SAVE + 10 );
		static USHORT( WINAPI *s_pfnCaptureStackBackTrace )( ULONG FramesToSkip, ULONG FramesToCapture, PVOID* BackTrace, PULONG BackTraceHash ) = 0;
		if( s_pfnCaptureStackBackTrace == 0 )
		{
			const HMODULE hNtDll = GetModuleHandleW( L"ntdll.dll" );
			reinterpret_cast<void*&>( s_pfnCaptureStackBackTrace )
				= ::GetProcAddress( hNtDll, "RtlCaptureStackBackTrace" );
			if( s_pfnCaptureStackBackTrace == 0 )
				return;
		}
		UINT_PTR* myFrames = XGC_NEW UINT_PTR[maxframes];
		ZeroMemory( myFrames, sizeof( UINT_PTR ) * maxframes );
		s_pfnCaptureStackBackTrace( 0, maxframes, (PVOID*) myFrames, NULL );
		xgc_uint32  startIndex = 0;
		xgc_uint32 count = 0;
		while( count < maxframes )
		{
			if( myFrames[count] == 0 )
				break;
			if( myFrames[count] == *( framePointer + 1 ) )
				startIndex = count;
			count++;
		}
		FrameSequence.Count = 0;
		while( 
			FrameSequence.Count < maxframes && 
			FrameSequence.Count < XGC_COUNTOF( FrameSequence.Frame ) )
		{
			if( myFrames[FrameSequence.Count] == 0 )
				break;
			//push_back(myFrames[count]);
			FrameSequence.Frame[FrameSequence.Count] = (void*)myFrames[startIndex + FrameSequence.Count];
			FrameSequence.Count += 1;
		}
		delete[] myFrames;
	#endif
	}