示例#1
0
void StackAnalyzer::analyze() {
	std::vector<void *> buffer{64};
	auto count = RtlCaptureStackBackTrace(base_skip_frames, buffer.size(), buffer.data(), NULL);
	if (count < buffer.size()) {
		buffer.resize(count);
	}
	this->stack_addrs = std::move(buffer);
}
示例#2
0
文件: backtrace.cpp 项目: K-ballo/hpx
        HPX_API_EXPORT std::size_t trace(void **array,std::size_t n)
        {
#if _WIN32_WINNT < 0x0600
            // for Windows XP/Windows Server 2003
            if(n>=63)
                n=62;
#endif
            return RtlCaptureStackBackTrace(ULONG(0),ULONG(n),array,nullptr);
        }
示例#3
0
文件: backtrace.cpp 项目: adk9/hpx
        HPX_BACKTRACE_DECL std::size_t trace(void **array,std::size_t n)
        {
#if _WIN32_WINNT < 0x0600
            // for Windows XP/Windows Server 2003
            if(n>=63)
                n=62;
#endif
            return RtlCaptureStackBackTrace(ULONG(0),ULONG(n),array,NULL);
        }
示例#4
0
void WTFGetBacktrace(void** stack, int* size)
{
#if OS(DARWIN) || (OS(LINUX) && defined(__GLIBC__) && !defined(__UCLIBC__))
    *size = backtrace(stack, *size);
#elif OS(WINDOWS)
    *size = RtlCaptureStackBackTrace(0, *size, stack, 0);
#else
    *size = 0;
#endif
}
示例#5
0
void
dtrace_getpcstack(pc_t *pcstack, int pcstack_limit, int aframes, uint32_t *intrpc)
{
	int depth = 0;
	uintptr_t ebp;
	struct frame *frame;
	uintptr_t callpc;
	pc_t caller = (pc_t) CPU[KeGetCurrentProcessorNumber()].cpu_dtrace_caller;
	CONTEXT Context;
#if defined(__i386__) || !defined(windows)
	thread_t *td = curthread;
	
	if (intrpc != 0)
		pcstack[depth++] = (pc_t) intrpc;
		
	aframes++;
	ebp = td->ebp;

	frame = (struct frame *)ebp;
	while (depth < pcstack_limit) {
		if ((uintptr_t)frame < td->klimit || (uintptr_t) ((char *) frame - sizeof(struct frame)) >= td->kbase)
			break;

		callpc = frame->f_retaddr;
		
		if (!INKERNEL(callpc))
			break;

		if (aframes > 0) {
			aframes--;
			if ((aframes == 0) && (caller != 0)) {
				pcstack[depth++] = caller;
			}
		}
		else {
			pcstack[depth++] = callpc;
		}

		frame = frame->f_frame;
	}
#else // windows and amd64
 	depth += RtlCaptureStackBackTrace(aframes, pcstack_limit, (PVOID) pcstack, NULL);
#endif
	for (; depth < pcstack_limit; depth++) {
		pcstack[depth] = 0;
	}
}
示例#6
0
void Win32Callstack::Collect()
{
  std::vector<PVOID> stack32;

  stack32.resize(64);

  USHORT num = RtlCaptureStackBackTrace(0, 63, &stack32[0], NULL);

  stack32.resize(num);

  while(!stack32.empty() && (uint64_t)stack32[0] >= (uint64_t)renderdocBase &&
        (uint64_t)stack32[0] <= (uint64_t)renderdocBase + renderdocSize)
  {
    stack32.erase(stack32.begin());
  }

  m_AddrStack.resize(stack32.size());
  for(size_t i = 0; i < stack32.size(); i++)
    m_AddrStack[i] = (DWORD64)stack32[i];
}
示例#7
0
文件: except.c 项目: RPG-7/reactos
/*
 * @implemented
 */
VOID
NTAPI
RtlGetCallersAddress(OUT PVOID *CallersAddress,
                     OUT PVOID *CallersCaller)
{
    USHORT FrameCount;
    PVOID  BackTrace[2];
    PULONG BackTraceHash = NULL;

    /* Get the tow back trace address */
    FrameCount = RtlCaptureStackBackTrace(2, 2, &BackTrace[0],BackTraceHash);

    /* Only if user want it */
    if (*CallersAddress != NULL)
    {
        /* only when first frames exist */
        if (FrameCount >= 1)
        {
            *CallersAddress = BackTrace[0];
        }
        else
        {
            *CallersAddress = NULL;
        }
    }

    /* Only if user want it */
    if (*CallersCaller != NULL)
    {
        /* only when second frames exist */
        if (FrameCount >= 2)
        {
            *CallersCaller = BackTrace[1];
        }
        else
        {
            *CallersCaller = NULL;
        }
    }
}
示例#8
0
static NTSTATUS
DebugRegister(
    IN  PXENBUS_DEBUG_CONTEXT   Context,
    IN  const CHAR              *Prefix,
    IN  VOID                    (*Function)(PVOID, BOOLEAN),
    IN  PVOID                   Argument OPTIONAL,
    OUT PXENBUS_DEBUG_CALLBACK  *Callback
    )
{
    ULONG                       Length;
    KIRQL                       Irql;
    NTSTATUS                    status;

    *Callback = __DebugAllocate(sizeof (XENBUS_DEBUG_CALLBACK));

    status = STATUS_NO_MEMORY;
    if (*Callback == NULL)
        goto fail1;

    (VOID) RtlCaptureStackBackTrace(1, 1, &(*Callback)->Caller, NULL);    

    Length = (ULONG)__min(strlen(Prefix), MAXIMUM_PREFIX_LENGTH - 1);
    RtlCopyMemory((*Callback)->Prefix, Prefix, Length);

    (*Callback)->Function = Function;
    (*Callback)->Argument = Argument;

    AcquireHighLock(&Context->Lock, &Irql);
    InsertTailList(&Context->List, &(*Callback)->ListEntry);
    ReleaseHighLock(&Context->Lock, Irql);

    return STATUS_SUCCESS;

fail1:
    Error("fail1 (%08x)\n", status);

    return status;
}
示例#9
0
int
dtrace_getstackdepth(int aframes)
{
	int depth = 0;
	struct frame *frame;
	uintptr_t ebp;
	uintptr_t callpc;
	thread_t *td = curthread;
#if defined(windows)
	int pcstack_limit = 100;
	uint64_t pcstack[100];
#endif
	ebp = td->ebp;
	frame = (struct frame *)ebp;
	depth++;
	
#ifdef __amd64
	depth += RtlCaptureStackBackTrace(0, pcstack_limit, (PVOID) pcstack, NULL);
#else
	for(;;) {
		if ((uintptr_t)frame < td->klimit || 
		    (uintptr_t) ((char *) frame - sizeof(struct frame)) >= td->kbase)
			break;
		depth++;
		callpc = frame->f_retaddr;
		
		if (!INKERNEL(callpc))
			break;

		frame = frame->f_frame;
	}
#endif
	if (depth < aframes)
		return 0;
	else
		return depth - aframes;
}
示例#10
0
文件: bug.c 项目: RPG-7/reactos
VOID
NTAPI
KeRosDumpStackFrames(IN PULONG_PTR Frame OPTIONAL,
                     IN ULONG FrameCount OPTIONAL)
{
    ULONG_PTR Frames[32];
    ULONG RealFrameCount;

    /* If the caller didn't ask, assume 32 frames */
    if (!FrameCount || FrameCount > 32) FrameCount = 32;

    if (Frame)
    {
        /* Dump them */
        KeRosDumpStackFrameArray(Frame, FrameCount);
    }
    else
    {
        /* Get the current frames (skip the two. One for the dumper, one for the caller) */
        RealFrameCount = RtlCaptureStackBackTrace(2, FrameCount, (PVOID*)Frames, NULL);
        DPRINT1("RealFrameCount =%lu\n", RealFrameCount);

        /* Dump them */
        KeRosDumpStackFrameArray(Frames, RealFrameCount);

        /* Count left for user mode? */
        if (FrameCount - RealFrameCount > 0)
        {
            /* Get the current frames */
            RealFrameCount = KeRosCaptureUserStackBackTrace(-1, FrameCount - RealFrameCount, (PVOID*)Frames, NULL);

            /* Dump them */
            KeRosDumpStackFrameArray(Frames, RealFrameCount);
        }
    }
}
示例#11
0
文件: stktrace.c 项目: mingpen/OpenNT
VOID
RtlGetCallersAddress(
    OUT PVOID *CallersAddress,
    OUT PVOID *CallersCaller
    )
/*++

Routine Description:

    This routine returns the first to callers on the current stack. It should be
    noted that the function can miss some of the callers in the presence of FPO
    optimization.

Arguments:

    CallersAddress - address to save the first caller.
    
    CallersCaller - address to save the second caller.

Return Value:

    None. If the function does not succeed in finding the two callers
    it will zero the addresses where it was supposed to write them.

Environment:

    X86, user mode and w/o having a macro with same name defined.

--*/

{
    PVOID BackTrace[ 2 ];
    ULONG Hash;
    USHORT Count;

    Count = RtlCaptureStackBackTrace(
        2,
        2,
        BackTrace,
        &Hash
        );

    if (ARGUMENT_PRESENT( CallersAddress )) {
        if (Count >= 1) {
            *CallersAddress = BackTrace[ 0 ];
        }
        else {
            *CallersAddress = NULL;
        }
    }

    if (ARGUMENT_PRESENT( CallersCaller )) {
        if (Count >= 2) {
            *CallersCaller = BackTrace[ 1 ];
        }
        else {
            *CallersCaller = NULL;
        }
    }

    return;
}
示例#12
0
/**
 * Allocates a object.
 *
 * \param Object A variable which receives a pointer to the newly allocated object.
 * \param ObjectSize The size of the object.
 * \param Flags A combination of flags specifying how the object is to be allocated.
 * \li \c PHOBJ_RAISE_ON_FAIL An exception will be raised if the object cannot be
 * allocated.
 * \param ObjectType The type of the object.
 */
__mayRaise NTSTATUS PhCreateObject(
    __out PVOID *Object,
    __in SIZE_T ObjectSize,
    __in ULONG Flags,
    __in PPH_OBJECT_TYPE ObjectType
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PPH_OBJECT_HEADER objectHeader;

#ifdef PHOBJ_STRICT_CHECKS
    /* Check the flags. */
    if ((Flags & PHOBJ_VALID_FLAGS) != Flags) /* Valid flag mask */
    {
        status = STATUS_INVALID_PARAMETER_3;
    }
#else
    assert(!((Flags & PHOBJ_VALID_FLAGS) != Flags));
#endif

#ifdef PHOBJ_STRICT_CHECKS
    if (NT_SUCCESS(status))
    {
#endif
        /* Allocate storage for the object. Note that this includes
         * the object header followed by the object body. */
        objectHeader = PhpAllocateObject(ObjectType, ObjectSize, Flags);

#ifndef PHOBJ_ALLOCATE_NEVER_NULL
        if (!objectHeader)
            status = STATUS_NO_MEMORY;
#endif
#ifdef PHOBJ_STRICT_CHECKS
    }
#endif

#ifndef PHOBJ_ALLOCATE_NEVER_NULL
    if (!NT_SUCCESS(status))
    {
        if (!(Flags & PHOBJ_RAISE_ON_FAIL))
            return status;
        else
            PhRaiseStatus(status);
    }
#endif

    /* Object type statistics. */
    _InterlockedIncrement((PLONG)&ObjectType->NumberOfObjects);

    /* Initialize the object header. */
    objectHeader->RefCount = 1;
    // objectHeader->Flags is initialized by PhpAllocateObject.
    objectHeader->Size = ObjectSize;
    objectHeader->Type = ObjectType;

    REF_STAT_UP(RefObjectsCreated);

#ifdef DEBUG
    {
        USHORT capturedFrames;

        capturedFrames = RtlCaptureStackBackTrace(1, 16, objectHeader->StackBackTrace, NULL);
        memset(
            &objectHeader->StackBackTrace[capturedFrames],
            0,
            sizeof(objectHeader->StackBackTrace) - capturedFrames * sizeof(PVOID)
            );
    }

    PhAcquireQueuedLockExclusive(&PhDbgObjectListLock);
    InsertTailList(&PhDbgObjectListHead, &objectHeader->ObjectListEntry);
    PhReleaseQueuedLockExclusive(&PhDbgObjectListLock);

    {
        PPH_CREATE_OBJECT_HOOK dbgCreateObjectHook;

        dbgCreateObjectHook = PhDbgCreateObjectHook;

        if (dbgCreateObjectHook)
        {
            dbgCreateObjectHook(
                PhObjectHeaderToObject(objectHeader),
                ObjectSize,
                Flags,
                ObjectType
                );
        }
    }
#endif

    /* Pass a pointer to the object body back to the caller. */
    *Object = PhObjectHeaderToObject(objectHeader);

    return status;
}
示例#13
0
 int trace(void **array,int n)
 {
     if(n>=63)
         n=62;
     return RtlCaptureStackBackTrace(0,n,array,0);
 }
示例#14
0
EASYHOOK_NT_EXPORT LhBarrierCallStackTrace(
            PVOID* OutMethodArray, 
            ULONG InMaxMethodCount,
            ULONG* OutMethodCount)
{
/*
Description:

    Creates a call stack trace and translates all method entries
    back into their owning modules.

Parameters:

    - OutMethodArray

        An array receiving the methods on the call stack.

    - InMaxMethodCount

        The length of the method array. 

    - OutMethodCount

        The actual count of methods on the call stack. This will never
        be greater than 64.

Returns:

    STATUS_NOT_IMPLEMENTED

        Only supported since Windows XP.
*/
    NTSTATUS				NtStatus;
    PVOID					Backup = NULL;

	if(InMaxMethodCount > 64)
		THROW(STATUS_INVALID_PARAMETER_2, L"At maximum 64 modules are supported.");

	if(!IsValidPointer(OutMethodArray, InMaxMethodCount * sizeof(PVOID)))
		THROW(STATUS_INVALID_PARAMETER_1, L"The given module buffer is invalid.");

	if(!IsValidPointer(OutMethodCount, sizeof(ULONG)))
		THROW(STATUS_INVALID_PARAMETER_3, L"Invalid module count storage.");

    FORCE(LhBarrierBeginStackTrace(&Backup));

#ifndef DRIVER
    if(RtlCaptureStackBackTrace == NULL)
        RtlCaptureStackBackTrace = (PROC_RtlCaptureStackBackTrace*)GetProcAddress(hKernel32, "RtlCaptureStackBackTrace");

    if(RtlCaptureStackBackTrace == NULL)
        THROW(STATUS_NOT_IMPLEMENTED, L"This method requires Windows XP or later.");
#endif

    *OutMethodCount = RtlCaptureStackBackTrace(1, 32, OutMethodArray, NULL);

    RETURN;

THROW_OUTRO:
FINALLY_OUTRO:
     {
        if(Backup != NULL)
            LhBarrierEndStackTrace(Backup);

        return NtStatus;
    }
}
示例#15
0
文件: main.cpp 项目: shive/blogpost
    void
    backtrace() {
        static struct sym_t {
            HANDLE proc;
            sym_t() {
                proc = GetCurrentProcess();
                SymSetOptions(
                    SYMOPT_DEFERRED_LOADS | // シンボルを参照する必要があるときまで読み込まない
                    SYMOPT_LOAD_LINES |     // 行番号情報を読み込む
                    SYMOPT_UNDNAME          // すべてのシンボルを装飾されていない形式で表します
                    );
                if(!SymInitialize(proc, 0, true)){
                    throw exception("error : SymInitialize");
                }
                // cout << "<SymInitialize>" << endl;
            }
            ~sym_t() {
                SymCleanup(proc);
                // cout << "<SymCleanup>" << endl;
            }
        } s_sym;

        array<void*,8> addr;
        int count = RtlCaptureStackBackTrace(0, addr.size(), &addr[0], 0);
        cout << "---- BEGIN BACKTRACE ----" << endl;
        for(int Li = 1; Li < count; ++Li){
            auto p = reinterpret_cast<uintptr_t>(addr[Li]);

            IMAGEHLP_MODULE module;
            ::memset(&module, 0, sizeof(module));
            module.SizeOfStruct = sizeof(module);
            if(!SymGetModuleInfo(s_sym.proc, p, &module)){
                throw exception("error : SymGetModuleInfo");
            }

            char buffer[sizeof(IMAGEHLP_SYMBOL) + MAX_PATH];
            ::memset(buffer, 0, sizeof(buffer));
            auto symbol = reinterpret_cast<IMAGEHLP_SYMBOL*>(buffer);
            symbol->SizeOfStruct = sizeof(*symbol);
            symbol->MaxNameLength = MAX_PATH;

            DWORDx disp = 0;
            if(!SymGetSymFromAddr(s_sym.proc, p, &disp, symbol)){
                throw exception("error : SymGetSymFromAddr");
            }
            if(!strcmp(symbol->Name, "__tmainCRTStartup")){
                break;
            }

            string text = "?";
            IMAGEHLP_LINE line;
            ::memset(&line, 0, sizeof(line));
            line.SizeOfStruct = sizeof(line);
            DWORD disp2 = 0;
            if(!SymGetLineFromAddr(s_sym.proc, p, &disp2, &line)){
                line.FileName = "?";
                line.LineNumber = 0;
                text = "?";
            } else {
                text = getline(line.FileName, line.LineNumber);
            }

            cout << Li
                 << " : 0x" << hex << setw(sizeof(uintptr_t) * 2) << setfill('0') << p
                 << " : " << module.ModuleName
                 << " : " << symbol->Name
                 << " : " << line.FileName << "(" << dec << line.LineNumber << ")"
                 << " : " << text.c_str()
                 << endl;
        }
        cout << "---- END BACKTRACE ----" << endl << endl;
    }
示例#16
0
文件: callstack.cpp 项目: viknash/vld
// 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 function = context.func;
    if (function != NULL)
    {
        count++;
        push_back(function);
    }

/*#if defined(_M_IX86)
    UINT_PTR* framePointer = (UINT_PTR*)context.BPREG;
    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);
    UINT_PTR* myFrames = new UINT_PTR[maxframes];
    ZeroMemory(myFrames, sizeof(UINT_PTR) * maxframes);
    ULONG BackTraceHash;
    maxframes = RtlCaptureStackBackTrace(0, maxframes, reinterpret_cast<PVOID*>(myFrames), &BackTraceHash);
    m_hashValue = BackTraceHash;
    UINT32  startIndex = 0;
    while (count < maxframes) {
        if (myFrames[count] == 0)
            break;
        if (myFrames[count] == context.fp)
            startIndex = count;
        count++;
    }
    count = startIndex;
    while (count < maxframes) {
        if (myFrames[count] == 0)
            break;
        push_back(myFrames[count]);
        count++;
    }
    delete [] myFrames;
//#endif
}
示例#17
0
	void PlatformStack::CaptureStackBackTrace(uint64* backTrace, uint32 maxDepth, void* context)
	{
		if (backTrace == NULL || maxDepth == 0)
		{
			return;
		}

		if (context)
		{
			CaptureStackTraceHelper(backTrace, maxDepth, (CONTEXT*)context);
		}
		else
		{
#if USE_FAST_STACKTRACE
			//if (!GMaxCallstackDepthInitialized)
			//{
			//	DetermineMaxCallstackDepth();
			//}

			PVOID winBackTrace[MAX_CALLSTACK_DEPTH];
			uint16 numFrames = RtlCaptureStackBackTrace(0, maxDepth, winBackTrace, NULL);
			for (uint16 frameIndex = 0; frameIndex < numFrames; ++frameIndex)
			{
				backTrace[frameIndex] = (uint64)winBackTrace[frameIndex];
			}

			while (numFrames < maxDepth)
			{
				backTrace[numFrames++] = 0;
			}

#elif USE_SLOW_STACKTRACE
			InitSysStack();

			CONTEXT helperContext;
			RtlCaptureContext(&helperContext);

			CaptureStackTraceHelper(backTrace, maxDepth, &helperContext);

#elif _WIN64
			// Raise an exception so CaptureStackBackTraceHelper has access to context record.
			__try
			{
				RaiseException(0,			// Application-defined exception code.
					0,			// Zero indicates continuable exception.
					0,			// Number of arguments in args array (ignored if args is NULL)
					NULL);		// Array of arguments
			}
			// Capture the back trace.
			__except (CaptureStackTraceHelper(backTrace, maxDepth, (GetExceptionInformation())->ContextRecord))
			{
			}
#else
			// Use a bit of inline assembly to capture the information relevant to stack walking which is
			// basically EIP and EBP.
			CONTEXT HelperContext;
			memset(&HelperContext, 0, sizeof(CONTEXT));
			HelperContext.ContextFlags = CONTEXT_FULL;

			// Use a fake function call to pop the return address and retrieve EIP.
			__asm
			{
				call FakeFunctionCall
				FakeFunctionCall :
				pop eax
					mov HelperContext.Eip, eax
					mov HelperContext.Ebp, ebp
					mov HelperContext.Esp, esp
			}

			// Capture the back trace.
			CaptureStackTraceHelper(backTrace, maxDepth, &HelperContext);
#endif
		}
	}
示例#18
0
	int callstack( int skip_frames, void** addresses, int num_addresses )
	{
		return RtlCaptureStackBackTrace( skip_frames + 1, num_addresses, addresses, 0 );
	}
示例#19
0
文件: reftrace.c 项目: aspnet/Home
LONG
__cdecl
WriteRefTraceLogEx(
    IN PTRACE_LOG Log,
    IN LONG NewRefCount,
    IN CONST VOID * Context,
    IN CONST VOID * Context1, // optional extra context
    IN CONST VOID * Context2, // optional extra context
    IN CONST VOID * Context3  // optional extra context
    )
/*++

Routine Description:

    Writes a new "extended" entry to the specified ref count trace log.
    The entry written contains the updated reference count, stack backtrace
    leading up to the current caller and extra context information.

Arguments:

    Log - The log to write to.

    NewRefCount - The updated reference count.

    Context  - An uninterpreted context to associate with the log entry.
    Context1 - An uninterpreted context to associate with the log entry.
    Context2 - An uninterpreted context to associate with the log entry.
    Context3 - An uninterpreted context to associate with the log entry.

    NOTE Context1/2/3 are "optional" in that the caller may suppress
    debug display of these values by passing REF_TRACE_EMPTY_CONTEXT
    for each of them.

Return Value:

    Index of entry in log.

--*/
{

    REF_TRACE_LOG_ENTRY entry;
    ULONG hash;
    DWORD cStackFramesSkipped;

    //
    // Initialize the entry.
    //

    RtlZeroMemory(
        &entry,
        sizeof(entry)
        );

    //
    //  Set log entry members.
    //

    entry.NewRefCount = NewRefCount;
    entry.Context = Context;
    entry.Thread = GetCurrentThreadId();
    entry.Context1 = Context1;
    entry.Context2 = Context2;
    entry.Context3 = Context3;

    //
    // Capture the stack backtrace. Normally, we skip two stack frames:
    // one for this routine, and one for RtlCaptureBacktrace() itself.
    // For non-Ex callers who come in via WriteRefTraceLog,
    // we skip three stack frames.
    //

    if (    entry.Context1 == REF_TRACE_EMPTY_CONTEXT
         && entry.Context2 == REF_TRACE_EMPTY_CONTEXT
         && entry.Context3 == REF_TRACE_EMPTY_CONTEXT
         ) {

         cStackFramesSkipped = 2;

    } else {

         cStackFramesSkipped = 1;

    }

    RtlCaptureStackBackTrace(
        cStackFramesSkipped,
        REF_TRACE_LOG_STACK_DEPTH,
        entry.Stack,
        &hash
        );

    //
    // Write it to the log.
    //

    return WriteTraceLog(
        Log,
        &entry
        );

}   // WriteRefTraceLogEx
示例#20
0
文件: debug.c 项目: dcatonR1/FreeRDP
void* winpr_backtrace(DWORD size)
{
#if defined(HAVE_EXECINFO_H)
	t_execinfo* data = calloc(1, sizeof(t_execinfo));

	if (!data)
		return NULL;

	data->buffer = calloc(size, sizeof(void*));

	if (!data->buffer)
	{
		free(data);
		return NULL;
	}

	data->max = size;
	data->used = backtrace(data->buffer, size);
	return data;
#elif defined(ANDROID)
	t_corkscrew_data* data = calloc(1, sizeof(t_corkscrew_data));

	if (!data)
		return NULL;

	data->buffer = calloc(size, sizeof(backtrace_frame_t));

	if (!data->buffer)
	{
		free(data);
		return NULL;
	}

	pthread_once(&initialized, load_library);
	data->max = size;
	data->used = fkt->unwind_backtrace(data->buffer, 0, size);
	return data;
#elif (defined(_WIN32) || defined(_WIN64)) && !defined(_UWP)
	HANDLE process = GetCurrentProcess();
	t_win_stack* data = calloc(1, sizeof(t_win_stack));

	if (!data)
		return NULL;

	data->max = size;
	data->stack = calloc(data->max, sizeof(PVOID));

	if (!data->stack)
	{
		free(data);
		return NULL;
	}

	SymInitialize(process, NULL, TRUE);
	data->used = RtlCaptureStackBackTrace(2, size, data->stack, NULL);

	return data;
#else
	LOGF(support_msg);
	return NULL;
#endif
}
示例#21
0
文件: stktrace.c 项目: mingpen/OpenNT
USHORT
RtlLogStackBackTrace( 
    VOID 
    )
/*++

Routine Description:

    This routine will capture the current stacktrace (skipping the 
    present function) and will save it in the global (per process) 
    stack trace database. It should be noted that we do not save
    duplicate traces.

Arguments:

    None.

Return Value:

    Index of the stack trace saved. The index can be used by tools
    to access quickly the trace data. This is the reason at the end of
    the database we save downwards a list of pointers to trace entries.
    This index can be used to find this pointer in constant time.
    
    A zero index will be returned for error conditions (e.g. stack 
    trace database not initialized).

Environment:

    User mode. 

--*/

{
    PSTACK_TRACE_DATABASE DataBase;
    RTL_STACK_TRACE_ENTRY StackTrace;
    PRTL_STACK_TRACE_ENTRY p, *pp;
    ULONG Hash, RequestedSize, DepthSize;

    if (RtlpStackTraceDataBase == NULL) {
        return 0;
        }

    Hash = 0;

    //
    // Capture stack trace. The try/except was useful
    // in the old days when the function did not validate
    // the stack frame chain. We keep it just ot be defensive.
    //

    try {
        StackTrace.Depth = RtlCaptureStackBackTrace(
            1,
            MAX_STACK_DEPTH,
            StackTrace.BackTrace,
            &Hash
            );
    }
    except(EXCEPTION_EXECUTE_HANDLER) {
        StackTrace.Depth = 0;
    }

    if (StackTrace.Depth == 0) {
        return 0;
    }

    //
    // Lock the global per-process stack trace database.
    //

    DataBase = RtlpAcquireStackTraceDataBase();
    
    if (DataBase == NULL) {
        return( 0 );
    }

    DataBase->NumberOfEntriesLookedUp++;

    try {

        //
        // We will try to find out if the trace has been saved in the past.
        // We find the right hash chain and then traverse it.
        //

        DepthSize = StackTrace.Depth * sizeof( StackTrace.BackTrace[ 0 ] );
        pp = &DataBase->Buckets[ Hash % DataBase->NumberOfBuckets ];

        while (p = *pp) {
            if (p->Depth == StackTrace.Depth &&
                RtlCompareMemory( &p->BackTrace[ 0 ],
                &StackTrace.BackTrace[ 0 ],
                DepthSize
                ) == DepthSize
                ) {
                break;
            }
            else {
                pp = &p->HashChain;
            }
        }

        if (p == NULL) {

            //
            // We did not find the stack trace. We will extend the database
            // and save the new trace.
            //

            RequestedSize = FIELD_OFFSET( RTL_STACK_TRACE_ENTRY, BackTrace ) +
                DepthSize;

            p = RtlpExtendStackTraceDataBase( &StackTrace, RequestedSize );
            
            //
            // If we managed to stack the trace we need to link it as the last
            // element in the proper hash chain.
            //

            if (p != NULL) {
                *pp = p;
            }
        }
    }
    except(EXCEPTION_EXECUTE_HANDLER) {

        //
        // bugbug (silviuc): We should not be here. Right?
        //

        p = NULL;
    }

    //
    // Release global trace db.
    //

    RtlpReleaseStackTraceDataBase();

    if (p != NULL) {
        p->TraceCount++;
        return( p->Index );
        }
    else {
        return( 0 );
        }

    return 0;
}
示例#22
0
int appCaptureStackTrace(address_t* buffer, int maxDepth, int framesToSkip)
{
	return RtlCaptureStackBackTrace(framesToSkip, maxDepth, (void**)buffer, NULL);
}