comparison src/os/posix/vm/os_posix.cpp @ 12141:cc56f122f3f7

8023720: (hotspot) setjmp/longjmp changes the process signal mask on OS X Reviewed-by: dholmes, rbackman
author sla
date Thu, 29 Aug 2013 11:05:55 +0200
parents 5e3b6f79d280
children c636758ea616
comparison
equal deleted inserted replaced
12140:915cc4f3fb15 12141:cc56f122f3f7
1 /* 1 /*
2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
28 #include "utilities/vmError.hpp" 28 #include "utilities/vmError.hpp"
29 29
30 #include <unistd.h> 30 #include <unistd.h>
31 #include <sys/resource.h> 31 #include <sys/resource.h>
32 #include <sys/utsname.h> 32 #include <sys/utsname.h>
33 #include <pthread.h>
34 #include <signal.h>
33 35
34 36
35 // Check core dump limit and report possible place where core can be found 37 // Check core dump limit and report possible place where core can be found
36 void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize) { 38 void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize) {
37 int n; 39 int n;
269 * Protects the callback call so that SIGSEGV / SIGBUS jumps back into this 271 * Protects the callback call so that SIGSEGV / SIGBUS jumps back into this
270 * method and returns false. If none of the signals are raised, returns true. 272 * method and returns false. If none of the signals are raised, returns true.
271 * The callback is supposed to provide the method that should be protected. 273 * The callback is supposed to provide the method that should be protected.
272 */ 274 */
273 bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) { 275 bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) {
276 sigset_t saved_sig_mask;
277
274 assert(Thread::current()->is_Watcher_thread(), "Only for WatcherThread"); 278 assert(Thread::current()->is_Watcher_thread(), "Only for WatcherThread");
275 assert(!WatcherThread::watcher_thread()->has_crash_protection(), 279 assert(!WatcherThread::watcher_thread()->has_crash_protection(),
276 "crash_protection already set?"); 280 "crash_protection already set?");
277 281
278 if (sigsetjmp(_jmpbuf, 1) == 0) { 282 // we cannot rely on sigsetjmp/siglongjmp to save/restore the signal mask
283 // since on at least some systems (OS X) siglongjmp will restore the mask
284 // for the process, not the thread
285 pthread_sigmask(0, NULL, &saved_sig_mask);
286 if (sigsetjmp(_jmpbuf, 0) == 0) {
279 // make sure we can see in the signal handler that we have crash protection 287 // make sure we can see in the signal handler that we have crash protection
280 // installed 288 // installed
281 WatcherThread::watcher_thread()->set_crash_protection(this); 289 WatcherThread::watcher_thread()->set_crash_protection(this);
282 cb.call(); 290 cb.call();
283 // and clear the crash protection 291 // and clear the crash protection
284 WatcherThread::watcher_thread()->set_crash_protection(NULL); 292 WatcherThread::watcher_thread()->set_crash_protection(NULL);
285 return true; 293 return true;
286 } 294 }
287 // this happens when we siglongjmp() back 295 // this happens when we siglongjmp() back
296 pthread_sigmask(SIG_SETMASK, &saved_sig_mask, NULL);
288 WatcherThread::watcher_thread()->set_crash_protection(NULL); 297 WatcherThread::watcher_thread()->set_crash_protection(NULL);
289 return false; 298 return false;
290 } 299 }
291 300
292 void os::WatcherThreadCrashProtection::restore() { 301 void os::WatcherThreadCrashProtection::restore() {