mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
[NTDLL]
- Implement user-mode version of RtlWalkFrameChain (mostly as a copy of the kernel version). Now RtlCaptureStackBackTrace actually, you know, captures stack back-traces. svn path=/trunk/; revision=74490
This commit is contained in:
parent
8550143bab
commit
cf595e72fa
2 changed files with 108 additions and 17 deletions
|
@ -20,22 +20,6 @@ PVOID MmHighestUserAddress = (PVOID)MI_HIGHEST_USER_ADDRESS;
|
|||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
#ifndef _M_AMD64
|
||||
// FIXME: Why "Not implemented"???
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
ULONG
|
||||
NTAPI
|
||||
RtlWalkFrameChain(OUT PVOID *Callers,
|
||||
IN ULONG Count,
|
||||
IN ULONG Flags)
|
||||
{
|
||||
/* Not implemented for user-mode */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
RtlpCheckForActiveDebugger(VOID)
|
||||
|
@ -234,6 +218,113 @@ RtlpCaptureStackLimits(IN ULONG_PTR Ebp,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#ifndef _M_AMD64
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
ULONG
|
||||
NTAPI
|
||||
RtlWalkFrameChain(OUT PVOID *Callers,
|
||||
IN ULONG Count,
|
||||
IN ULONG Flags)
|
||||
{
|
||||
ULONG_PTR Stack, NewStack, StackBegin, StackEnd = 0;
|
||||
ULONG Eip;
|
||||
BOOLEAN Result, StopSearch = FALSE;
|
||||
ULONG i = 0;
|
||||
|
||||
/* Get current EBP */
|
||||
#if defined(_M_IX86)
|
||||
#if defined __GNUC__
|
||||
__asm__("mov %%ebp, %0" : "=r" (Stack) : );
|
||||
#elif defined(_MSC_VER)
|
||||
__asm mov Stack, ebp
|
||||
#endif
|
||||
#elif defined(_M_MIPS)
|
||||
__asm__("move $sp, %0" : "=r" (Stack) : );
|
||||
#elif defined(_M_PPC)
|
||||
__asm__("mr %0,1" : "=r" (Stack) : );
|
||||
#elif defined(_M_ARM)
|
||||
__asm__("mov sp, %0" : "=r"(Stack) : );
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
|
||||
/* Set it as the stack begin limit as well */
|
||||
StackBegin = (ULONG_PTR)Stack;
|
||||
|
||||
/* Check if we're called for non-logging mode */
|
||||
if (!Flags)
|
||||
{
|
||||
/* Get the actual safe limits */
|
||||
Result = RtlpCaptureStackLimits((ULONG_PTR)Stack,
|
||||
&StackBegin,
|
||||
&StackEnd);
|
||||
if (!Result) return 0;
|
||||
}
|
||||
|
||||
/* Use a SEH block for maximum protection */
|
||||
_SEH2_TRY
|
||||
{
|
||||
/* Loop the frames */
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
/*
|
||||
* Leave if we're past the stack,
|
||||
* if we're before the stack,
|
||||
* or if we've reached ourselves.
|
||||
*/
|
||||
if ((Stack >= StackEnd) ||
|
||||
(!i ? (Stack < StackBegin) : (Stack <= StackBegin)) ||
|
||||
((StackEnd - Stack) < (2 * sizeof(ULONG_PTR))))
|
||||
{
|
||||
/* We're done or hit a bad address */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get new stack and EIP */
|
||||
NewStack = *(PULONG_PTR)Stack;
|
||||
Eip = *(PULONG_PTR)(Stack + sizeof(ULONG_PTR));
|
||||
|
||||
/* Check if the new pointer is above the oldone and past the end */
|
||||
if (!((Stack < NewStack) && (NewStack < StackEnd)))
|
||||
{
|
||||
/* Stop searching after this entry */
|
||||
StopSearch = TRUE;
|
||||
}
|
||||
|
||||
/* Also make sure that the EIP isn't a stack address */
|
||||
if ((StackBegin < Eip) && (Eip < StackEnd)) break;
|
||||
|
||||
/* FIXME: Check that EIP is inside a loaded module */
|
||||
|
||||
/* Save this frame */
|
||||
Callers[i] = (PVOID)Eip;
|
||||
|
||||
/* Check if we should continue */
|
||||
if (StopSearch)
|
||||
{
|
||||
/* Return the next index */
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Move to the next stack */
|
||||
Stack = NewStack;
|
||||
}
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
/* No index */
|
||||
i = 0;
|
||||
}
|
||||
_SEH2_END;
|
||||
|
||||
/* Return frames parsed */
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _AMD64_
|
||||
VOID
|
||||
NTAPI
|
||||
|
|
|
@ -406,7 +406,7 @@ RtlWalkFrameChain(OUT PVOID *Callers,
|
|||
&StackBegin,
|
||||
&StackEnd);
|
||||
if (!Result) return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Use a SEH block for maximum protection */
|
||||
_SEH2_TRY
|
||||
|
|
Loading…
Reference in a new issue