mirror of
https://github.com/reactos/reactos.git
synced 2025-06-01 07:28:19 +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 ***************************************************************/
|
/* 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
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlpCheckForActiveDebugger(VOID)
|
RtlpCheckForActiveDebugger(VOID)
|
||||||
|
@ -234,6 +218,113 @@ RtlpCaptureStackLimits(IN ULONG_PTR Ebp,
|
||||||
return TRUE;
|
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_
|
#ifdef _AMD64_
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
|
|
|
@ -406,7 +406,7 @@ RtlWalkFrameChain(OUT PVOID *Callers,
|
||||||
&StackBegin,
|
&StackBegin,
|
||||||
&StackEnd);
|
&StackEnd);
|
||||||
if (!Result) return 0;
|
if (!Result) return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use a SEH block for maximum protection */
|
/* Use a SEH block for maximum protection */
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
|
|
Loading…
Reference in a new issue