Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
5.2 KiB

  1. TITLE "Capture Stack Back Trace"
  2. ;++
  3. ;
  4. ; Copyright (c) 1989 Microsoft Corporation
  5. ;
  6. ; Module Name:
  7. ;
  8. ; stkwalk.asm
  9. ;
  10. ; Abstract:
  11. ;
  12. ; This module implements the routine RtlCaptureStackBackTrace. It will
  13. ; walker the stack back trace and capture a portion of it.
  14. ;
  15. ; Author:
  16. ;
  17. ; Steve Wood (stevewo) 29-Jan-1992
  18. ;
  19. ; Environment:
  20. ;
  21. ; Any mode.
  22. ;
  23. ; Revision History:
  24. ;
  25. ;--
  26. .386p
  27. .xlist
  28. include ks386.inc
  29. include callconv.inc ; calling convention macros
  30. .list
  31. IFDEF NTOS_KERNEL_RUNTIME
  32. EXTRNP _MmIsAddressValid,1
  33. ENDIF
  34. _TEXT SEGMENT DWORD PUBLIC 'CODE'
  35. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  36. IFDEF NTOS_KERNEL_RUNTIME
  37. page ,132
  38. subttl "RtlGetCallersAddress"
  39. ;++
  40. ;
  41. ; VOID
  42. ; RtlGetCallersAddress(
  43. ; OUT PVOID *CallersAddress,
  44. ; OUT PVOID *CallersCaller
  45. ; )
  46. ;
  47. ; Routine Description:
  48. ;
  49. ; This routine walks up the stack frames, capturing the first two return
  50. ; addresses
  51. ;
  52. ;
  53. ; Arguments:
  54. ;
  55. ; OUT PVOID CallersAddress - returns callers return address
  56. ; OUT PVOID CallersCaller - returns callers caller return address
  57. ;
  58. ; Return Value:
  59. ;
  60. ; None.
  61. ;
  62. ;
  63. ;--
  64. RgcaCallersAddress EQU [ebp+08h]
  65. RgcaCallersCaller EQU [ebp+0Ch]
  66. cPublicProc _RtlGetCallersAddress ,2
  67. push ebp
  68. mov ebp, esp
  69. push ebx ; Save EBX
  70. push esi ; Save ESI
  71. push edi ; Save EDI
  72. mov eax, PCR[PcPrcbData+PbCurrentThread] ; (eax)->current thread
  73. push ThInitialStack[eax] ; RcbtInitialStack = base of kernel stack
  74. push esp ; Save current esp for handler
  75. push offset RgcaFault ; Address of handler
  76. push PCR[PcExceptionList] ; Save current list head
  77. mov PCR[PcExceptionList],esp; Put us on list
  78. xor esi,esi ; (ESI) will contain callers return address
  79. xor edi,edi ; (EDI) will contain callers caller return address
  80. mov edx,ebp ; (EDX) = current frame pointer
  81. mov edx,[edx] ; (EDX) = callers frame pointer
  82. cmp edx,ebp ; If outside stack limits,
  83. jbe short RgcaExit ; ...then exit
  84. cmp edx,RcbtInitialStack
  85. jae short RgcaCheckForDpcStack
  86. cmp edx,ThStackLimit[eax]
  87. jb short RgcaCheckForDpcStack
  88. Rgca20:
  89. mov esi,[edx].4 ; Get callers return address
  90. mov edx,[edx] ; (EDX) = callers caller frame pointer
  91. cmp edx,ebp ; If outside stack limits,
  92. jbe short RgcaExit ; ...then exit
  93. cmp edx,RcbtInitialStack
  94. jae short RgcaExit
  95. mov edi,[edx].4 ; Get callers caller return address
  96. RgcaExit:
  97. mov ecx,RgcaCallersAddress
  98. jecxz @F
  99. mov [ecx],esi
  100. @@:
  101. mov ecx,RgcaCallersCaller
  102. jecxz @F
  103. mov [ecx],edi
  104. @@:
  105. pop PCR[PcExceptionList] ; Restore Exception list
  106. pop edi ; discard handler address
  107. pop edi ; discard saved esp
  108. pop edi ; discard RcbtInitialStack
  109. pop edi ; Restore EDI
  110. pop esi ; Restore ESI
  111. pop ebx ; Restore EBX
  112. pop ebp
  113. stdRET _RtlGetCallersAddress
  114. ;
  115. ; We may be executing on the DPC stack for this processor which is ok.
  116. ;
  117. RgcaCheckForDpcStack:
  118. ; Check if DPC active.
  119. cmp dword ptr PCR[PcPrcbData+PbDpcRoutineActive], 0
  120. mov eax, PCR[PcPrcbData+PbDpcStack]
  121. je short RgcaExit ; if no DPC active, must be bad stack.
  122. ; Check if address if below DPC stack upper bound
  123. ;
  124. ; Note: If we ARE on the DPC stack, we need to adjust this funtion's
  125. ; idea of the initial stack pointer so it will succeed the check at
  126. ; the next level. We do not support transitioning across stacks in
  127. ; this function.
  128. cmp edx, eax
  129. mov RcbtInitialStack, eax
  130. jae short RgcaExit ; exit if above upper bound
  131. ; Check if below DPC stack lower bound.
  132. sub eax, KERNEL_STACK_SIZE
  133. cmp edx, eax
  134. ja short Rgca20 ; jif on DPC stack
  135. jmp short RgcaExit ; not on DPC stack.
  136. RgcaFault:
  137. ;
  138. ; Cheap and sleazy exception handler. This will not unwind properly, which
  139. ; is ok because this function is a leaf except for calling KeGetCurrentIrql,
  140. ; which has no exception handler.
  141. ;
  142. mov eax,[esp+0Ch] ; (esp)->Context
  143. mov edi,CsEdi[eax] ; restore buffer pointer
  144. mov esp,[esp+8] ; (esp)->ExceptionList
  145. jmp RgcaExit ;
  146. stdENDP _RtlGetCallersAddress
  147. ENDIF
  148. IFDEF NTOS_KERNEL_RUNTIME
  149. RcbtInitialStack EQU [ebp-10h]
  150. ENDIF
  151. _TEXT ends
  152. end