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 Larry Osterman (larryo) 18-Mar-1991 (with help from DaveC) 00018 00019 Revision History: 00020 00021 18-Mar-1991 larryo 00022 00023 Created 00024 00025 Thomas Van Baak (tvb) 5-May-1992 00026 00027 Adapted for Alpha AXP. 00028 00029 --*/ 00030 #include "ntrtlp.h" 00031 00032 // 00033 // Undefine get callers address since it is defined as a macro. 00034 // 00035 00036 #undef RtlGetCallersAddress 00037 00038 VOID 00039 RtlGetCallersAddress ( 00040 OUT PVOID *CallersPc, 00041 OUT PVOID *CallersCallersPc 00042 ) 00043 00044 /*++ 00045 00046 Routine Description: 00047 00048 This routine returns the address of the call to the routine that called 00049 this routine, and the address of the call to the routine that called 00050 the routine that called this routine. For example, if A called B called 00051 C which called this routine, the return addresses in B and A would be 00052 returned. 00053 00054 Arguments: 00055 00056 CallersPc - Supplies a pointer to a variable that receives the address 00057 of the caller of the caller of this routine (B). 00058 00059 CallersCallersPc - Supplies a pointer to a variable that receives the 00060 address of the caller of the caller of the caller of this routine 00061 (A). 00062 00063 Return Value: 00064 00065 None. 00066 00067 Note: 00068 00069 If either of the calling stack frames exceeds the limits of the stack, 00070 they are set to NULL. 00071 00072 --*/ 00073 00074 { 00075 #ifdef REALLY_GET_CALLERS_CALLER 00076 CONTEXT ContextRecord; 00077 FRAME_POINTERS EstablisherFrame; 00078 PRUNTIME_FUNCTION FunctionEntry; 00079 BOOLEAN InFunction; 00080 ULONG HighLimit, LowLimit; 00081 ULONG NextPc; 00082 00083 // 00084 // Assume the function table entries for the various routines cannot be 00085 // found or there are not four procedure activation records on the stack. 00086 // 00087 00088 *CallersPc = NULL; 00089 *CallersCallersPc = NULL; 00090 00091 // 00092 // Capture the current context. 00093 // 00094 00095 RtlCaptureContext(&ContextRecord); 00096 NextPc = (ULONG)ContextRecord.IntRa; 00097 00098 // 00099 // Get the high and low limits of the current thread's stack. 00100 // 00101 00102 RtlpGetStackLimits(&LowLimit, &HighLimit); 00103 00104 // 00105 // Attempt to unwind to the caller of this routine (C). The FunctionEntry 00106 // returned here will be that of this routine since NextPc was the return 00107 // address of our call to RtlCaptureContext. For the purposes of this 00108 // function, the +4 and -4 adjustments to NextPc are unnecessary. 00109 // 00110 00111 FunctionEntry = RtlLookupFunctionEntry(NextPc); 00112 if (FunctionEntry != NULL) { 00113 00114 // 00115 // A function entry was found for this routine. Virtually unwind 00116 // to the caller of this routine (C). 00117 // 00118 00119 NextPc = RtlVirtualUnwind(NextPc, 00120 FunctionEntry, 00121 &ContextRecord, 00122 &InFunction, 00123 &EstablisherFrame, 00124 NULL); 00125 00126 // 00127 // Attempt to unwind to the caller of the caller of this routine (B). 00128 // 00129 00130 FunctionEntry = RtlLookupFunctionEntry(NextPc); 00131 if ((FunctionEntry != NULL) && ((ULONG)ContextRecord.IntSp < HighLimit)) { 00132 00133 // 00134 // A function table entry was found for the caller of the caller 00135 // of this routine (B). Virtually unwind to the caller of the 00136 // caller of this routine (B). 00137 // 00138 00139 NextPc = RtlVirtualUnwind(NextPc, 00140 FunctionEntry, 00141 &ContextRecord, 00142 &InFunction, 00143 &EstablisherFrame, 00144 NULL); 00145 *CallersPc = (PVOID)NextPc; 00146 00147 // 00148 // Attempt to unwind to the caller of the caller of the caller 00149 // of the caller of this routine (A). 00150 // 00151 00152 FunctionEntry = RtlLookupFunctionEntry(NextPc); 00153 if ((FunctionEntry != NULL) && ((ULONG)ContextRecord.IntSp < HighLimit)) { 00154 00155 // 00156 // A function table entry was found for the caller of the 00157 // caller of the caller of this routine (A). Virtually unwind 00158 // to the caller of the caller of the caller of this routine 00159 // (A). 00160 // 00161 00162 NextPc = RtlVirtualUnwind(NextPc, 00163 FunctionEntry, 00164 &ContextRecord, 00165 &InFunction, 00166 &EstablisherFrame, 00167 NULL); 00168 00169 *CallersCallersPc = (PVOID)NextPc; 00170 } 00171 } 00172 } 00173 #else 00174 *CallersPc = NULL; 00175 *CallersCallersPc = NULL; 00176 #endif 00177 return; 00178 } 00179 00180 USHORT 00181 RtlCaptureStackBackTrace( 00182 IN ULONG FramesToSkip, 00183 IN ULONG FramesToCapture, 00184 OUT PVOID *BackTrace, 00185 OUT PULONG BackTraceHash 00186 ) 00187 { 00188 return 0; 00189 }

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