8183925: Decouple crash protection from watcher thread

Tue, 04 Feb 2020 11:16:27 +0800

author
rehn
date
Tue, 04 Feb 2020 11:16:27 +0800
changeset 9891
4904bded9702
parent 9890
429bb572ee65
child 9892
9a4141de094d

8183925: Decouple crash protection from watcher thread
Reviewed-by: dcubed, coleenp

src/os/posix/vm/os_posix.cpp file | annotate | diff | comparison | revisions
src/os/posix/vm/os_posix.hpp file | annotate | diff | comparison | revisions
src/os/windows/vm/os_windows.cpp file | annotate | diff | comparison | revisions
src/os/windows/vm/os_windows.hpp file | annotate | diff | comparison | revisions
src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp file | annotate | diff | comparison | revisions
src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp file | annotate | diff | comparison | revisions
src/os_cpu/linux_x86/vm/os_linux_x86.cpp file | annotate | diff | comparison | revisions
src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp file | annotate | diff | comparison | revisions
src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/mutex.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/os.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/thread.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/thread.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/os/posix/vm/os_posix.cpp	Thu Jan 30 00:21:06 2020 +0000
     1.2 +++ b/src/os/posix/vm/os_posix.cpp	Tue Feb 04 11:16:27 2020 +0800
     1.3 @@ -919,59 +919,3 @@
     1.4      }
     1.5    }
     1.6  }
     1.7 -
     1.8 -os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() {
     1.9 -  assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread");
    1.10 -}
    1.11 -
    1.12 -/*
    1.13 - * See the caveats for this class in os_posix.hpp
    1.14 - * Protects the callback call so that SIGSEGV / SIGBUS jumps back into this
    1.15 - * method and returns false. If none of the signals are raised, returns true.
    1.16 - * The callback is supposed to provide the method that should be protected.
    1.17 - */
    1.18 -bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) {
    1.19 -  sigset_t saved_sig_mask;
    1.20 -
    1.21 -  assert(Thread::current()->is_Watcher_thread(), "Only for WatcherThread");
    1.22 -  assert(!WatcherThread::watcher_thread()->has_crash_protection(),
    1.23 -      "crash_protection already set?");
    1.24 -
    1.25 -  // we cannot rely on sigsetjmp/siglongjmp to save/restore the signal mask
    1.26 -  // since on at least some systems (OS X) siglongjmp will restore the mask
    1.27 -  // for the process, not the thread
    1.28 -  pthread_sigmask(0, NULL, &saved_sig_mask);
    1.29 -  if (sigsetjmp(_jmpbuf, 0) == 0) {
    1.30 -    // make sure we can see in the signal handler that we have crash protection
    1.31 -    // installed
    1.32 -    WatcherThread::watcher_thread()->set_crash_protection(this);
    1.33 -    cb.call();
    1.34 -    // and clear the crash protection
    1.35 -    WatcherThread::watcher_thread()->set_crash_protection(NULL);
    1.36 -    return true;
    1.37 -  }
    1.38 -  // this happens when we siglongjmp() back
    1.39 -  pthread_sigmask(SIG_SETMASK, &saved_sig_mask, NULL);
    1.40 -  WatcherThread::watcher_thread()->set_crash_protection(NULL);
    1.41 -  return false;
    1.42 -}
    1.43 -
    1.44 -void os::WatcherThreadCrashProtection::restore() {
    1.45 -  assert(WatcherThread::watcher_thread()->has_crash_protection(),
    1.46 -      "must have crash protection");
    1.47 -
    1.48 -  siglongjmp(_jmpbuf, 1);
    1.49 -}
    1.50 -
    1.51 -void os::WatcherThreadCrashProtection::check_crash_protection(int sig,
    1.52 -    Thread* thread) {
    1.53 -
    1.54 -  if (thread != NULL &&
    1.55 -      thread->is_Watcher_thread() &&
    1.56 -      WatcherThread::watcher_thread()->has_crash_protection()) {
    1.57 -
    1.58 -    if (sig == SIGSEGV || sig == SIGBUS) {
    1.59 -      WatcherThread::watcher_thread()->crash_protection()->restore();
    1.60 -    }
    1.61 -  }
    1.62 -}
     2.1 --- a/src/os/posix/vm/os_posix.hpp	Thu Jan 30 00:21:06 2020 +0000
     2.2 +++ b/src/os/posix/vm/os_posix.hpp	Tue Feb 04 11:16:27 2020 +0800
     2.3 @@ -88,24 +88,4 @@
     2.4    sigjmp_buf _jmpbuf;
     2.5  };
     2.6  
     2.7 -/*
     2.8 - * Crash protection for the watcher thread. Wrap the callback
     2.9 - * with a sigsetjmp and in case of a SIGSEGV/SIGBUS we siglongjmp
    2.10 - * back.
    2.11 - * To be able to use this - don't take locks, don't rely on destructors,
    2.12 - * don't make OS library calls, don't allocate memory, don't print,
    2.13 - * don't call code that could leave the heap / memory in an inconsistent state,
    2.14 - * or anything else where we are not in control if we suddenly jump out.
    2.15 - */
    2.16 -class WatcherThreadCrashProtection : public StackObj {
    2.17 -public:
    2.18 -  WatcherThreadCrashProtection();
    2.19 -  bool call(os::CrashProtectionCallback& cb);
    2.20 -
    2.21 -  static void check_crash_protection(int signal, Thread* thread);
    2.22 -private:
    2.23 -  void restore();
    2.24 -  sigjmp_buf _jmpbuf;
    2.25 -};
    2.26 -
    2.27  #endif // OS_POSIX_VM_OS_POSIX_HPP
     3.1 --- a/src/os/windows/vm/os_windows.cpp	Thu Jan 30 00:21:06 2020 +0000
     3.2 +++ b/src/os/windows/vm/os_windows.cpp	Tue Feb 04 11:16:27 2020 +0800
     3.3 @@ -4905,34 +4905,6 @@
     3.4    return success;
     3.5  }
     3.6  
     3.7 -os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() {
     3.8 -  assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread");
     3.9 -}
    3.10 -
    3.11 -/*
    3.12 - * See the caveats for this class in os_windows.hpp
    3.13 - * Protects the callback call so that raised OS EXCEPTIONS causes a jump back
    3.14 - * into this method and returns false. If no OS EXCEPTION was raised, returns
    3.15 - * true.
    3.16 - * The callback is supposed to provide the method that should be protected.
    3.17 - */
    3.18 -bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) {
    3.19 -  assert(Thread::current()->is_Watcher_thread(), "Only for WatcherThread");
    3.20 -  assert(!WatcherThread::watcher_thread()->has_crash_protection(),
    3.21 -      "crash_protection already set?");
    3.22 -
    3.23 -  bool success = true;
    3.24 -  __try {
    3.25 -    WatcherThread::watcher_thread()->set_crash_protection(this);
    3.26 -    cb.call();
    3.27 -  } __except(EXCEPTION_EXECUTE_HANDLER) {
    3.28 -    // only for protection, nothing to do
    3.29 -    success = false;
    3.30 -  }
    3.31 -  WatcherThread::watcher_thread()->set_crash_protection(NULL);
    3.32 -  return success;
    3.33 -}
    3.34 -
    3.35  // An Event wraps a win32 "CreateEvent" kernel handle.
    3.36  //
    3.37  // We have a number of choices regarding "CreateEvent" win32 handle leakage:
     4.1 --- a/src/os/windows/vm/os_windows.hpp	Thu Jan 30 00:21:06 2020 +0000
     4.2 +++ b/src/os/windows/vm/os_windows.hpp	Tue Feb 04 11:16:27 2020 +0800
     4.3 @@ -1,5 +1,5 @@
     4.4  /*
     4.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     4.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     4.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.8   *
     4.9   * This code is free software; you can redistribute it and/or modify it
    4.10 @@ -125,20 +125,6 @@
    4.11    static volatile intptr_t _crash_mux;
    4.12  };
    4.13  
    4.14 -/*
    4.15 - * Crash protection for the watcher thread. Wrap the callback
    4.16 - * with a __try { call() }
    4.17 - * To be able to use this - don't take locks, don't rely on destructors,
    4.18 - * don't make OS library calls, don't allocate memory, don't print,
    4.19 - * don't call code that could leave the heap / memory in an inconsistent state,
    4.20 - * or anything else where we are not in control if we suddenly jump out.
    4.21 - */
    4.22 -class WatcherThreadCrashProtection : public StackObj {
    4.23 -public:
    4.24 -  WatcherThreadCrashProtection();
    4.25 -  bool call(os::CrashProtectionCallback& cb);
    4.26 -};
    4.27 -
    4.28  class PlatformEvent : public CHeapObj<mtInternal> {
    4.29    private:
    4.30      double CachePad [4] ;   // increase odds that _Event is sole occupant of cache line
     5.1 --- a/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Thu Jan 30 00:21:06 2020 +0000
     5.2 +++ b/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp	Tue Feb 04 11:16:27 2020 +0800
     5.3 @@ -407,7 +407,7 @@
     5.4  
     5.5    // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
     5.6    // (no destructors can be run)
     5.7 -  os::WatcherThreadCrashProtection::check_crash_protection(sig, t);
     5.8 +  os::ThreadCrashProtection::check_crash_protection(sig, t);
     5.9  
    5.10    SignalHandlerMark shm(t);
    5.11  
     6.1 --- a/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Thu Jan 30 00:21:06 2020 +0000
     6.2 +++ b/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp	Tue Feb 04 11:16:27 2020 +0800
     6.3 @@ -544,7 +544,7 @@
     6.4  
     6.5    // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
     6.6    // (no destructors can be run)
     6.7 -  os::WatcherThreadCrashProtection::check_crash_protection(sig, t);
     6.8 +  os::ThreadCrashProtection::check_crash_protection(sig, t);
     6.9  
    6.10    SignalHandlerMark shm(t);
    6.11  
     7.1 --- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Thu Jan 30 00:21:06 2020 +0000
     7.2 +++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Tue Feb 04 11:16:27 2020 +0800
     7.3 @@ -1,5 +1,5 @@
     7.4  /*
     7.5 - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
     7.6 + * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
     7.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.8   *
     7.9   * This code is free software; you can redistribute it and/or modify it
    7.10 @@ -222,7 +222,7 @@
    7.11  
    7.12    // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
    7.13    // (no destructors can be run)
    7.14 -  os::WatcherThreadCrashProtection::check_crash_protection(sig, t);
    7.15 +  os::ThreadCrashProtection::check_crash_protection(sig, t);
    7.16  
    7.17    SignalHandlerMark shm(t);
    7.18  
     8.1 --- a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Thu Jan 30 00:21:06 2020 +0000
     8.2 +++ b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp	Tue Feb 04 11:16:27 2020 +0800
     8.3 @@ -312,7 +312,7 @@
     8.4  
     8.5    // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
     8.6    // (no destructors can be run)
     8.7 -  os::WatcherThreadCrashProtection::check_crash_protection(sig, t);
     8.8 +  os::ThreadCrashProtection::check_crash_protection(sig, t);
     8.9  
    8.10    SignalHandlerMark shm(t);
    8.11  
     9.1 --- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Thu Jan 30 00:21:06 2020 +0000
     9.2 +++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp	Tue Feb 04 11:16:27 2020 +0800
     9.3 @@ -369,7 +369,7 @@
     9.4  
     9.5    // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
     9.6    // (no destructors can be run)
     9.7 -  os::WatcherThreadCrashProtection::check_crash_protection(sig, t);
     9.8 +  os::ThreadCrashProtection::check_crash_protection(sig, t);
     9.9  
    9.10    SignalHandlerMark shm(t);
    9.11  
    10.1 --- a/src/share/vm/runtime/mutex.cpp	Thu Jan 30 00:21:06 2020 +0000
    10.2 +++ b/src/share/vm/runtime/mutex.cpp	Tue Feb 04 11:16:27 2020 +0800
    10.3 @@ -1,6 +1,6 @@
    10.4  
    10.5  /*
    10.6 - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
    10.7 + * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
    10.8   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    10.9   *
   10.10   * This code is free software; you can redistribute it and/or modify it
   10.11 @@ -1373,10 +1373,8 @@
   10.12      debug_only(if (rank() != Mutex::special) \
   10.13        thread->check_for_valid_safepoint_state(false);)
   10.14    }
   10.15 -  if (thread->is_Watcher_thread()) {
   10.16 -    assert(!WatcherThread::watcher_thread()->has_crash_protection(),
   10.17 -        "locking not allowed when crash protection is set");
   10.18 -  }
   10.19 +  assert(!os::ThreadCrashProtection::is_crash_protected(thread),
   10.20 +         "locking not allowed when crash protection is set");
   10.21  }
   10.22  
   10.23  void Monitor::check_block_state(Thread *thread) {
    11.1 --- a/src/share/vm/runtime/os.cpp	Thu Jan 30 00:21:06 2020 +0000
    11.2 +++ b/src/share/vm/runtime/os.cpp	Tue Feb 04 11:16:27 2020 +0800
    11.3 @@ -593,21 +593,10 @@
    11.4    NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
    11.5    NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
    11.6  
    11.7 -#ifdef ASSERT
    11.8 -  // checking for the WatcherThread and crash_protection first
    11.9 -  // since os::malloc can be called when the libjvm.{dll,so} is
   11.10 -  // first loaded and we don't have a thread yet.
   11.11 -  // try to find the thread after we see that the watcher thread
   11.12 -  // exists and has crash protection.
   11.13 -  WatcherThread *wt = WatcherThread::watcher_thread();
   11.14 -  if (wt != NULL && wt->has_crash_protection()) {
   11.15 -    Thread* thread = ThreadLocalStorage::get_thread_slow();
   11.16 -    if (thread == wt) {
   11.17 -      assert(!wt->has_crash_protection(),
   11.18 -          "Can't malloc with crash protection from WatcherThread");
   11.19 -    }
   11.20 -  }
   11.21 -#endif
   11.22 +  // Since os::malloc can be called when the libjvm.{dll,so} is
   11.23 +  // first loaded and we don't have a thread yet we must accept NULL also here.
   11.24 +  assert(!os::ThreadCrashProtection::is_crash_protected(ThreadLocalStorage::thread()),
   11.25 +         "malloc() not allowed when crash protection is set");
   11.26  
   11.27    if (size == 0) {
   11.28      // return a valid pointer if size is zero
    12.1 --- a/src/share/vm/runtime/thread.cpp	Thu Jan 30 00:21:06 2020 +0000
    12.2 +++ b/src/share/vm/runtime/thread.cpp	Tue Feb 04 11:16:27 2020 +0800
    12.3 @@ -1239,7 +1239,7 @@
    12.4  bool WatcherThread::_startable = false;
    12.5  volatile bool  WatcherThread::_should_terminate = false;
    12.6  
    12.7 -WatcherThread::WatcherThread() : Thread(), _crash_protection(NULL) {
    12.8 +WatcherThread::WatcherThread() : Thread() {
    12.9    assert(watcher_thread() == NULL, "we can only allocate one WatcherThread");
   12.10    if (os::create_thread(this, os::watcher_thread)) {
   12.11      _watcher_thread = this;
    13.1 --- a/src/share/vm/runtime/thread.hpp	Thu Jan 30 00:21:06 2020 +0000
    13.2 +++ b/src/share/vm/runtime/thread.hpp	Tue Feb 04 11:16:27 2020 +0800
    13.3 @@ -734,8 +734,6 @@
    13.4  
    13.5    static bool _startable;
    13.6    volatile static bool _should_terminate; // updated without holding lock
    13.7 -
    13.8 -  os::WatcherThreadCrashProtection* _crash_protection;
    13.9   public:
   13.10    enum SomeConstants {
   13.11      delay_interval = 10                          // interrupt delay in milliseconds
   13.12 @@ -762,15 +760,6 @@
   13.13    // Only allow start once the VM is sufficiently initialized
   13.14    // Otherwise the first task to enroll will trigger the start
   13.15    static void make_startable();
   13.16 -
   13.17 -  void set_crash_protection(os::WatcherThreadCrashProtection* crash_protection) {
   13.18 -    assert(Thread::current()->is_Watcher_thread(), "Can only be set by WatcherThread");
   13.19 -    _crash_protection = crash_protection;
   13.20 -  }
   13.21 -
   13.22 -  bool has_crash_protection() const { return _crash_protection != NULL; }
   13.23 -  os::WatcherThreadCrashProtection* crash_protection() const { return _crash_protection; }
   13.24 -
   13.25   private:
   13.26    int sleep() const;
   13.27  };

mercurial