Fri, 08 Feb 2013 12:48:24 +0100
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
Summary: Do not rely on mach thread port names to identify threads from SA
Reviewed-by: dholmes, minqi, rbackman
never@3156 | 1 | /* |
kvn@3520 | 2 | * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. |
never@3156 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
never@3156 | 4 | * |
never@3156 | 5 | * This code is free software; you can redistribute it and/or modify it |
never@3156 | 6 | * under the terms of the GNU General Public License version 2 only, as |
never@3156 | 7 | * published by the Free Software Foundation. |
never@3156 | 8 | * |
never@3156 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
never@3156 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
never@3156 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
never@3156 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
never@3156 | 13 | * accompanied this code). |
never@3156 | 14 | * |
never@3156 | 15 | * You should have received a copy of the GNU General Public License version |
never@3156 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
never@3156 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
never@3156 | 18 | * |
never@3156 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
never@3156 | 20 | * or visit www.oracle.com if you need additional information or have any |
never@3156 | 21 | * questions. |
never@3156 | 22 | * |
never@3156 | 23 | */ |
never@3156 | 24 | |
never@3156 | 25 | // no precompiled headers |
twisti@4318 | 26 | #include "asm/macroAssembler.hpp" |
never@3156 | 27 | #include "classfile/classLoader.hpp" |
never@3156 | 28 | #include "classfile/systemDictionary.hpp" |
never@3156 | 29 | #include "classfile/vmSymbols.hpp" |
never@3156 | 30 | #include "code/icBuffer.hpp" |
never@3156 | 31 | #include "code/vtableStubs.hpp" |
never@3156 | 32 | #include "interpreter/interpreter.hpp" |
never@3156 | 33 | #include "jvm_bsd.h" |
never@3156 | 34 | #include "memory/allocation.inline.hpp" |
never@3156 | 35 | #include "mutex_bsd.inline.hpp" |
never@3156 | 36 | #include "os_share_bsd.hpp" |
never@3156 | 37 | #include "prims/jniFastGetField.hpp" |
never@3156 | 38 | #include "prims/jvm.h" |
never@3156 | 39 | #include "prims/jvm_misc.hpp" |
never@3156 | 40 | #include "runtime/arguments.hpp" |
never@3156 | 41 | #include "runtime/extendedPC.hpp" |
never@3156 | 42 | #include "runtime/frame.inline.hpp" |
never@3156 | 43 | #include "runtime/interfaceSupport.hpp" |
never@3156 | 44 | #include "runtime/java.hpp" |
never@3156 | 45 | #include "runtime/javaCalls.hpp" |
never@3156 | 46 | #include "runtime/mutexLocker.hpp" |
never@3156 | 47 | #include "runtime/osThread.hpp" |
never@3156 | 48 | #include "runtime/sharedRuntime.hpp" |
never@3156 | 49 | #include "runtime/stubRoutines.hpp" |
stefank@4299 | 50 | #include "runtime/thread.inline.hpp" |
never@3156 | 51 | #include "runtime/timer.hpp" |
never@3156 | 52 | #include "utilities/events.hpp" |
never@3156 | 53 | #include "utilities/vmError.hpp" |
never@3156 | 54 | |
never@3156 | 55 | // put OS-includes here |
never@3156 | 56 | # include <sys/types.h> |
never@3156 | 57 | # include <sys/mman.h> |
never@3156 | 58 | # include <pthread.h> |
never@3156 | 59 | # include <signal.h> |
never@3156 | 60 | # include <errno.h> |
never@3156 | 61 | # include <dlfcn.h> |
never@3156 | 62 | # include <stdlib.h> |
never@3156 | 63 | # include <stdio.h> |
never@3156 | 64 | # include <unistd.h> |
never@3156 | 65 | # include <sys/resource.h> |
never@3156 | 66 | # include <pthread.h> |
never@3156 | 67 | # include <sys/stat.h> |
never@3156 | 68 | # include <sys/time.h> |
never@3156 | 69 | # include <sys/utsname.h> |
never@3156 | 70 | # include <sys/socket.h> |
never@3156 | 71 | # include <sys/wait.h> |
never@3156 | 72 | # include <pwd.h> |
never@3156 | 73 | # include <poll.h> |
never@3156 | 74 | #ifndef __OpenBSD__ |
never@3156 | 75 | # include <ucontext.h> |
never@3156 | 76 | #endif |
never@3156 | 77 | |
sla@4229 | 78 | #if !defined(__APPLE__) && !defined(__NetBSD__) |
never@3156 | 79 | # include <pthread_np.h> |
never@3156 | 80 | #endif |
never@3156 | 81 | |
never@3156 | 82 | #ifdef AMD64 |
never@3156 | 83 | #define SPELL_REG_SP "rsp" |
never@3156 | 84 | #define SPELL_REG_FP "rbp" |
never@3156 | 85 | #else |
never@3156 | 86 | #define SPELL_REG_SP "esp" |
never@3156 | 87 | #define SPELL_REG_FP "ebp" |
never@3156 | 88 | #endif // AMD64 |
never@3156 | 89 | |
never@3156 | 90 | #ifdef __FreeBSD__ |
never@3156 | 91 | # define context_trapno uc_mcontext.mc_trapno |
never@3156 | 92 | # ifdef AMD64 |
never@3156 | 93 | # define context_pc uc_mcontext.mc_rip |
never@3156 | 94 | # define context_sp uc_mcontext.mc_rsp |
never@3156 | 95 | # define context_fp uc_mcontext.mc_rbp |
never@3156 | 96 | # define context_rip uc_mcontext.mc_rip |
never@3156 | 97 | # define context_rsp uc_mcontext.mc_rsp |
never@3156 | 98 | # define context_rbp uc_mcontext.mc_rbp |
never@3156 | 99 | # define context_rax uc_mcontext.mc_rax |
never@3156 | 100 | # define context_rbx uc_mcontext.mc_rbx |
never@3156 | 101 | # define context_rcx uc_mcontext.mc_rcx |
never@3156 | 102 | # define context_rdx uc_mcontext.mc_rdx |
never@3156 | 103 | # define context_rsi uc_mcontext.mc_rsi |
never@3156 | 104 | # define context_rdi uc_mcontext.mc_rdi |
never@3156 | 105 | # define context_r8 uc_mcontext.mc_r8 |
never@3156 | 106 | # define context_r9 uc_mcontext.mc_r9 |
never@3156 | 107 | # define context_r10 uc_mcontext.mc_r10 |
never@3156 | 108 | # define context_r11 uc_mcontext.mc_r11 |
never@3156 | 109 | # define context_r12 uc_mcontext.mc_r12 |
never@3156 | 110 | # define context_r13 uc_mcontext.mc_r13 |
never@3156 | 111 | # define context_r14 uc_mcontext.mc_r14 |
never@3156 | 112 | # define context_r15 uc_mcontext.mc_r15 |
never@3156 | 113 | # define context_flags uc_mcontext.mc_flags |
never@3156 | 114 | # define context_err uc_mcontext.mc_err |
never@3156 | 115 | # else |
never@3156 | 116 | # define context_pc uc_mcontext.mc_eip |
never@3156 | 117 | # define context_sp uc_mcontext.mc_esp |
never@3156 | 118 | # define context_fp uc_mcontext.mc_ebp |
never@3156 | 119 | # define context_eip uc_mcontext.mc_eip |
never@3156 | 120 | # define context_esp uc_mcontext.mc_esp |
never@3156 | 121 | # define context_eax uc_mcontext.mc_eax |
never@3156 | 122 | # define context_ebx uc_mcontext.mc_ebx |
never@3156 | 123 | # define context_ecx uc_mcontext.mc_ecx |
never@3156 | 124 | # define context_edx uc_mcontext.mc_edx |
never@3156 | 125 | # define context_ebp uc_mcontext.mc_ebp |
never@3156 | 126 | # define context_esi uc_mcontext.mc_esi |
never@3156 | 127 | # define context_edi uc_mcontext.mc_edi |
never@3156 | 128 | # define context_eflags uc_mcontext.mc_eflags |
never@3156 | 129 | # define context_trapno uc_mcontext.mc_trapno |
never@3156 | 130 | # endif |
never@3156 | 131 | #endif |
never@3156 | 132 | |
never@3156 | 133 | #ifdef __APPLE__ |
never@3156 | 134 | # if __DARWIN_UNIX03 && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) |
never@3156 | 135 | // 10.5 UNIX03 member name prefixes |
never@3156 | 136 | #define DU3_PREFIX(s, m) __ ## s.__ ## m |
never@3156 | 137 | # else |
never@3156 | 138 | #define DU3_PREFIX(s, m) s ## . ## m |
never@3156 | 139 | # endif |
never@3156 | 140 | |
never@3156 | 141 | # ifdef AMD64 |
never@3156 | 142 | # define context_pc context_rip |
never@3156 | 143 | # define context_sp context_rsp |
never@3156 | 144 | # define context_fp context_rbp |
never@3156 | 145 | # define context_rip uc_mcontext->DU3_PREFIX(ss,rip) |
never@3156 | 146 | # define context_rsp uc_mcontext->DU3_PREFIX(ss,rsp) |
never@3156 | 147 | # define context_rax uc_mcontext->DU3_PREFIX(ss,rax) |
never@3156 | 148 | # define context_rbx uc_mcontext->DU3_PREFIX(ss,rbx) |
never@3156 | 149 | # define context_rcx uc_mcontext->DU3_PREFIX(ss,rcx) |
never@3156 | 150 | # define context_rdx uc_mcontext->DU3_PREFIX(ss,rdx) |
never@3156 | 151 | # define context_rbp uc_mcontext->DU3_PREFIX(ss,rbp) |
never@3156 | 152 | # define context_rsi uc_mcontext->DU3_PREFIX(ss,rsi) |
never@3156 | 153 | # define context_rdi uc_mcontext->DU3_PREFIX(ss,rdi) |
never@3156 | 154 | # define context_r8 uc_mcontext->DU3_PREFIX(ss,r8) |
never@3156 | 155 | # define context_r9 uc_mcontext->DU3_PREFIX(ss,r9) |
never@3156 | 156 | # define context_r10 uc_mcontext->DU3_PREFIX(ss,r10) |
never@3156 | 157 | # define context_r11 uc_mcontext->DU3_PREFIX(ss,r11) |
never@3156 | 158 | # define context_r12 uc_mcontext->DU3_PREFIX(ss,r12) |
never@3156 | 159 | # define context_r13 uc_mcontext->DU3_PREFIX(ss,r13) |
never@3156 | 160 | # define context_r14 uc_mcontext->DU3_PREFIX(ss,r14) |
never@3156 | 161 | # define context_r15 uc_mcontext->DU3_PREFIX(ss,r15) |
never@3156 | 162 | # define context_flags uc_mcontext->DU3_PREFIX(ss,rflags) |
never@3156 | 163 | # define context_trapno uc_mcontext->DU3_PREFIX(es,trapno) |
never@3156 | 164 | # define context_err uc_mcontext->DU3_PREFIX(es,err) |
never@3156 | 165 | # else |
never@3156 | 166 | # define context_pc context_eip |
never@3156 | 167 | # define context_sp context_esp |
never@3156 | 168 | # define context_fp context_ebp |
never@3156 | 169 | # define context_eip uc_mcontext->DU3_PREFIX(ss,eip) |
never@3156 | 170 | # define context_esp uc_mcontext->DU3_PREFIX(ss,esp) |
never@3156 | 171 | # define context_eax uc_mcontext->DU3_PREFIX(ss,eax) |
never@3156 | 172 | # define context_ebx uc_mcontext->DU3_PREFIX(ss,ebx) |
never@3156 | 173 | # define context_ecx uc_mcontext->DU3_PREFIX(ss,ecx) |
never@3156 | 174 | # define context_edx uc_mcontext->DU3_PREFIX(ss,edx) |
never@3156 | 175 | # define context_ebp uc_mcontext->DU3_PREFIX(ss,ebp) |
never@3156 | 176 | # define context_esi uc_mcontext->DU3_PREFIX(ss,esi) |
never@3156 | 177 | # define context_edi uc_mcontext->DU3_PREFIX(ss,edi) |
never@3156 | 178 | # define context_eflags uc_mcontext->DU3_PREFIX(ss,eflags) |
never@3156 | 179 | # define context_trapno uc_mcontext->DU3_PREFIX(es,trapno) |
never@3156 | 180 | # endif |
never@3156 | 181 | #endif |
never@3156 | 182 | |
never@3156 | 183 | #ifdef __OpenBSD__ |
never@3156 | 184 | # define context_trapno sc_trapno |
never@3156 | 185 | # ifdef AMD64 |
never@3156 | 186 | # define context_pc sc_rip |
never@3156 | 187 | # define context_sp sc_rsp |
never@3156 | 188 | # define context_fp sc_rbp |
never@3156 | 189 | # define context_rip sc_rip |
never@3156 | 190 | # define context_rsp sc_rsp |
never@3156 | 191 | # define context_rbp sc_rbp |
never@3156 | 192 | # define context_rax sc_rax |
never@3156 | 193 | # define context_rbx sc_rbx |
never@3156 | 194 | # define context_rcx sc_rcx |
never@3156 | 195 | # define context_rdx sc_rdx |
never@3156 | 196 | # define context_rsi sc_rsi |
never@3156 | 197 | # define context_rdi sc_rdi |
never@3156 | 198 | # define context_r8 sc_r8 |
never@3156 | 199 | # define context_r9 sc_r9 |
never@3156 | 200 | # define context_r10 sc_r10 |
never@3156 | 201 | # define context_r11 sc_r11 |
never@3156 | 202 | # define context_r12 sc_r12 |
never@3156 | 203 | # define context_r13 sc_r13 |
never@3156 | 204 | # define context_r14 sc_r14 |
never@3156 | 205 | # define context_r15 sc_r15 |
never@3156 | 206 | # define context_flags sc_rflags |
never@3156 | 207 | # define context_err sc_err |
never@3156 | 208 | # else |
never@3156 | 209 | # define context_pc sc_eip |
never@3156 | 210 | # define context_sp sc_esp |
never@3156 | 211 | # define context_fp sc_ebp |
never@3156 | 212 | # define context_eip sc_eip |
never@3156 | 213 | # define context_esp sc_esp |
never@3156 | 214 | # define context_eax sc_eax |
never@3156 | 215 | # define context_ebx sc_ebx |
never@3156 | 216 | # define context_ecx sc_ecx |
never@3156 | 217 | # define context_edx sc_edx |
never@3156 | 218 | # define context_ebp sc_ebp |
never@3156 | 219 | # define context_esi sc_esi |
never@3156 | 220 | # define context_edi sc_edi |
never@3156 | 221 | # define context_eflags sc_eflags |
never@3156 | 222 | # define context_trapno sc_trapno |
never@3156 | 223 | # endif |
never@3156 | 224 | #endif |
never@3156 | 225 | |
never@3156 | 226 | #ifdef __NetBSD__ |
never@3156 | 227 | # define context_trapno uc_mcontext.__gregs[_REG_TRAPNO] |
never@3156 | 228 | # ifdef AMD64 |
never@3156 | 229 | # define __register_t __greg_t |
never@3156 | 230 | # define context_pc uc_mcontext.__gregs[_REG_RIP] |
never@3156 | 231 | # define context_sp uc_mcontext.__gregs[_REG_URSP] |
never@3156 | 232 | # define context_fp uc_mcontext.__gregs[_REG_RBP] |
never@3156 | 233 | # define context_rip uc_mcontext.__gregs[_REG_RIP] |
never@3156 | 234 | # define context_rsp uc_mcontext.__gregs[_REG_URSP] |
never@3156 | 235 | # define context_rax uc_mcontext.__gregs[_REG_RAX] |
never@3156 | 236 | # define context_rbx uc_mcontext.__gregs[_REG_RBX] |
never@3156 | 237 | # define context_rcx uc_mcontext.__gregs[_REG_RCX] |
never@3156 | 238 | # define context_rdx uc_mcontext.__gregs[_REG_RDX] |
never@3156 | 239 | # define context_rbp uc_mcontext.__gregs[_REG_RBP] |
never@3156 | 240 | # define context_rsi uc_mcontext.__gregs[_REG_RSI] |
never@3156 | 241 | # define context_rdi uc_mcontext.__gregs[_REG_RDI] |
never@3156 | 242 | # define context_r8 uc_mcontext.__gregs[_REG_R8] |
never@3156 | 243 | # define context_r9 uc_mcontext.__gregs[_REG_R9] |
never@3156 | 244 | # define context_r10 uc_mcontext.__gregs[_REG_R10] |
never@3156 | 245 | # define context_r11 uc_mcontext.__gregs[_REG_R11] |
never@3156 | 246 | # define context_r12 uc_mcontext.__gregs[_REG_R12] |
never@3156 | 247 | # define context_r13 uc_mcontext.__gregs[_REG_R13] |
never@3156 | 248 | # define context_r14 uc_mcontext.__gregs[_REG_R14] |
never@3156 | 249 | # define context_r15 uc_mcontext.__gregs[_REG_R15] |
never@3156 | 250 | # define context_flags uc_mcontext.__gregs[_REG_RFL] |
never@3156 | 251 | # define context_err uc_mcontext.__gregs[_REG_ERR] |
never@3156 | 252 | # else |
never@3156 | 253 | # define context_pc uc_mcontext.__gregs[_REG_EIP] |
never@3156 | 254 | # define context_sp uc_mcontext.__gregs[_REG_UESP] |
never@3156 | 255 | # define context_fp uc_mcontext.__gregs[_REG_EBP] |
never@3156 | 256 | # define context_eip uc_mcontext.__gregs[_REG_EIP] |
never@3156 | 257 | # define context_esp uc_mcontext.__gregs[_REG_UESP] |
never@3156 | 258 | # define context_eax uc_mcontext.__gregs[_REG_EAX] |
never@3156 | 259 | # define context_ebx uc_mcontext.__gregs[_REG_EBX] |
never@3156 | 260 | # define context_ecx uc_mcontext.__gregs[_REG_ECX] |
never@3156 | 261 | # define context_edx uc_mcontext.__gregs[_REG_EDX] |
never@3156 | 262 | # define context_ebp uc_mcontext.__gregs[_REG_EBP] |
never@3156 | 263 | # define context_esi uc_mcontext.__gregs[_REG_ESI] |
never@3156 | 264 | # define context_edi uc_mcontext.__gregs[_REG_EDI] |
never@3156 | 265 | # define context_eflags uc_mcontext.__gregs[_REG_EFL] |
never@3156 | 266 | # define context_trapno uc_mcontext.__gregs[_REG_TRAPNO] |
never@3156 | 267 | # endif |
never@3156 | 268 | #endif |
never@3156 | 269 | |
never@3156 | 270 | address os::current_stack_pointer() { |
dcubed@3202 | 271 | #if defined(__clang__) || defined(__llvm__) |
dcubed@3202 | 272 | register void *esp; |
dcubed@3202 | 273 | __asm__("mov %%"SPELL_REG_SP", %0":"=r"(esp)); |
dcubed@3202 | 274 | return (address) esp; |
dcubed@3202 | 275 | #elif defined(SPARC_WORKS) |
never@3156 | 276 | register void *esp; |
never@3156 | 277 | __asm__("mov %%"SPELL_REG_SP", %0":"=r"(esp)); |
never@3156 | 278 | return (address) ((char*)esp + sizeof(long)*2); |
never@3156 | 279 | #else |
never@3156 | 280 | register void *esp __asm__ (SPELL_REG_SP); |
never@3156 | 281 | return (address) esp; |
never@3156 | 282 | #endif |
never@3156 | 283 | } |
never@3156 | 284 | |
never@3156 | 285 | char* os::non_memory_address_word() { |
never@3156 | 286 | // Must never look like an address returned by reserve_memory, |
never@3156 | 287 | // even in its subfields (as defined by the CPU immediate fields, |
never@3156 | 288 | // if the CPU splits constants across multiple instructions). |
never@3156 | 289 | |
never@3156 | 290 | return (char*) -1; |
never@3156 | 291 | } |
never@3156 | 292 | |
zgu@4079 | 293 | void os::initialize_thread(Thread* thr) { |
never@3156 | 294 | // Nothing to do. |
never@3156 | 295 | } |
never@3156 | 296 | |
never@3156 | 297 | address os::Bsd::ucontext_get_pc(ucontext_t * uc) { |
never@3156 | 298 | return (address)uc->context_pc; |
never@3156 | 299 | } |
never@3156 | 300 | |
never@3156 | 301 | intptr_t* os::Bsd::ucontext_get_sp(ucontext_t * uc) { |
never@3156 | 302 | return (intptr_t*)uc->context_sp; |
never@3156 | 303 | } |
never@3156 | 304 | |
never@3156 | 305 | intptr_t* os::Bsd::ucontext_get_fp(ucontext_t * uc) { |
never@3156 | 306 | return (intptr_t*)uc->context_fp; |
never@3156 | 307 | } |
never@3156 | 308 | |
never@3156 | 309 | // For Forte Analyzer AsyncGetCallTrace profiling support - thread |
never@3156 | 310 | // is currently interrupted by SIGPROF. |
never@3156 | 311 | // os::Solaris::fetch_frame_from_ucontext() tries to skip nested signal |
never@3156 | 312 | // frames. Currently we don't do that on Bsd, so it's the same as |
never@3156 | 313 | // os::fetch_frame_from_context(). |
never@3156 | 314 | ExtendedPC os::Bsd::fetch_frame_from_ucontext(Thread* thread, |
never@3156 | 315 | ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) { |
never@3156 | 316 | |
never@3156 | 317 | assert(thread != NULL, "just checking"); |
never@3156 | 318 | assert(ret_sp != NULL, "just checking"); |
never@3156 | 319 | assert(ret_fp != NULL, "just checking"); |
never@3156 | 320 | |
never@3156 | 321 | return os::fetch_frame_from_context(uc, ret_sp, ret_fp); |
never@3156 | 322 | } |
never@3156 | 323 | |
never@3156 | 324 | ExtendedPC os::fetch_frame_from_context(void* ucVoid, |
never@3156 | 325 | intptr_t** ret_sp, intptr_t** ret_fp) { |
never@3156 | 326 | |
never@3156 | 327 | ExtendedPC epc; |
never@3156 | 328 | ucontext_t* uc = (ucontext_t*)ucVoid; |
never@3156 | 329 | |
never@3156 | 330 | if (uc != NULL) { |
never@3156 | 331 | epc = ExtendedPC(os::Bsd::ucontext_get_pc(uc)); |
never@3156 | 332 | if (ret_sp) *ret_sp = os::Bsd::ucontext_get_sp(uc); |
never@3156 | 333 | if (ret_fp) *ret_fp = os::Bsd::ucontext_get_fp(uc); |
never@3156 | 334 | } else { |
never@3156 | 335 | // construct empty ExtendedPC for return value checking |
never@3156 | 336 | epc = ExtendedPC(NULL); |
never@3156 | 337 | if (ret_sp) *ret_sp = (intptr_t *)NULL; |
never@3156 | 338 | if (ret_fp) *ret_fp = (intptr_t *)NULL; |
never@3156 | 339 | } |
never@3156 | 340 | |
never@3156 | 341 | return epc; |
never@3156 | 342 | } |
never@3156 | 343 | |
never@3156 | 344 | frame os::fetch_frame_from_context(void* ucVoid) { |
never@3156 | 345 | intptr_t* sp; |
never@3156 | 346 | intptr_t* fp; |
never@3156 | 347 | ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp); |
never@3156 | 348 | return frame(sp, fp, epc.pc()); |
never@3156 | 349 | } |
never@3156 | 350 | |
never@3156 | 351 | // By default, gcc always save frame pointer (%ebp/%rbp) on stack. It may get |
never@3156 | 352 | // turned off by -fomit-frame-pointer, |
never@3156 | 353 | frame os::get_sender_for_C_frame(frame* fr) { |
never@3156 | 354 | return frame(fr->sender_sp(), fr->link(), fr->sender_pc()); |
never@3156 | 355 | } |
never@3156 | 356 | |
never@3156 | 357 | intptr_t* _get_previous_fp() { |
kvn@3520 | 358 | #if defined(SPARC_WORKS) || defined(__clang__) || defined(__llvm__) |
never@3156 | 359 | register intptr_t **ebp; |
never@3156 | 360 | __asm__("mov %%"SPELL_REG_FP", %0":"=r"(ebp)); |
never@3156 | 361 | #else |
never@3156 | 362 | register intptr_t **ebp __asm__ (SPELL_REG_FP); |
never@3156 | 363 | #endif |
never@3156 | 364 | return (intptr_t*) *ebp; // we want what it points to. |
never@3156 | 365 | } |
never@3156 | 366 | |
never@3156 | 367 | |
never@3156 | 368 | frame os::current_frame() { |
never@3156 | 369 | intptr_t* fp = _get_previous_fp(); |
never@3156 | 370 | frame myframe((intptr_t*)os::current_stack_pointer(), |
never@3156 | 371 | (intptr_t*)fp, |
never@3156 | 372 | CAST_FROM_FN_PTR(address, os::current_frame)); |
never@3156 | 373 | if (os::is_first_C_frame(&myframe)) { |
never@3156 | 374 | // stack is not walkable |
dholmes@4528 | 375 | return frame(); |
never@3156 | 376 | } else { |
never@3156 | 377 | return os::get_sender_for_C_frame(&myframe); |
never@3156 | 378 | } |
never@3156 | 379 | } |
never@3156 | 380 | |
never@3156 | 381 | // Utility functions |
never@3156 | 382 | |
never@3156 | 383 | // From IA32 System Programming Guide |
never@3156 | 384 | enum { |
never@3156 | 385 | trap_page_fault = 0xE |
never@3156 | 386 | }; |
never@3156 | 387 | |
never@3156 | 388 | extern "C" void Fetch32PFI () ; |
never@3156 | 389 | extern "C" void Fetch32Resume () ; |
never@3156 | 390 | #ifdef AMD64 |
never@3156 | 391 | extern "C" void FetchNPFI () ; |
never@3156 | 392 | extern "C" void FetchNResume () ; |
never@3156 | 393 | #endif // AMD64 |
never@3156 | 394 | |
never@3156 | 395 | extern "C" JNIEXPORT int |
never@3156 | 396 | JVM_handle_bsd_signal(int sig, |
never@3156 | 397 | siginfo_t* info, |
never@3156 | 398 | void* ucVoid, |
never@3156 | 399 | int abort_if_unrecognized) { |
never@3156 | 400 | ucontext_t* uc = (ucontext_t*) ucVoid; |
never@3156 | 401 | |
never@3156 | 402 | Thread* t = ThreadLocalStorage::get_thread_slow(); |
never@3156 | 403 | |
never@3156 | 404 | SignalHandlerMark shm(t); |
never@3156 | 405 | |
never@3156 | 406 | // Note: it's not uncommon that JNI code uses signal/sigset to install |
never@3156 | 407 | // then restore certain signal handler (e.g. to temporarily block SIGPIPE, |
never@3156 | 408 | // or have a SIGILL handler when detecting CPU type). When that happens, |
never@3156 | 409 | // JVM_handle_bsd_signal() might be invoked with junk info/ucVoid. To |
never@3156 | 410 | // avoid unnecessary crash when libjsig is not preloaded, try handle signals |
never@3156 | 411 | // that do not require siginfo/ucontext first. |
never@3156 | 412 | |
never@3156 | 413 | if (sig == SIGPIPE || sig == SIGXFSZ) { |
never@3156 | 414 | // allow chained handler to go first |
never@3156 | 415 | if (os::Bsd::chained_handler(sig, info, ucVoid)) { |
never@3156 | 416 | return true; |
never@3156 | 417 | } else { |
never@3156 | 418 | if (PrintMiscellaneous && (WizardMode || Verbose)) { |
never@3156 | 419 | char buf[64]; |
never@3156 | 420 | warning("Ignoring %s - see bugs 4229104 or 646499219", |
never@3156 | 421 | os::exception_name(sig, buf, sizeof(buf))); |
never@3156 | 422 | } |
never@3156 | 423 | return true; |
never@3156 | 424 | } |
never@3156 | 425 | } |
never@3156 | 426 | |
never@3156 | 427 | JavaThread* thread = NULL; |
never@3156 | 428 | VMThread* vmthread = NULL; |
never@3156 | 429 | if (os::Bsd::signal_handlers_are_installed) { |
never@3156 | 430 | if (t != NULL ){ |
never@3156 | 431 | if(t->is_Java_thread()) { |
never@3156 | 432 | thread = (JavaThread*)t; |
never@3156 | 433 | } |
never@3156 | 434 | else if(t->is_VM_thread()){ |
never@3156 | 435 | vmthread = (VMThread *)t; |
never@3156 | 436 | } |
never@3156 | 437 | } |
never@3156 | 438 | } |
never@3156 | 439 | /* |
never@3156 | 440 | NOTE: does not seem to work on bsd. |
never@3156 | 441 | if (info == NULL || info->si_code <= 0 || info->si_code == SI_NOINFO) { |
never@3156 | 442 | // can't decode this kind of signal |
never@3156 | 443 | info = NULL; |
never@3156 | 444 | } else { |
never@3156 | 445 | assert(sig == info->si_signo, "bad siginfo"); |
never@3156 | 446 | } |
never@3156 | 447 | */ |
never@3156 | 448 | // decide if this trap can be handled by a stub |
never@3156 | 449 | address stub = NULL; |
never@3156 | 450 | |
never@3156 | 451 | address pc = NULL; |
never@3156 | 452 | |
never@3156 | 453 | //%note os_trap_1 |
never@3156 | 454 | if (info != NULL && uc != NULL && thread != NULL) { |
never@3156 | 455 | pc = (address) os::Bsd::ucontext_get_pc(uc); |
never@3156 | 456 | |
never@3156 | 457 | if (pc == (address) Fetch32PFI) { |
never@3156 | 458 | uc->context_pc = intptr_t(Fetch32Resume) ; |
never@3156 | 459 | return 1 ; |
never@3156 | 460 | } |
never@3156 | 461 | #ifdef AMD64 |
never@3156 | 462 | if (pc == (address) FetchNPFI) { |
never@3156 | 463 | uc->context_pc = intptr_t (FetchNResume) ; |
never@3156 | 464 | return 1 ; |
never@3156 | 465 | } |
never@3156 | 466 | #endif // AMD64 |
never@3156 | 467 | |
never@3156 | 468 | // Handle ALL stack overflow variations here |
never@3156 | 469 | if (sig == SIGSEGV || sig == SIGBUS) { |
never@3156 | 470 | address addr = (address) info->si_addr; |
never@3156 | 471 | |
never@3156 | 472 | // check if fault address is within thread stack |
never@3156 | 473 | if (addr < thread->stack_base() && |
never@3156 | 474 | addr >= thread->stack_base() - thread->stack_size()) { |
never@3156 | 475 | // stack overflow |
never@3156 | 476 | if (thread->in_stack_yellow_zone(addr)) { |
never@3156 | 477 | thread->disable_stack_yellow_zone(); |
never@3156 | 478 | if (thread->thread_state() == _thread_in_Java) { |
never@3156 | 479 | // Throw a stack overflow exception. Guard pages will be reenabled |
never@3156 | 480 | // while unwinding the stack. |
never@3156 | 481 | stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW); |
never@3156 | 482 | } else { |
never@3156 | 483 | // Thread was in the vm or native code. Return and try to finish. |
never@3156 | 484 | return 1; |
never@3156 | 485 | } |
never@3156 | 486 | } else if (thread->in_stack_red_zone(addr)) { |
never@3156 | 487 | // Fatal red zone violation. Disable the guard pages and fall through |
never@3156 | 488 | // to handle_unexpected_exception way down below. |
never@3156 | 489 | thread->disable_stack_red_zone(); |
never@3156 | 490 | tty->print_raw_cr("An irrecoverable stack overflow has occurred."); |
never@3156 | 491 | } |
never@3156 | 492 | } |
never@3156 | 493 | } |
never@3156 | 494 | |
roland@3887 | 495 | // We test if stub is already set (by the stack overflow code |
roland@3887 | 496 | // above) so it is not overwritten by the code that follows. This |
roland@3887 | 497 | // check is not required on other platforms, because on other |
roland@3887 | 498 | // platforms we check for SIGSEGV only or SIGBUS only, where here |
roland@3887 | 499 | // we have to check for both SIGSEGV and SIGBUS. |
roland@3887 | 500 | if (thread->thread_state() == _thread_in_Java && stub == NULL) { |
never@3156 | 501 | // Java thread running in Java code => find exception handler if any |
never@3156 | 502 | // a fault inside compiled code, the interpreter, or a stub |
never@3156 | 503 | |
never@3156 | 504 | if ((sig == SIGSEGV || sig == SIGBUS) && os::is_poll_address((address)info->si_addr)) { |
never@3156 | 505 | stub = SharedRuntime::get_poll_stub(pc); |
roland@3788 | 506 | #if defined(__APPLE__) |
never@3156 | 507 | // 32-bit Darwin reports a SIGBUS for nearly all memory access exceptions. |
roland@3788 | 508 | // 64-bit Darwin may also use a SIGBUS (seen with compressed oops). |
never@3156 | 509 | // Catching SIGBUS here prevents the implicit SIGBUS NULL check below from |
never@3156 | 510 | // being called, so only do so if the implicit NULL check is not necessary. |
roland@3788 | 511 | } else if (sig == SIGBUS && MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) { |
never@3156 | 512 | #else |
never@3156 | 513 | } else if (sig == SIGBUS /* && info->si_code == BUS_OBJERR */) { |
never@3156 | 514 | #endif |
never@3156 | 515 | // BugId 4454115: A read from a MappedByteBuffer can fault |
never@3156 | 516 | // here if the underlying file has been truncated. |
never@3156 | 517 | // Do not crash the VM in such a case. |
never@3156 | 518 | CodeBlob* cb = CodeCache::find_blob_unsafe(pc); |
never@3156 | 519 | nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL; |
never@3156 | 520 | if (nm != NULL && nm->has_unsafe_access()) { |
never@3156 | 521 | stub = StubRoutines::handler_for_unsafe_access(); |
never@3156 | 522 | } |
never@3156 | 523 | } |
never@3156 | 524 | else |
never@3156 | 525 | |
never@3156 | 526 | #ifdef AMD64 |
never@3156 | 527 | if (sig == SIGFPE && |
never@3156 | 528 | (info->si_code == FPE_INTDIV || info->si_code == FPE_FLTDIV)) { |
never@3156 | 529 | stub = |
never@3156 | 530 | SharedRuntime:: |
never@3156 | 531 | continuation_for_implicit_exception(thread, |
never@3156 | 532 | pc, |
never@3156 | 533 | SharedRuntime:: |
never@3156 | 534 | IMPLICIT_DIVIDE_BY_ZERO); |
never@3156 | 535 | #ifdef __APPLE__ |
never@3156 | 536 | } else if (sig == SIGFPE && info->si_code == FPE_NOOP) { |
never@3156 | 537 | int op = pc[0]; |
never@3156 | 538 | |
never@3156 | 539 | // Skip REX |
never@3156 | 540 | if ((pc[0] & 0xf0) == 0x40) { |
never@3156 | 541 | op = pc[1]; |
never@3156 | 542 | } else { |
never@3156 | 543 | op = pc[0]; |
never@3156 | 544 | } |
never@3156 | 545 | |
never@3156 | 546 | // Check for IDIV |
never@3156 | 547 | if (op == 0xF7) { |
never@3156 | 548 | stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime:: IMPLICIT_DIVIDE_BY_ZERO); |
never@3156 | 549 | } else { |
never@3156 | 550 | // TODO: handle more cases if we are using other x86 instructions |
never@3156 | 551 | // that can generate SIGFPE signal. |
never@3156 | 552 | tty->print_cr("unknown opcode 0x%X with SIGFPE.", op); |
never@3156 | 553 | fatal("please update this code."); |
never@3156 | 554 | } |
never@3156 | 555 | #endif /* __APPLE__ */ |
never@3156 | 556 | |
never@3156 | 557 | #else |
never@3156 | 558 | if (sig == SIGFPE /* && info->si_code == FPE_INTDIV */) { |
never@3156 | 559 | // HACK: si_code does not work on bsd 2.2.12-20!!! |
never@3156 | 560 | int op = pc[0]; |
never@3156 | 561 | if (op == 0xDB) { |
never@3156 | 562 | // FIST |
never@3156 | 563 | // TODO: The encoding of D2I in i486.ad can cause an exception |
never@3156 | 564 | // prior to the fist instruction if there was an invalid operation |
never@3156 | 565 | // pending. We want to dismiss that exception. From the win_32 |
never@3156 | 566 | // side it also seems that if it really was the fist causing |
never@3156 | 567 | // the exception that we do the d2i by hand with different |
never@3156 | 568 | // rounding. Seems kind of weird. |
never@3156 | 569 | // NOTE: that we take the exception at the NEXT floating point instruction. |
never@3156 | 570 | assert(pc[0] == 0xDB, "not a FIST opcode"); |
never@3156 | 571 | assert(pc[1] == 0x14, "not a FIST opcode"); |
never@3156 | 572 | assert(pc[2] == 0x24, "not a FIST opcode"); |
never@3156 | 573 | return true; |
never@3156 | 574 | } else if (op == 0xF7) { |
never@3156 | 575 | // IDIV |
never@3156 | 576 | stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO); |
never@3156 | 577 | } else { |
never@3156 | 578 | // TODO: handle more cases if we are using other x86 instructions |
never@3156 | 579 | // that can generate SIGFPE signal on bsd. |
never@3156 | 580 | tty->print_cr("unknown opcode 0x%X with SIGFPE.", op); |
never@3156 | 581 | fatal("please update this code."); |
never@3156 | 582 | } |
never@3156 | 583 | #endif // AMD64 |
never@3156 | 584 | } else if ((sig == SIGSEGV || sig == SIGBUS) && |
never@3156 | 585 | !MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) { |
never@3156 | 586 | // Determination of interpreter/vtable stub/compiled code null exception |
never@3156 | 587 | stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); |
never@3156 | 588 | } |
never@3156 | 589 | } else if (thread->thread_state() == _thread_in_vm && |
never@3156 | 590 | sig == SIGBUS && /* info->si_code == BUS_OBJERR && */ |
never@3156 | 591 | thread->doing_unsafe_access()) { |
never@3156 | 592 | stub = StubRoutines::handler_for_unsafe_access(); |
never@3156 | 593 | } |
never@3156 | 594 | |
never@3156 | 595 | // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in |
never@3156 | 596 | // and the heap gets shrunk before the field access. |
never@3156 | 597 | if ((sig == SIGSEGV) || (sig == SIGBUS)) { |
never@3156 | 598 | address addr = JNI_FastGetField::find_slowcase_pc(pc); |
never@3156 | 599 | if (addr != (address)-1) { |
never@3156 | 600 | stub = addr; |
never@3156 | 601 | } |
never@3156 | 602 | } |
never@3156 | 603 | |
never@3156 | 604 | // Check to see if we caught the safepoint code in the |
never@3156 | 605 | // process of write protecting the memory serialization page. |
never@3156 | 606 | // It write enables the page immediately after protecting it |
never@3156 | 607 | // so we can just return to retry the write. |
never@3156 | 608 | if ((sig == SIGSEGV || sig == SIGBUS) && |
never@3156 | 609 | os::is_memory_serialize_page(thread, (address) info->si_addr)) { |
never@3156 | 610 | // Block current thread until the memory serialize page permission restored. |
never@3156 | 611 | os::block_on_serialize_page_trap(); |
never@3156 | 612 | return true; |
never@3156 | 613 | } |
never@3156 | 614 | } |
never@3156 | 615 | |
never@3156 | 616 | #ifndef AMD64 |
never@3156 | 617 | // Execution protection violation |
never@3156 | 618 | // |
never@3156 | 619 | // This should be kept as the last step in the triage. We don't |
never@3156 | 620 | // have a dedicated trap number for a no-execute fault, so be |
never@3156 | 621 | // conservative and allow other handlers the first shot. |
never@3156 | 622 | // |
never@3156 | 623 | // Note: We don't test that info->si_code == SEGV_ACCERR here. |
never@3156 | 624 | // this si_code is so generic that it is almost meaningless; and |
never@3156 | 625 | // the si_code for this condition may change in the future. |
never@3156 | 626 | // Furthermore, a false-positive should be harmless. |
never@3156 | 627 | if (UnguardOnExecutionViolation > 0 && |
never@3156 | 628 | (sig == SIGSEGV || sig == SIGBUS) && |
never@3156 | 629 | uc->context_trapno == trap_page_fault) { |
never@3156 | 630 | int page_size = os::vm_page_size(); |
never@3156 | 631 | address addr = (address) info->si_addr; |
never@3156 | 632 | address pc = os::Bsd::ucontext_get_pc(uc); |
never@3156 | 633 | // Make sure the pc and the faulting address are sane. |
never@3156 | 634 | // |
never@3156 | 635 | // If an instruction spans a page boundary, and the page containing |
never@3156 | 636 | // the beginning of the instruction is executable but the following |
never@3156 | 637 | // page is not, the pc and the faulting address might be slightly |
never@3156 | 638 | // different - we still want to unguard the 2nd page in this case. |
never@3156 | 639 | // |
never@3156 | 640 | // 15 bytes seems to be a (very) safe value for max instruction size. |
never@3156 | 641 | bool pc_is_near_addr = |
never@3156 | 642 | (pointer_delta((void*) addr, (void*) pc, sizeof(char)) < 15); |
never@3156 | 643 | bool instr_spans_page_boundary = |
never@3156 | 644 | (align_size_down((intptr_t) pc ^ (intptr_t) addr, |
never@3156 | 645 | (intptr_t) page_size) > 0); |
never@3156 | 646 | |
never@3156 | 647 | if (pc == addr || (pc_is_near_addr && instr_spans_page_boundary)) { |
never@3156 | 648 | static volatile address last_addr = |
never@3156 | 649 | (address) os::non_memory_address_word(); |
never@3156 | 650 | |
never@3156 | 651 | // In conservative mode, don't unguard unless the address is in the VM |
never@3156 | 652 | if (addr != last_addr && |
never@3156 | 653 | (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) { |
never@3156 | 654 | |
never@3156 | 655 | // Set memory to RWX and retry |
never@3156 | 656 | address page_start = |
never@3156 | 657 | (address) align_size_down((intptr_t) addr, (intptr_t) page_size); |
never@3156 | 658 | bool res = os::protect_memory((char*) page_start, page_size, |
never@3156 | 659 | os::MEM_PROT_RWX); |
never@3156 | 660 | |
never@3156 | 661 | if (PrintMiscellaneous && Verbose) { |
never@3156 | 662 | char buf[256]; |
never@3156 | 663 | jio_snprintf(buf, sizeof(buf), "Execution protection violation " |
never@3156 | 664 | "at " INTPTR_FORMAT |
never@3156 | 665 | ", unguarding " INTPTR_FORMAT ": %s, errno=%d", addr, |
never@3156 | 666 | page_start, (res ? "success" : "failed"), errno); |
never@3156 | 667 | tty->print_raw_cr(buf); |
never@3156 | 668 | } |
never@3156 | 669 | stub = pc; |
never@3156 | 670 | |
never@3156 | 671 | // Set last_addr so if we fault again at the same address, we don't end |
never@3156 | 672 | // up in an endless loop. |
never@3156 | 673 | // |
never@3156 | 674 | // There are two potential complications here. Two threads trapping at |
never@3156 | 675 | // the same address at the same time could cause one of the threads to |
never@3156 | 676 | // think it already unguarded, and abort the VM. Likely very rare. |
never@3156 | 677 | // |
never@3156 | 678 | // The other race involves two threads alternately trapping at |
never@3156 | 679 | // different addresses and failing to unguard the page, resulting in |
never@3156 | 680 | // an endless loop. This condition is probably even more unlikely than |
never@3156 | 681 | // the first. |
never@3156 | 682 | // |
never@3156 | 683 | // Although both cases could be avoided by using locks or thread local |
never@3156 | 684 | // last_addr, these solutions are unnecessary complication: this |
never@3156 | 685 | // handler is a best-effort safety net, not a complete solution. It is |
never@3156 | 686 | // disabled by default and should only be used as a workaround in case |
never@3156 | 687 | // we missed any no-execute-unsafe VM code. |
never@3156 | 688 | |
never@3156 | 689 | last_addr = addr; |
never@3156 | 690 | } |
never@3156 | 691 | } |
never@3156 | 692 | } |
never@3156 | 693 | #endif // !AMD64 |
never@3156 | 694 | |
never@3156 | 695 | if (stub != NULL) { |
never@3156 | 696 | // save all thread context in case we need to restore it |
never@3156 | 697 | if (thread != NULL) thread->set_saved_exception_pc(pc); |
never@3156 | 698 | |
never@3156 | 699 | uc->context_pc = (intptr_t)stub; |
never@3156 | 700 | return true; |
never@3156 | 701 | } |
never@3156 | 702 | |
never@3156 | 703 | // signal-chaining |
never@3156 | 704 | if (os::Bsd::chained_handler(sig, info, ucVoid)) { |
never@3156 | 705 | return true; |
never@3156 | 706 | } |
never@3156 | 707 | |
never@3156 | 708 | if (!abort_if_unrecognized) { |
never@3156 | 709 | // caller wants another chance, so give it to him |
never@3156 | 710 | return false; |
never@3156 | 711 | } |
never@3156 | 712 | |
never@3156 | 713 | if (pc == NULL && uc != NULL) { |
never@3156 | 714 | pc = os::Bsd::ucontext_get_pc(uc); |
never@3156 | 715 | } |
never@3156 | 716 | |
never@3156 | 717 | // unmask current signal |
never@3156 | 718 | sigset_t newset; |
never@3156 | 719 | sigemptyset(&newset); |
never@3156 | 720 | sigaddset(&newset, sig); |
never@3156 | 721 | sigprocmask(SIG_UNBLOCK, &newset, NULL); |
never@3156 | 722 | |
never@3156 | 723 | VMError err(t, sig, pc, info, ucVoid); |
never@3156 | 724 | err.report_and_die(); |
never@3156 | 725 | |
never@3156 | 726 | ShouldNotReachHere(); |
never@3156 | 727 | } |
never@3156 | 728 | |
never@3156 | 729 | // From solaris_i486.s ported to bsd_i486.s |
never@3156 | 730 | extern "C" void fixcw(); |
never@3156 | 731 | |
never@3156 | 732 | void os::Bsd::init_thread_fpu_state(void) { |
never@3156 | 733 | #ifndef AMD64 |
never@3156 | 734 | // Set fpu to 53 bit precision. This happens too early to use a stub. |
never@3156 | 735 | fixcw(); |
never@3156 | 736 | #endif // !AMD64 |
never@3156 | 737 | } |
never@3156 | 738 | |
never@3156 | 739 | |
never@3156 | 740 | // Check that the bsd kernel version is 2.4 or higher since earlier |
never@3156 | 741 | // versions do not support SSE without patches. |
never@3156 | 742 | bool os::supports_sse() { |
never@3156 | 743 | return true; |
never@3156 | 744 | } |
never@3156 | 745 | |
never@3156 | 746 | bool os::is_allocatable(size_t bytes) { |
never@3156 | 747 | #ifdef AMD64 |
never@3156 | 748 | // unused on amd64? |
never@3156 | 749 | return true; |
never@3156 | 750 | #else |
never@3156 | 751 | |
never@3156 | 752 | if (bytes < 2 * G) { |
never@3156 | 753 | return true; |
never@3156 | 754 | } |
never@3156 | 755 | |
never@3156 | 756 | char* addr = reserve_memory(bytes, NULL); |
never@3156 | 757 | |
never@3156 | 758 | if (addr != NULL) { |
never@3156 | 759 | release_memory(addr, bytes); |
never@3156 | 760 | } |
never@3156 | 761 | |
never@3156 | 762 | return addr != NULL; |
never@3156 | 763 | #endif // AMD64 |
never@3156 | 764 | } |
never@3156 | 765 | |
never@3156 | 766 | //////////////////////////////////////////////////////////////////////////////// |
never@3156 | 767 | // thread stack |
never@3156 | 768 | |
never@3156 | 769 | #ifdef AMD64 |
never@3156 | 770 | size_t os::Bsd::min_stack_allowed = 64 * K; |
never@3156 | 771 | |
never@3156 | 772 | // amd64: pthread on amd64 is always in floating stack mode |
never@3156 | 773 | bool os::Bsd::supports_variable_stack_size() { return true; } |
never@3156 | 774 | #else |
never@3156 | 775 | size_t os::Bsd::min_stack_allowed = (48 DEBUG_ONLY(+4))*K; |
never@3156 | 776 | |
never@3156 | 777 | #ifdef __GNUC__ |
never@3156 | 778 | #define GET_GS() ({int gs; __asm__ volatile("movw %%gs, %w0":"=q"(gs)); gs&0xffff;}) |
never@3156 | 779 | #endif |
never@3156 | 780 | |
never@3156 | 781 | bool os::Bsd::supports_variable_stack_size() { return true; } |
never@3156 | 782 | #endif // AMD64 |
never@3156 | 783 | |
never@3156 | 784 | // return default stack size for thr_type |
never@3156 | 785 | size_t os::Bsd::default_stack_size(os::ThreadType thr_type) { |
never@3156 | 786 | // default stack size (compiler thread needs larger stack) |
never@3156 | 787 | #ifdef AMD64 |
never@3156 | 788 | size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M); |
never@3156 | 789 | #else |
never@3156 | 790 | size_t s = (thr_type == os::compiler_thread ? 2 * M : 512 * K); |
never@3156 | 791 | #endif // AMD64 |
never@3156 | 792 | return s; |
never@3156 | 793 | } |
never@3156 | 794 | |
never@3156 | 795 | size_t os::Bsd::default_guard_size(os::ThreadType thr_type) { |
never@3156 | 796 | // Creating guard page is very expensive. Java thread has HotSpot |
never@3156 | 797 | // guard page, only enable glibc guard page for non-Java threads. |
never@3156 | 798 | return (thr_type == java_thread ? 0 : page_size()); |
never@3156 | 799 | } |
never@3156 | 800 | |
never@3156 | 801 | // Java thread: |
never@3156 | 802 | // |
never@3156 | 803 | // Low memory addresses |
never@3156 | 804 | // +------------------------+ |
never@3156 | 805 | // | |\ JavaThread created by VM does not have glibc |
never@3156 | 806 | // | glibc guard page | - guard, attached Java thread usually has |
never@3156 | 807 | // | |/ 1 page glibc guard. |
never@3156 | 808 | // P1 +------------------------+ Thread::stack_base() - Thread::stack_size() |
never@3156 | 809 | // | |\ |
never@3156 | 810 | // | HotSpot Guard Pages | - red and yellow pages |
never@3156 | 811 | // | |/ |
never@3156 | 812 | // +------------------------+ JavaThread::stack_yellow_zone_base() |
never@3156 | 813 | // | |\ |
never@3156 | 814 | // | Normal Stack | - |
never@3156 | 815 | // | |/ |
never@3156 | 816 | // P2 +------------------------+ Thread::stack_base() |
never@3156 | 817 | // |
never@3156 | 818 | // Non-Java thread: |
never@3156 | 819 | // |
never@3156 | 820 | // Low memory addresses |
never@3156 | 821 | // +------------------------+ |
never@3156 | 822 | // | |\ |
never@3156 | 823 | // | glibc guard page | - usually 1 page |
never@3156 | 824 | // | |/ |
never@3156 | 825 | // P1 +------------------------+ Thread::stack_base() - Thread::stack_size() |
never@3156 | 826 | // | |\ |
never@3156 | 827 | // | Normal Stack | - |
never@3156 | 828 | // | |/ |
never@3156 | 829 | // P2 +------------------------+ Thread::stack_base() |
never@3156 | 830 | // |
never@3156 | 831 | // ** P1 (aka bottom) and size ( P2 = P1 - size) are the address and stack size returned from |
never@3156 | 832 | // pthread_attr_getstack() |
never@3156 | 833 | |
never@3156 | 834 | static void current_stack_region(address * bottom, size_t * size) { |
never@3156 | 835 | #ifdef __APPLE__ |
never@3156 | 836 | pthread_t self = pthread_self(); |
never@3156 | 837 | void *stacktop = pthread_get_stackaddr_np(self); |
never@3156 | 838 | *size = pthread_get_stacksize_np(self); |
never@3156 | 839 | *bottom = (address) stacktop - *size; |
never@3156 | 840 | #elif defined(__OpenBSD__) |
never@3156 | 841 | stack_t ss; |
never@3156 | 842 | int rslt = pthread_stackseg_np(pthread_self(), &ss); |
never@3156 | 843 | |
never@3156 | 844 | if (rslt != 0) |
never@3156 | 845 | fatal(err_msg("pthread_stackseg_np failed with err = %d", rslt)); |
never@3156 | 846 | |
never@3156 | 847 | *bottom = (address)((char *)ss.ss_sp - ss.ss_size); |
never@3156 | 848 | *size = ss.ss_size; |
sla@4229 | 849 | #else |
never@3156 | 850 | pthread_attr_t attr; |
never@3156 | 851 | |
never@3156 | 852 | int rslt = pthread_attr_init(&attr); |
never@3156 | 853 | |
never@3156 | 854 | // JVM needs to know exact stack location, abort if it fails |
never@3156 | 855 | if (rslt != 0) |
never@3156 | 856 | fatal(err_msg("pthread_attr_init failed with err = %d", rslt)); |
never@3156 | 857 | |
never@3156 | 858 | rslt = pthread_attr_get_np(pthread_self(), &attr); |
never@3156 | 859 | |
never@3156 | 860 | if (rslt != 0) |
never@3156 | 861 | fatal(err_msg("pthread_attr_get_np failed with err = %d", rslt)); |
never@3156 | 862 | |
never@3156 | 863 | if (pthread_attr_getstackaddr(&attr, (void **)bottom) != 0 || |
never@3156 | 864 | pthread_attr_getstacksize(&attr, size) != 0) { |
never@3156 | 865 | fatal("Can not locate current stack attributes!"); |
never@3156 | 866 | } |
never@3156 | 867 | |
never@3156 | 868 | pthread_attr_destroy(&attr); |
never@3156 | 869 | #endif |
never@3156 | 870 | assert(os::current_stack_pointer() >= *bottom && |
never@3156 | 871 | os::current_stack_pointer() < *bottom + *size, "just checking"); |
never@3156 | 872 | } |
never@3156 | 873 | |
never@3156 | 874 | address os::current_stack_base() { |
never@3156 | 875 | address bottom; |
never@3156 | 876 | size_t size; |
never@3156 | 877 | current_stack_region(&bottom, &size); |
never@3156 | 878 | return (bottom + size); |
never@3156 | 879 | } |
never@3156 | 880 | |
never@3156 | 881 | size_t os::current_stack_size() { |
never@3156 | 882 | // stack size includes normal stack and HotSpot guard pages |
never@3156 | 883 | address bottom; |
never@3156 | 884 | size_t size; |
never@3156 | 885 | current_stack_region(&bottom, &size); |
never@3156 | 886 | return size; |
never@3156 | 887 | } |
never@3156 | 888 | |
never@3156 | 889 | ///////////////////////////////////////////////////////////////////////////// |
never@3156 | 890 | // helper functions for fatal error handler |
never@3156 | 891 | |
never@3156 | 892 | void os::print_context(outputStream *st, void *context) { |
never@3156 | 893 | if (context == NULL) return; |
never@3156 | 894 | |
never@3156 | 895 | ucontext_t *uc = (ucontext_t*)context; |
never@3156 | 896 | st->print_cr("Registers:"); |
never@3156 | 897 | #ifdef AMD64 |
never@3156 | 898 | st->print( "RAX=" INTPTR_FORMAT, uc->context_rax); |
never@3156 | 899 | st->print(", RBX=" INTPTR_FORMAT, uc->context_rbx); |
never@3156 | 900 | st->print(", RCX=" INTPTR_FORMAT, uc->context_rcx); |
never@3156 | 901 | st->print(", RDX=" INTPTR_FORMAT, uc->context_rdx); |
never@3156 | 902 | st->cr(); |
never@3156 | 903 | st->print( "RSP=" INTPTR_FORMAT, uc->context_rsp); |
never@3156 | 904 | st->print(", RBP=" INTPTR_FORMAT, uc->context_rbp); |
never@3156 | 905 | st->print(", RSI=" INTPTR_FORMAT, uc->context_rsi); |
never@3156 | 906 | st->print(", RDI=" INTPTR_FORMAT, uc->context_rdi); |
never@3156 | 907 | st->cr(); |
never@3156 | 908 | st->print( "R8 =" INTPTR_FORMAT, uc->context_r8); |
never@3156 | 909 | st->print(", R9 =" INTPTR_FORMAT, uc->context_r9); |
never@3156 | 910 | st->print(", R10=" INTPTR_FORMAT, uc->context_r10); |
never@3156 | 911 | st->print(", R11=" INTPTR_FORMAT, uc->context_r11); |
never@3156 | 912 | st->cr(); |
never@3156 | 913 | st->print( "R12=" INTPTR_FORMAT, uc->context_r12); |
never@3156 | 914 | st->print(", R13=" INTPTR_FORMAT, uc->context_r13); |
never@3156 | 915 | st->print(", R14=" INTPTR_FORMAT, uc->context_r14); |
never@3156 | 916 | st->print(", R15=" INTPTR_FORMAT, uc->context_r15); |
never@3156 | 917 | st->cr(); |
never@3156 | 918 | st->print( "RIP=" INTPTR_FORMAT, uc->context_rip); |
never@3156 | 919 | st->print(", EFLAGS=" INTPTR_FORMAT, uc->context_flags); |
never@3156 | 920 | st->print(", ERR=" INTPTR_FORMAT, uc->context_err); |
never@3156 | 921 | st->cr(); |
never@3156 | 922 | st->print(" TRAPNO=" INTPTR_FORMAT, uc->context_trapno); |
never@3156 | 923 | #else |
never@3156 | 924 | st->print( "EAX=" INTPTR_FORMAT, uc->context_eax); |
never@3156 | 925 | st->print(", EBX=" INTPTR_FORMAT, uc->context_ebx); |
never@3156 | 926 | st->print(", ECX=" INTPTR_FORMAT, uc->context_ecx); |
never@3156 | 927 | st->print(", EDX=" INTPTR_FORMAT, uc->context_edx); |
never@3156 | 928 | st->cr(); |
never@3156 | 929 | st->print( "ESP=" INTPTR_FORMAT, uc->context_esp); |
never@3156 | 930 | st->print(", EBP=" INTPTR_FORMAT, uc->context_ebp); |
never@3156 | 931 | st->print(", ESI=" INTPTR_FORMAT, uc->context_esi); |
never@3156 | 932 | st->print(", EDI=" INTPTR_FORMAT, uc->context_edi); |
never@3156 | 933 | st->cr(); |
never@3156 | 934 | st->print( "EIP=" INTPTR_FORMAT, uc->context_eip); |
never@3156 | 935 | st->print(", EFLAGS=" INTPTR_FORMAT, uc->context_eflags); |
never@3156 | 936 | #endif // AMD64 |
never@3156 | 937 | st->cr(); |
never@3156 | 938 | st->cr(); |
never@3156 | 939 | |
never@3156 | 940 | intptr_t *sp = (intptr_t *)os::Bsd::ucontext_get_sp(uc); |
never@3156 | 941 | st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp); |
never@3156 | 942 | print_hex_dump(st, (address)sp, (address)(sp + 8*sizeof(intptr_t)), sizeof(intptr_t)); |
never@3156 | 943 | st->cr(); |
never@3156 | 944 | |
never@3156 | 945 | // Note: it may be unsafe to inspect memory near pc. For example, pc may |
never@3156 | 946 | // point to garbage if entry point in an nmethod is corrupted. Leave |
never@3156 | 947 | // this at the end, and hope for the best. |
never@3156 | 948 | address pc = os::Bsd::ucontext_get_pc(uc); |
never@3156 | 949 | st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc); |
never@3156 | 950 | print_hex_dump(st, pc - 32, pc + 32, sizeof(char)); |
never@3156 | 951 | } |
never@3156 | 952 | |
never@3156 | 953 | void os::print_register_info(outputStream *st, void *context) { |
never@3156 | 954 | if (context == NULL) return; |
never@3156 | 955 | |
never@3156 | 956 | ucontext_t *uc = (ucontext_t*)context; |
never@3156 | 957 | |
never@3156 | 958 | st->print_cr("Register to memory mapping:"); |
never@3156 | 959 | st->cr(); |
never@3156 | 960 | |
never@3156 | 961 | // this is horrendously verbose but the layout of the registers in the |
never@3156 | 962 | // context does not match how we defined our abstract Register set, so |
never@3156 | 963 | // we can't just iterate through the gregs area |
never@3156 | 964 | |
never@3156 | 965 | // this is only for the "general purpose" registers |
never@3156 | 966 | |
never@3156 | 967 | #ifdef AMD64 |
never@3156 | 968 | st->print("RAX="); print_location(st, uc->context_rax); |
never@3156 | 969 | st->print("RBX="); print_location(st, uc->context_rbx); |
never@3156 | 970 | st->print("RCX="); print_location(st, uc->context_rcx); |
never@3156 | 971 | st->print("RDX="); print_location(st, uc->context_rdx); |
never@3156 | 972 | st->print("RSP="); print_location(st, uc->context_rsp); |
never@3156 | 973 | st->print("RBP="); print_location(st, uc->context_rbp); |
never@3156 | 974 | st->print("RSI="); print_location(st, uc->context_rsi); |
never@3156 | 975 | st->print("RDI="); print_location(st, uc->context_rdi); |
never@3156 | 976 | st->print("R8 ="); print_location(st, uc->context_r8); |
never@3156 | 977 | st->print("R9 ="); print_location(st, uc->context_r9); |
never@3156 | 978 | st->print("R10="); print_location(st, uc->context_r10); |
never@3156 | 979 | st->print("R11="); print_location(st, uc->context_r11); |
never@3156 | 980 | st->print("R12="); print_location(st, uc->context_r12); |
never@3156 | 981 | st->print("R13="); print_location(st, uc->context_r13); |
never@3156 | 982 | st->print("R14="); print_location(st, uc->context_r14); |
never@3156 | 983 | st->print("R15="); print_location(st, uc->context_r15); |
never@3156 | 984 | #else |
never@3156 | 985 | st->print("EAX="); print_location(st, uc->context_eax); |
never@3156 | 986 | st->print("EBX="); print_location(st, uc->context_ebx); |
never@3156 | 987 | st->print("ECX="); print_location(st, uc->context_ecx); |
never@3156 | 988 | st->print("EDX="); print_location(st, uc->context_edx); |
never@3156 | 989 | st->print("ESP="); print_location(st, uc->context_esp); |
never@3156 | 990 | st->print("EBP="); print_location(st, uc->context_ebp); |
never@3156 | 991 | st->print("ESI="); print_location(st, uc->context_esi); |
never@3156 | 992 | st->print("EDI="); print_location(st, uc->context_edi); |
never@3156 | 993 | #endif // AMD64 |
never@3156 | 994 | |
never@3156 | 995 | st->cr(); |
never@3156 | 996 | } |
never@3156 | 997 | |
never@3156 | 998 | void os::setup_fpu() { |
never@3156 | 999 | #ifndef AMD64 |
never@3156 | 1000 | address fpu_cntrl = StubRoutines::addr_fpu_cntrl_wrd_std(); |
never@3156 | 1001 | __asm__ volatile ( "fldcw (%0)" : |
never@3156 | 1002 | : "r" (fpu_cntrl) : "memory"); |
never@3156 | 1003 | #endif // !AMD64 |
never@3156 | 1004 | } |
roland@3606 | 1005 | |
roland@3606 | 1006 | #ifndef PRODUCT |
roland@3606 | 1007 | void os::verify_stack_alignment() { |
roland@3606 | 1008 | } |
roland@3606 | 1009 | #endif |