Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

getcalr.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1991 Microsoft Corporation 00004 00005 Module Name: 00006 00007 getcalr.c 00008 00009 Abstract: 00010 00011 This module implements the routine RtlGetCallerAddress. It will 00012 return the address of the caller, and the callers caller to the 00013 specified procedure. 00014 00015 Author: 00016 00017 William K. Cheung (wcheung) 17-Jan-1996 00018 00019 based on version by Larry Osterman (larryo) 18-Mar-1991 00020 00021 Revision History: 00022 00023 --*/ 00024 #include "ntrtlp.h" 00025 00026 // 00027 // Undefine get callers address since it is defined as a macro. 00028 // 00029 00030 #undef RtlGetCallersAddress 00031 00032 VOID 00033 RtlGetCallersAddress ( 00034 OUT PVOID *CallersPc, 00035 OUT PVOID *CallersCallersPc 00036 ) 00037 00038 /*++ 00039 00040 Routine Description: 00041 00042 This routine returns the address of the routine that called the routine 00043 that called this routine, and the routine that called the routine that 00044 called this routine. For example, if A called B called C which called 00045 this routine, the return addresses in A and B would be returned. 00046 00047 Arguments: 00048 00049 CallersPc - Supplies a pointer to a variable that receives the address 00050 of the caller of the caller of this routine (B). 00051 00052 CallersCallersPc - Supplies a pointer to a variable that receives the 00053 address of the caller of the caller of the caller of this routine 00054 (A). 00055 00056 Return Value: 00057 00058 None. 00059 00060 Note: 00061 00062 If either of the calling stack frames exceeds the limits of the stack, 00063 they are set to NULL. 00064 00065 --*/ 00066 00067 { 00068 #ifdef REALLY_GET_CALLERS_CALLER 00069 CONTEXT ContextRecord; 00070 FRAME_POINTERS EstablisherFrame; 00071 PRUNTIME_FUNCTION FunctionEntry; 00072 BOOLEAN InFunction; 00073 ULONG_PTR NextPc; 00074 ULONGLONG HighStackLimit, LowStackLimit; 00075 ULONGLONG HighBStoreLimit, LowBStoreLimit; 00076 ULONGLONG ImageBase; 00077 ULONGLONG TargetGp; 00078 00079 // 00080 // Assume the function table entries for the various routines cannot be 00081 // found or there are not four procedure activation records on the stack. 00082 // 00083 00084 *CallersPc = NULL; 00085 *CallersCallersPc = NULL; 00086 00087 // 00088 // Capture the current context. 00089 // 00090 00091 RtlCaptureContext(&ContextRecord); 00092 NextPc = (ULONG_PTR)ContextRecord.BrRp; 00093 00094 // 00095 // Get the high and low limits of the current thread's stack. 00096 // 00097 00098 Rtlp64GetStackLimits(&LowStackLimit, &HighStackLimit); 00099 Rtlp64GetBStoreLimits(&LowBStoreLimit, &HighBStoreLimit); 00100 00101 // 00102 // Attempt to unwind to the caller of this routine (C). 00103 // 00104 00105 FunctionEntry = RtlLookupFunctionEntry(NextPc, &ImageBase, &TargetGp); 00106 if (FunctionEntry != NULL) { 00107 00108 // 00109 // A function entry was found for this routine. Virtually unwind 00110 // to the caller of this routine (C). 00111 // 00112 00113 NextPc = RtlVirtualUnwind(NextPc, 00114 FunctionEntry, 00115 &ContextRecord, 00116 &InFunction, 00117 &EstablisherFrame, 00118 NULL); 00119 00120 // 00121 // Attempt to unwind to the caller of the caller of this routine (B). 00122 // 00123 00124 FunctionEntry = RtlLookupFunctionEntry(NextPc); 00125 if ((FunctionEntry != NULL) && (((ULONG_PTR)ContextRecord.IntSp < HighStackLimit) && ((ULONG_PTR)ContextRecord.RsBSP > LowBStoreLimit))) { 00126 00127 // 00128 // A function table entry was found for the caller of the caller 00129 // of this routine (B). Virtually unwind to the caller of the 00130 // caller of this routine (B). 00131 // 00132 00133 NextPc = RtlVirtualUnwind(NextPc, 00134 FunctionEntry, 00135 &ContextRecord, 00136 &InFunction, 00137 &EstablisherFrame, 00138 NULL); 00139 00140 *CallersPc = (PVOID)NextPc; 00141 00142 // 00143 // Attempt to unwind to the caller of the caller of the caller 00144 // of the caller of this routine (A). 00145 // 00146 00147 FunctionEntry = RtlLookupFunctionEntry(NextPc); 00148 if ((FunctionEntry != NULL) && (((ULONG_PTR)ContextRecord.IntSp < HighStackLimit) && ((ULONG_PTR)ContextRecord.RsBSP > LowBStoreLimit))) { 00149 00150 // 00151 // A function table entry was found for the caller of the 00152 // caller of the caller of this routine (A). Virtually unwind 00153 // to the caller of the caller of the caller of this routine 00154 // (A). 00155 // 00156 00157 NextPc = RtlVirtualUnwind(NextPc, 00158 FunctionEntry, 00159 &ContextRecord, 00160 &InFunction, 00161 &EstablisherFrame, 00162 NULL); 00163 00164 *CallersCallersPc = (PVOID)NextPc; 00165 } 00166 } 00167 } 00168 #else 00169 *CallersPc = NULL; 00170 *CallersCallersPc = NULL; 00171 #endif // REALLY_GET_CALLERS_CALLER 00172 return; 00173 } 00174 00175 USHORT 00176 RtlCaptureStackBackTrace( 00177 IN ULONG FramesToSkip, 00178 IN ULONG FramesToCapture, 00179 OUT PVOID *BackTrace, 00180 OUT PULONG BackTraceHash 00181 ) 00182 { 00183 return 0; 00184 }

Generated on Sat May 15 19:40:11 2004 for test by doxygen 1.3.7