Walk the stack of the current thread and resolve the module associated with the return addresses. @param ResolvedStack - Caller-supplied array of return address information that this function populates. @param ResolvedStackSize - The number of return addresses to resolve. @param ResolvedStackTag - The tag to allocate ResolvedStack with. */
| 123 | @param ResolvedStackTag - The tag to allocate ResolvedStack with. |
| 124 | */ |
| 125 | VOID |
| 126 | StackWalker::WalkAndResolveStack ( |
| 127 | _Inout_ PSTACK_RETURN_INFO* ResolvedStack, |
| 128 | _Inout_ ULONG* ResolvedStackSize, |
| 129 | _In_ ULONG ResolvedStackTag |
| 130 | ) |
| 131 | { |
| 132 | PVOID* stackReturnPtrs; |
| 133 | ULONG capturedReturnPtrs; |
| 134 | ULONG i; |
| 135 | |
| 136 | capturedReturnPtrs = 0; |
| 137 | *ResolvedStack = NULL; |
| 138 | |
| 139 | // |
| 140 | // Allocate space for the return addresses. |
| 141 | // |
| 142 | stackReturnPtrs = RCAST<PVOID*>(ExAllocatePoolWithTag(PagedPool, sizeof(PVOID) * *ResolvedStackSize, STACK_WALK_ARRAY_TAG)); |
| 143 | if (stackReturnPtrs == NULL) |
| 144 | { |
| 145 | DBGPRINT("StackWalker!WalkAndResolveStack: Failed to allocate space for temporary stack array."); |
| 146 | goto Exit; |
| 147 | } |
| 148 | |
| 149 | memset(stackReturnPtrs, 0, sizeof(PVOID) * *ResolvedStackSize); |
| 150 | |
| 151 | // |
| 152 | // Get the return addresses leading up to this call. |
| 153 | // |
| 154 | capturedReturnPtrs = RtlWalkFrameChain(stackReturnPtrs, *ResolvedStackSize, 1); |
| 155 | if (capturedReturnPtrs == 0) |
| 156 | { |
| 157 | DBGPRINT("StackWalker!WalkAndResolveStack: Failed to walk the stack."); |
| 158 | goto Exit; |
| 159 | } |
| 160 | |
| 161 | NT_ASSERT(capturedReturnPtrs < ResolvedStackSize); |
| 162 | |
| 163 | *ResolvedStackSize = capturedReturnPtrs; |
| 164 | |
| 165 | // |
| 166 | // Allocate space for the stack return info array. |
| 167 | // |
| 168 | *ResolvedStack = RCAST<PSTACK_RETURN_INFO>(ExAllocatePoolWithTag(PagedPool, sizeof(STACK_RETURN_INFO) * *ResolvedStackSize, ResolvedStackTag)); |
| 169 | if (*ResolvedStack == NULL) |
| 170 | { |
| 171 | DBGPRINT("StackWalker!WalkAndResolveStack: Failed to allocate space for stack info array."); |
| 172 | goto Exit; |
| 173 | } |
| 174 | memset(*ResolvedStack, 0, sizeof(STACK_RETURN_INFO) * *ResolvedStackSize); |
| 175 | |
| 176 | |
| 177 | // |
| 178 | // Iterate each return address and fill out the struct. |
| 179 | // |
| 180 | for (i = 0; i < capturedReturnPtrs; i++) |
| 181 | { |
| 182 | (*ResolvedStack)[i].RawAddress = stackReturnPtrs[i]; |
no test coverage detected