Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
892c54bb
D
dragonwell8_hotspot
项目概览
openanolis
/
dragonwell8_hotspot
通知
2
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_hotspot
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
892c54bb
编写于
7月 17, 2013
作者:
R
rbackman
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8020701: Avoid crashes in WatcherThread
Reviewed-by: acorn, dcubed, dsimms
上级
31bda49d
变更
14
显示空白变更内容
内联
并排
Showing
14 changed file
with
169 addition
and
1 deletion
+169
-1
src/os/posix/vm/os_posix.cpp
src/os/posix/vm/os_posix.cpp
+49
-0
src/os/posix/vm/os_posix.hpp
src/os/posix/vm/os_posix.hpp
+19
-0
src/os/windows/vm/os_windows.cpp
src/os/windows/vm/os_windows.cpp
+28
-0
src/os/windows/vm/os_windows.hpp
src/os/windows/vm/os_windows.hpp
+14
-0
src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
+4
-0
src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp
src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp
+4
-0
src/os_cpu/linux_x86/vm/os_linux_x86.cpp
src/os_cpu/linux_x86/vm/os_linux_x86.cpp
+4
-0
src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp
src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp
+4
-0
src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp
src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp
+4
-0
src/share/vm/runtime/mutex.cpp
src/share/vm/runtime/mutex.cpp
+4
-0
src/share/vm/runtime/os.cpp
src/share/vm/runtime/os.cpp
+16
-0
src/share/vm/runtime/os.hpp
src/share/vm/runtime/os.hpp
+8
-0
src/share/vm/runtime/thread.cpp
src/share/vm/runtime/thread.cpp
+1
-1
src/share/vm/runtime/thread.hpp
src/share/vm/runtime/thread.hpp
+10
-0
未找到文件。
src/os/posix/vm/os_posix.cpp
浏览文件 @
892c54bb
...
...
@@ -259,3 +259,52 @@ const char* os::get_current_directory(char *buf, size_t buflen) {
FILE
*
os
::
open
(
int
fd
,
const
char
*
mode
)
{
return
::
fdopen
(
fd
,
mode
);
}
os
::
WatcherThreadCrashProtection
::
WatcherThreadCrashProtection
()
{
assert
(
Thread
::
current
()
->
is_Watcher_thread
(),
"Must be WatcherThread"
);
}
/*
* See the caveats for this class in os_posix.hpp
* Protects the callback call so that SIGSEGV / SIGBUS jumps back into this
* method and returns false. If none of the signals are raised, returns true.
* The callback is supposed to provide the method that should be protected.
*/
bool
os
::
WatcherThreadCrashProtection
::
call
(
os
::
CrashProtectionCallback
&
cb
)
{
assert
(
Thread
::
current
()
->
is_Watcher_thread
(),
"Only for WatcherThread"
);
assert
(
!
WatcherThread
::
watcher_thread
()
->
has_crash_protection
(),
"crash_protection already set?"
);
if
(
sigsetjmp
(
_jmpbuf
,
1
)
==
0
)
{
// make sure we can see in the signal handler that we have crash protection
// installed
WatcherThread
::
watcher_thread
()
->
set_crash_protection
(
this
);
cb
.
call
();
// and clear the crash protection
WatcherThread
::
watcher_thread
()
->
set_crash_protection
(
NULL
);
return
true
;
}
// this happens when we siglongjmp() back
WatcherThread
::
watcher_thread
()
->
set_crash_protection
(
NULL
);
return
false
;
}
void
os
::
WatcherThreadCrashProtection
::
restore
()
{
assert
(
WatcherThread
::
watcher_thread
()
->
has_crash_protection
(),
"must have crash protection"
);
siglongjmp
(
_jmpbuf
,
1
);
}
void
os
::
WatcherThreadCrashProtection
::
check_crash_protection
(
int
sig
,
Thread
*
thread
)
{
if
(
thread
!=
NULL
&&
thread
->
is_Watcher_thread
()
&&
WatcherThread
::
watcher_thread
()
->
has_crash_protection
())
{
if
(
sig
==
SIGSEGV
||
sig
==
SIGBUS
)
{
WatcherThread
::
watcher_thread
()
->
crash_protection
()
->
restore
();
}
}
}
src/os/posix/vm/os_posix.hpp
浏览文件 @
892c54bb
...
...
@@ -37,5 +37,24 @@ protected:
};
/*
* Crash protection for the watcher thread. Wrap the callback
* with a sigsetjmp and in case of a SIGSEGV/SIGBUS we siglongjmp
* back.
* To be able to use this - don't take locks, don't rely on destructors,
* don't make OS library calls, don't allocate memory, don't print,
* don't call code that could leave the heap / memory in an inconsistent state,
* or anything else where we are not in control if we suddenly jump out.
*/
class
WatcherThreadCrashProtection
:
public
StackObj
{
public:
WatcherThreadCrashProtection
();
bool
call
(
os
::
CrashProtectionCallback
&
cb
);
static
void
check_crash_protection
(
int
signal
,
Thread
*
thread
);
private:
void
restore
();
sigjmp_buf
_jmpbuf
;
};
#endif
src/os/windows/vm/os_windows.cpp
浏览文件 @
892c54bb
...
...
@@ -4684,6 +4684,34 @@ void os::pause() {
}
}
os
::
WatcherThreadCrashProtection
::
WatcherThreadCrashProtection
()
{
assert
(
Thread
::
current
()
->
is_Watcher_thread
(),
"Must be WatcherThread"
);
}
/*
* See the caveats for this class in os_windows.hpp
* Protects the callback call so that raised OS EXCEPTIONS causes a jump back
* into this method and returns false. If no OS EXCEPTION was raised, returns
* true.
* The callback is supposed to provide the method that should be protected.
*/
bool
os
::
WatcherThreadCrashProtection
::
call
(
os
::
CrashProtectionCallback
&
cb
)
{
assert
(
Thread
::
current
()
->
is_Watcher_thread
(),
"Only for WatcherThread"
);
assert
(
!
WatcherThread
::
watcher_thread
()
->
has_crash_protection
(),
"crash_protection already set?"
);
bool
success
=
true
;
__try
{
WatcherThread
::
watcher_thread
()
->
set_crash_protection
(
this
);
cb
.
call
();
}
__except
(
EXCEPTION_EXECUTE_HANDLER
)
{
// only for protection, nothing to do
success
=
false
;
}
WatcherThread
::
watcher_thread
()
->
set_crash_protection
(
NULL
);
return
success
;
}
// An Event wraps a win32 "CreateEvent" kernel handle.
//
// We have a number of choices regarding "CreateEvent" win32 handle leakage:
...
...
src/os/windows/vm/os_windows.hpp
浏览文件 @
892c54bb
...
...
@@ -102,6 +102,20 @@ class win32 {
static
LONG
WINAPI
serialize_fault_filter
(
struct
_EXCEPTION_POINTERS
*
e
);
};
/*
* Crash protection for the watcher thread. Wrap the callback
* with a __try { call() }
* To be able to use this - don't take locks, don't rely on destructors,
* don't make OS library calls, don't allocate memory, don't print,
* don't call code that could leave the heap / memory in an inconsistent state,
* or anything else where we are not in control if we suddenly jump out.
*/
class
WatcherThreadCrashProtection
:
public
StackObj
{
public:
WatcherThreadCrashProtection
();
bool
call
(
os
::
CrashProtectionCallback
&
cb
);
};
class
PlatformEvent
:
public
CHeapObj
<
mtInternal
>
{
private:
double
CachePad
[
4
]
;
// increase odds that _Event is sole occupant of cache line
...
...
src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
浏览文件 @
892c54bb
...
...
@@ -401,6 +401,10 @@ JVM_handle_bsd_signal(int sig,
Thread
*
t
=
ThreadLocalStorage
::
get_thread_slow
();
// Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
// (no destructors can be run)
os
::
WatcherThreadCrashProtection
::
check_crash_protection
(
sig
,
t
);
SignalHandlerMark
shm
(
t
);
// Note: it's not uncommon that JNI code uses signal/sigset to install
...
...
src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp
浏览文件 @
892c54bb
...
...
@@ -553,6 +553,10 @@ JVM_handle_linux_signal(int sig,
Thread
*
t
=
ThreadLocalStorage
::
get_thread_slow
();
// Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
// (no destructors can be run)
os
::
WatcherThreadCrashProtection
::
check_crash_protection
(
sig
,
t
);
SignalHandlerMark
shm
(
t
);
// Note: it's not uncommon that JNI code uses signal/sigset to install
...
...
src/os_cpu/linux_x86/vm/os_linux_x86.cpp
浏览文件 @
892c54bb
...
...
@@ -225,6 +225,10 @@ JVM_handle_linux_signal(int sig,
Thread
*
t
=
ThreadLocalStorage
::
get_thread_slow
();
// Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
// (no destructors can be run)
os
::
WatcherThreadCrashProtection
::
check_crash_protection
(
sig
,
t
);
SignalHandlerMark
shm
(
t
);
// Note: it's not uncommon that JNI code uses signal/sigset to install
...
...
src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp
浏览文件 @
892c54bb
...
...
@@ -315,6 +315,10 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
Thread
*
t
=
ThreadLocalStorage
::
get_thread_slow
();
// Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
// (no destructors can be run)
os
::
WatcherThreadCrashProtection
::
check_crash_protection
(
sig
,
t
);
SignalHandlerMark
shm
(
t
);
if
(
sig
==
SIGPIPE
||
sig
==
SIGXFSZ
)
{
...
...
src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp
浏览文件 @
892c54bb
...
...
@@ -374,6 +374,10 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
Thread
*
t
=
ThreadLocalStorage
::
get_thread_slow
();
// slow & steady
// Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
// (no destructors can be run)
os
::
WatcherThreadCrashProtection
::
check_crash_protection
(
sig
,
t
);
SignalHandlerMark
shm
(
t
);
if
(
sig
==
SIGPIPE
||
sig
==
SIGXFSZ
)
{
...
...
src/share/vm/runtime/mutex.cpp
浏览文件 @
892c54bb
...
...
@@ -1370,6 +1370,10 @@ void Monitor::check_prelock_state(Thread *thread) {
debug_only
(
if
(
rank
()
!=
Mutex
::
special
)
\
thread
->
check_for_valid_safepoint_state
(
false
);)
}
if
(
thread
->
is_Watcher_thread
())
{
assert
(
!
WatcherThread
::
watcher_thread
()
->
has_crash_protection
(),
"locking not allowed when crash protection is set"
);
}
}
void
Monitor
::
check_block_state
(
Thread
*
thread
)
{
...
...
src/share/vm/runtime/os.cpp
浏览文件 @
892c54bb
...
...
@@ -595,6 +595,22 @@ void* os::malloc(size_t size, MEMFLAGS memflags, address caller) {
NOT_PRODUCT
(
inc_stat_counter
(
&
num_mallocs
,
1
));
NOT_PRODUCT
(
inc_stat_counter
(
&
alloc_bytes
,
size
));
#ifdef ASSERT
// checking for the WatcherThread and crash_protection first
// since os::malloc can be called when the libjvm.{dll,so} is
// first loaded and we don't have a thread yet.
// try to find the thread after we see that the watcher thread
// exists and has crash protection.
WatcherThread
*
wt
=
WatcherThread
::
watcher_thread
();
if
(
wt
!=
NULL
&&
wt
->
has_crash_protection
())
{
Thread
*
thread
=
ThreadLocalStorage
::
get_thread_slow
();
if
(
thread
==
wt
)
{
assert
(
!
wt
->
has_crash_protection
(),
"Can't malloc with crash protection from WatcherThread"
);
}
}
#endif
if
(
size
==
0
)
{
// return a valid pointer if size is zero
// if NULL is returned the calling functions assume out of memory.
...
...
src/share/vm/runtime/os.hpp
浏览文件 @
892c54bb
...
...
@@ -32,15 +32,18 @@
#include "utilities/top.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "jvm_linux.h"
# include <setjmp.h>
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "jvm_solaris.h"
# include <setjmp.h>
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "jvm_windows.h"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "jvm_bsd.h"
# include <setjmp.h>
#endif
// os defines the interface to operating system; this includes traditional
...
...
@@ -730,6 +733,10 @@ class os: AllStatic {
#include "runtime/os_ext.hpp"
public:
class
CrashProtectionCallback
:
public
StackObj
{
public:
virtual
void
call
()
=
0
;
};
// Platform dependent stuff
#ifdef TARGET_OS_FAMILY_linux
...
...
@@ -908,6 +915,7 @@ class os: AllStatic {
char
pathSep
);
static
bool
set_boot_path
(
char
fileSep
,
char
pathSep
);
static
char
**
split_path
(
const
char
*
path
,
int
*
n
);
};
// Note that "PAUSE" is almost always used with synchronization
...
...
src/share/vm/runtime/thread.cpp
浏览文件 @
892c54bb
...
...
@@ -1226,7 +1226,7 @@ WatcherThread* WatcherThread::_watcher_thread = NULL;
bool
WatcherThread
::
_startable
=
false
;
volatile
bool
WatcherThread
::
_should_terminate
=
false
;
WatcherThread
::
WatcherThread
()
:
Thread
()
{
WatcherThread
::
WatcherThread
()
:
Thread
()
,
_crash_protection
(
NULL
)
{
assert
(
watcher_thread
()
==
NULL
,
"we can only allocate one WatcherThread"
);
if
(
os
::
create_thread
(
this
,
os
::
watcher_thread
))
{
_watcher_thread
=
this
;
...
...
src/share/vm/runtime/thread.hpp
浏览文件 @
892c54bb
...
...
@@ -733,6 +733,8 @@ class WatcherThread: public Thread {
static
bool
_startable
;
volatile
static
bool
_should_terminate
;
// updated without holding lock
os
::
WatcherThreadCrashProtection
*
_crash_protection
;
public:
enum
SomeConstants
{
delay_interval
=
10
// interrupt delay in milliseconds
...
...
@@ -760,6 +762,14 @@ class WatcherThread: public Thread {
// Otherwise the first task to enroll will trigger the start
static
void
make_startable
();
void
set_crash_protection
(
os
::
WatcherThreadCrashProtection
*
crash_protection
)
{
assert
(
Thread
::
current
()
->
is_Watcher_thread
(),
"Can only be set by WatcherThread"
);
_crash_protection
=
crash_protection
;
}
bool
has_crash_protection
()
const
{
return
_crash_protection
!=
NULL
;
}
os
::
WatcherThreadCrashProtection
*
crash_protection
()
const
{
return
_crash_protection
;
}
private:
int
sleep
()
const
;
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录