192 frame os::current_frame() {
193 intptr_t* fp = _get_previous_fp();
194 frame myframe((intptr_t*)os::current_stack_pointer(),
195 (intptr_t*)fp,
196 CAST_FROM_FN_PTR(address, os::current_frame));
197 if (os::is_first_C_frame(&myframe)) {
198 // stack is not walkable
199 return frame();
200 } else {
201 return os::get_sender_for_C_frame(&myframe);
202 }
203 }
204
205 // Utility functions
206
207 // From IA32 System Programming Guide
208 enum {
209 trap_page_fault = 0xE
210 };
211
212 extern "C" void Fetch32PFI () ;
213 extern "C" void Fetch32Resume () ;
214 #ifdef AMD64
215 extern "C" void FetchNPFI () ;
216 extern "C" void FetchNResume () ;
217 #endif // AMD64
218
219 extern "C" JNIEXPORT int
220 JVM_handle_linux_signal(int sig,
221 siginfo_t* info,
222 void* ucVoid,
223 int abort_if_unrecognized) {
224 ucontext_t* uc = (ucontext_t*) ucVoid;
225
226 Thread* t = ThreadLocalStorage::get_thread_slow();
227
228 SignalHandlerMark shm(t);
229
230 // Note: it's not uncommon that JNI code uses signal/sigset to install
231 // then restore certain signal handler (e.g. to temporarily block SIGPIPE,
232 // or have a SIGILL handler when detecting CPU type). When that happens,
233 // JVM_handle_linux_signal() might be invoked with junk info/ucVoid. To
234 // avoid unnecessary crash when libjsig is not preloaded, try handle signals
235 // that do not require siginfo/ucontext first.
236
237 if (sig == SIGPIPE || sig == SIGXFSZ) {
238 // allow chained handler to go first
261 }
262 }
263 /*
264 NOTE: does not seem to work on linux.
265 if (info == NULL || info->si_code <= 0 || info->si_code == SI_NOINFO) {
266 // can't decode this kind of signal
267 info = NULL;
268 } else {
269 assert(sig == info->si_signo, "bad siginfo");
270 }
271 */
272 // decide if this trap can be handled by a stub
273 address stub = NULL;
274
275 address pc = NULL;
276
277 //%note os_trap_1
278 if (info != NULL && uc != NULL && thread != NULL) {
279 pc = (address) os::Linux::ucontext_get_pc(uc);
280
281 if (pc == (address) Fetch32PFI) {
282 uc->uc_mcontext.gregs[REG_PC] = intptr_t(Fetch32Resume) ;
283 return 1 ;
284 }
285 #ifdef AMD64
286 if (pc == (address) FetchNPFI) {
287 uc->uc_mcontext.gregs[REG_PC] = intptr_t (FetchNResume) ;
288 return 1 ;
289 }
290 #endif // AMD64
291
292 // Handle ALL stack overflow variations here
293 if (sig == SIGSEGV) {
294 address addr = (address) info->si_addr;
295
296 // check if fault address is within thread stack
297 if (addr < thread->stack_base() &&
298 addr >= thread->stack_base() - thread->stack_size()) {
299 // stack overflow
300 if (thread->in_stack_yellow_zone(addr)) {
301 thread->disable_stack_yellow_zone();
302 if (thread->thread_state() == _thread_in_Java) {
303 // Throw a stack overflow exception. Guard pages will be reenabled
304 // while unwinding the stack.
305 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
306 } else {
307 // Thread was in the vm or native code. Return and try to finish.
308 return 1;
309 }
310 } else if (thread->in_stack_red_zone(addr)) {
|
192 frame os::current_frame() {
193 intptr_t* fp = _get_previous_fp();
194 frame myframe((intptr_t*)os::current_stack_pointer(),
195 (intptr_t*)fp,
196 CAST_FROM_FN_PTR(address, os::current_frame));
197 if (os::is_first_C_frame(&myframe)) {
198 // stack is not walkable
199 return frame();
200 } else {
201 return os::get_sender_for_C_frame(&myframe);
202 }
203 }
204
205 // Utility functions
206
207 // From IA32 System Programming Guide
208 enum {
209 trap_page_fault = 0xE
210 };
211
212 extern "C" JNIEXPORT int
213 JVM_handle_linux_signal(int sig,
214 siginfo_t* info,
215 void* ucVoid,
216 int abort_if_unrecognized) {
217 ucontext_t* uc = (ucontext_t*) ucVoid;
218
219 Thread* t = ThreadLocalStorage::get_thread_slow();
220
221 SignalHandlerMark shm(t);
222
223 // Note: it's not uncommon that JNI code uses signal/sigset to install
224 // then restore certain signal handler (e.g. to temporarily block SIGPIPE,
225 // or have a SIGILL handler when detecting CPU type). When that happens,
226 // JVM_handle_linux_signal() might be invoked with junk info/ucVoid. To
227 // avoid unnecessary crash when libjsig is not preloaded, try handle signals
228 // that do not require siginfo/ucontext first.
229
230 if (sig == SIGPIPE || sig == SIGXFSZ) {
231 // allow chained handler to go first
254 }
255 }
256 /*
257 NOTE: does not seem to work on linux.
258 if (info == NULL || info->si_code <= 0 || info->si_code == SI_NOINFO) {
259 // can't decode this kind of signal
260 info = NULL;
261 } else {
262 assert(sig == info->si_signo, "bad siginfo");
263 }
264 */
265 // decide if this trap can be handled by a stub
266 address stub = NULL;
267
268 address pc = NULL;
269
270 //%note os_trap_1
271 if (info != NULL && uc != NULL && thread != NULL) {
272 pc = (address) os::Linux::ucontext_get_pc(uc);
273
274 if (StubRoutines::is_safefetch_fault(pc)) {
275 uc->uc_mcontext.gregs[REG_PC] = intptr_t(StubRoutines::continuation_for_safefetch_fault(pc));
276 return 1;
277 }
278
279 // Handle ALL stack overflow variations here
280 if (sig == SIGSEGV) {
281 address addr = (address) info->si_addr;
282
283 // check if fault address is within thread stack
284 if (addr < thread->stack_base() &&
285 addr >= thread->stack_base() - thread->stack_size()) {
286 // stack overflow
287 if (thread->in_stack_yellow_zone(addr)) {
288 thread->disable_stack_yellow_zone();
289 if (thread->thread_state() == _thread_in_Java) {
290 // Throw a stack overflow exception. Guard pages will be reenabled
291 // while unwinding the stack.
292 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
293 } else {
294 // Thread was in the vm or native code. Return and try to finish.
295 return 1;
296 }
297 } else if (thread->in_stack_red_zone(addr)) {
|