257 } |
257 } |
258 |
258 |
259 FILE* os::open(int fd, const char* mode) { |
259 FILE* os::open(int fd, const char* mode) { |
260 return ::fdopen(fd, mode); |
260 return ::fdopen(fd, mode); |
261 } |
261 } |
|
262 |
|
263 os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() { |
|
264 assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread"); |
|
265 } |
|
266 |
|
267 /* |
|
268 * See the caveats for this class in os_posix.hpp |
|
269 * 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. |
|
271 * The callback is supposed to provide the method that should be protected. |
|
272 */ |
|
273 bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) { |
|
274 assert(Thread::current()->is_Watcher_thread(), "Only for WatcherThread"); |
|
275 assert(!WatcherThread::watcher_thread()->has_crash_protection(), |
|
276 "crash_protection already set?"); |
|
277 |
|
278 if (sigsetjmp(_jmpbuf, 1) == 0) { |
|
279 // make sure we can see in the signal handler that we have crash protection |
|
280 // installed |
|
281 WatcherThread::watcher_thread()->set_crash_protection(this); |
|
282 cb.call(); |
|
283 // and clear the crash protection |
|
284 WatcherThread::watcher_thread()->set_crash_protection(NULL); |
|
285 return true; |
|
286 } |
|
287 // this happens when we siglongjmp() back |
|
288 WatcherThread::watcher_thread()->set_crash_protection(NULL); |
|
289 return false; |
|
290 } |
|
291 |
|
292 void os::WatcherThreadCrashProtection::restore() { |
|
293 assert(WatcherThread::watcher_thread()->has_crash_protection(), |
|
294 "must have crash protection"); |
|
295 |
|
296 siglongjmp(_jmpbuf, 1); |
|
297 } |
|
298 |
|
299 void os::WatcherThreadCrashProtection::check_crash_protection(int sig, |
|
300 Thread* thread) { |
|
301 |
|
302 if (thread != NULL && |
|
303 thread->is_Watcher_thread() && |
|
304 WatcherThread::watcher_thread()->has_crash_protection()) { |
|
305 |
|
306 if (sig == SIGSEGV || sig == SIGBUS) { |
|
307 WatcherThread::watcher_thread()->crash_protection()->restore(); |
|
308 } |
|
309 } |
|
310 } |