| 205 | } |
| 206 | |
| 207 | bool StackFrame::checkInterruptedSyscall() { |
| 208 | #ifdef __APPLE__ |
| 209 | // We are not interested in syscalls that do not check error code, e.g. semaphore_wait_trap |
| 210 | if (*(instruction_t*)pc() == 0xc3) { |
| 211 | return true; |
| 212 | } |
| 213 | // If CF is set, the error code is in low byte of eax, |
| 214 | // some other syscalls (ulock_wait) do not set CF when interrupted |
| 215 | if (REG(EFL, rflags) & 1) { |
| 216 | return (retval() & 0xff) == EINTR || (retval() & 0xff) == ETIMEDOUT; |
| 217 | } else { |
| 218 | return retval() == (uintptr_t)-EINTR; |
| 219 | } |
| 220 | #else |
| 221 | if (retval() == (uintptr_t)-EINTR) { |
| 222 | // Workaround for JDK-8237858: restart the interrupted poll() manually. |
| 223 | // Check if the previous instruction is mov eax, SYS_poll with infinite timeout or |
| 224 | // mov eax, SYS_ppoll with any timeout (ppoll adjusts timeout automatically) |
| 225 | uintptr_t pc = this->pc(); |
| 226 | if ((pc & 0xfff) >= 7 && *(instruction_t*)(pc - 7) == 0xb8) { |
| 227 | int nr = *(int*)(pc - 6); |
| 228 | if (nr == SYS_ppoll |
| 229 | || (nr == SYS_poll && (int)REG(RDX, rdx) == -1) |
| 230 | || (nr == SYS_epoll_wait && (int)REG(R10, r10) == -1) |
| 231 | || (nr == SYS_epoll_pwait && (int)REG(R10, r10) == -1)) { |
| 232 | this->pc() = pc - 7; |
| 233 | } |
| 234 | } |
| 235 | return true; |
| 236 | } |
| 237 | return false; |
| 238 | #endif |
| 239 | } |
| 240 | |
| 241 | bool StackFrame::isSyscall(instruction_t* pc) { |
| 242 | return pc[0] == 0x0f && pc[1] == 0x05; |
nothing calls this directly
no outgoing calls
no test coverage detected