8221584: SIGSEGV in os::PlatformEvent::unpark() in JvmtiRawMonitor::raw_exit while posting method exit event
authordholmes
Mon, 08 Apr 2019 21:39:43 +0000
changeset 54469 8592226f5cd3
parent 54468 b02d1d829b09
child 54470 14986fb09d9a
8221584: SIGSEGV in os::PlatformEvent::unpark() in JvmtiRawMonitor::raw_exit while posting method exit event Reviewed-by: dholmes, dcubed Contributed-by: robbin.ehn@oracle.com, stefan.karlsson@oracle.com
src/hotspot/share/prims/jvmtiRawMonitor.cpp
--- a/src/hotspot/share/prims/jvmtiRawMonitor.cpp	Mon Apr 08 17:30:18 2019 -0400
+++ b/src/hotspot/share/prims/jvmtiRawMonitor.cpp	Mon Apr 08 21:39:43 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -167,7 +167,12 @@
   RawMonitor_lock->unlock() ;
   if (w != NULL) {
       guarantee (w ->TState == ObjectWaiter::TS_ENTER, "invariant") ;
+      // Once we set TState to TS_RUN the waiting thread can complete
+      // SimpleEnter and 'w' is pointing into random stack space. So we have
+      // to ensure we extract the ParkEvent (which is in type-stable memory)
+      // before we set the state, and then don't access 'w'.
       ParkEvent * ev = w->_event ;
+      OrderAccess::loadstore();
       w->TState = ObjectWaiter::TS_RUN ;
       OrderAccess::fence() ;
       ev->unpark() ;
@@ -200,7 +205,7 @@
 
   // If thread still resides on the waitset then unlink it.
   // Double-checked locking -- the usage is safe in this context
-  // as we TState is volatile and the lock-unlock operators are
+  // as TState is volatile and the lock-unlock operators are
   // serializing (barrier-equivalent).
 
   if (Node.TState == ObjectWaiter::TS_WAIT) {