| 204 | } |
| 205 | |
| 206 | int StackWalker::walkVM(void* ucontext, ASGCT_CallFrame* frames, int max_depth, int lock_index, |
| 207 | StackWalkFeatures features, EventType event_type) { |
| 208 | const void* pc; |
| 209 | uintptr_t fp; |
| 210 | uintptr_t sp; |
| 211 | uintptr_t bottom = (uintptr_t)&sp + MAX_WALK_SIZE; |
| 212 | |
| 213 | StackFrame frame(ucontext ? ucontext : &empty_ucontext); |
| 214 | if (ucontext == NULL) { |
| 215 | pc = callerPC(); |
| 216 | fp = (uintptr_t)callerFP(); |
| 217 | sp = (uintptr_t)callerSP(); |
| 218 | } else { |
| 219 | pc = (const void*)frame.pc(); |
| 220 | fp = frame.fp(); |
| 221 | sp = frame.sp(); |
| 222 | } |
| 223 | |
| 224 | Profiler* profiler = Profiler::instance(); |
| 225 | int bcp_offset = InterpreterFrame::bcp_offset(); |
| 226 | |
| 227 | jmp_buf current_ctx; |
| 228 | crash_protection_ctx[lock_index] = ¤t_ctx; |
| 229 | |
| 230 | // Should be preserved across setjmp/longjmp |
| 231 | volatile int depth = 0; |
| 232 | |
| 233 | if (setjmp(current_ctx) != 0) { |
| 234 | crash_protection_ctx[lock_index] = NULL; |
| 235 | if (depth < max_depth) { |
| 236 | fillFrame(frames[depth++], BCI_ERROR, "break_not_walkable"); |
| 237 | } |
| 238 | return depth; |
| 239 | } |
| 240 | |
| 241 | // Show extended frame types and stub frames for execution-type events |
| 242 | bool details = event_type <= MALLOC_SAMPLE || features.mixed; |
| 243 | |
| 244 | JavaFrameAnchor* anchor = NULL; |
| 245 | VMThread* vm_thread = VMThread::current(); |
| 246 | if (vm_thread != NULL && vm_thread->isJavaThread()) { |
| 247 | // For simple stack traces (e.g. for allocation profiling) |
| 248 | // jump directly to the first Java frame |
| 249 | if (details) { |
| 250 | anchor = vm_thread->anchor(); |
| 251 | } else if (!vm_thread->anchor()->restoreFrame(pc, sp, fp)) { |
| 252 | return 0; |
| 253 | } |
| 254 | } |
| 255 | |
| 256 | unwind_loop: |
| 257 | uintptr_t prev_sp = sp; |
| 258 | while (depth < max_depth) { |
| 259 | // As an extra safety measure, verify stack pointer invariants on every iteration |
| 260 | if (sp < prev_sp || sp >= bottom || !aligned(sp)) { |
| 261 | fillFrame(frames[depth++], BCI_ERROR, "break_stack_range"); |
| 262 | break; |
| 263 | } |
nothing calls this directly
no test coverage detected