MCPcopy Create free account
hub / github.com/async-profiler/async-profiler / checkInterruptedSyscall

Method checkInterruptedSyscall

src/stackFrame_aarch64.cpp:308–346  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

306}
307
308bool StackFrame::checkInterruptedSyscall() {
309#ifdef __APPLE__
310 // We are not interested in syscalls that do not check error code, e.g. semaphore_wait_trap
311 if (*(instruction_t*)pc() == 0xd65f03c0) {
312 return true;
313 }
314 // If carry flag is set, the error code is in low byte of x0
315 if (REG(pstate, cpsr) & (1 << 29)) {
316 return (retval() & 0xff) == EINTR || (retval() & 0xff) == ETIMEDOUT;
317 } else {
318 return retval() == (uintptr_t)-EINTR;
319 }
320#else
321 if (retval() == (uintptr_t)-EINTR) {
322 // Workaround for JDK-8237858: restart the interrupted poll / epoll_wait manually
323 uintptr_t nr = (uintptr_t)REG(regs[8], x[8]);
324 if (nr == SYS_ppoll || (nr == SYS_epoll_pwait && (int)arg3() == -1)) {
325 // Check against unreadable page for the loop below
326 const uintptr_t max_distance = 24;
327 if ((pc() & 0xfff) < max_distance && SafeAccess::load32((int32_t*)(pc() - max_distance)) == 0) {
328 return true;
329 }
330 // Try to restore the original value of x0 saved in another register
331 for (uintptr_t prev_pc = pc() - 4; pc() - prev_pc <= max_distance; prev_pc -= 4) {
332 instruction_t insn = *(instruction_t*)prev_pc;
333 unsigned int reg = (insn >> 16) & 31;
334 if ((insn & 0xffe0ffff) == 0xaa0003e0 && reg >= 6) {
335 // mov x0, reg
336 REG(regs[0], x[0]) = REG(regs[reg], x[reg]);
337 pc() -= sizeof(instruction_t);
338 break;
339 }
340 }
341 }
342 return true;
343 }
344 return false;
345#endif
346}
347
348bool StackFrame::isSyscall(instruction_t* pc) {
349 // svc #0 or svc #80

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected