Skip to content

Commit 579fbcb

Browse files
RealLucyTheRealMDoerr
authored andcommitted
8271490: [ppc] [s390]: Crash in JavaThread::pd_get_top_frame_for_profiling
Reviewed-by: mdoerr Backport-of: 276b07b36af01d339e48baada7a512451fe34afe
1 parent 9437d45 commit 579fbcb

File tree

4 files changed

+95
-33
lines changed

4 files changed

+95
-33
lines changed

src/hotspot/cpu/ppc/frame_ppc.cpp

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ void RegisterMap::check_location_valid() {
4848
#endif // ASSERT
4949

5050
bool frame::safe_for_sender(JavaThread *thread) {
51-
bool safe = false;
5251
address sp = (address)_sp;
5352
address fp = (address)_fp;
5453
address unextended_sp = (address)_unextended_sp;
@@ -76,29 +75,23 @@ bool frame::safe_for_sender(JavaThread *thread) {
7675

7776
// An fp must be within the stack and above (but not equal) sp.
7877
bool fp_safe = (fp <= thread->stack_base()) && (fp > sp);
79-
// An interpreter fp must be within the stack and above (but not equal) sp.
80-
// Moreover, it must be at least the size of the ijava_state structure.
81-
bool fp_interp_safe = (fp <= thread->stack_base()) && (fp > sp) &&
82-
((fp - sp) >= ijava_state_size);
78+
// An interpreter fp must be fp_safe.
79+
// Moreover, it must be at a distance at least the size of the ijava_state structure.
80+
bool fp_interp_safe = fp_safe && ((fp - sp) >= ijava_state_size);
8381

8482
// We know sp/unextended_sp are safe, only fp is questionable here
8583

8684
// If the current frame is known to the code cache then we can attempt to
87-
// to construct the sender and do some validation of it. This goes a long way
85+
// construct the sender and do some validation of it. This goes a long way
8886
// toward eliminating issues when we get in frame construction code
8987

9088
if (_cb != NULL ){
91-
// Entry frame checks
92-
if (is_entry_frame()) {
93-
// An entry frame must have a valid fp.
94-
return fp_safe && is_entry_frame_valid(thread);
95-
}
9689

97-
// Now check if the frame is complete and the test is
98-
// reliable. Unfortunately we can only check frame completeness for
99-
// runtime stubs and nmethods. Other generic buffer blobs are more
100-
// problematic so we just assume they are OK. Adapter blobs never have a
101-
// complete frame and are never OK
90+
// First check if the frame is complete and the test is reliable.
91+
// Unfortunately we can only check frame completeness for runtime stubs
92+
// and nmethods. Other generic buffer blobs are more problematic
93+
// so we just assume they are OK.
94+
// Adapter blobs never have a complete frame and are never OK
10295
if (!_cb->is_frame_complete_at(_pc)) {
10396
if (_cb->is_compiled() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) {
10497
return false;
@@ -110,10 +103,23 @@ bool frame::safe_for_sender(JavaThread *thread) {
110103
return false;
111104
}
112105

106+
// Entry frame checks
107+
if (is_entry_frame()) {
108+
// An entry frame must have a valid fp.
109+
return fp_safe && is_entry_frame_valid(thread);
110+
}
111+
113112
if (is_interpreted_frame() && !fp_interp_safe) {
114113
return false;
115114
}
116115

116+
// At this point, there still is a chance that fp_safe is false.
117+
// In particular, (fp == NULL) might be true. So let's check and
118+
// bail out before we actually dereference from fp.
119+
if (!fp_safe) {
120+
return false;
121+
}
122+
117123
abi_minframe* sender_abi = (abi_minframe*) fp;
118124
intptr_t* sender_sp = (intptr_t*) fp;
119125
address sender_pc = (address) sender_abi->lr;;

src/hotspot/cpu/s390/frame_s390.cpp

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ void RegisterMap::check_location_valid() {
5252
// Profiling/safepoint support
5353

5454
bool frame::safe_for_sender(JavaThread *thread) {
55-
bool safe = false;
5655
address sp = (address)_sp;
5756
address fp = (address)_fp;
5857
address unextended_sp = (address)_unextended_sp;
@@ -80,29 +79,23 @@ bool frame::safe_for_sender(JavaThread *thread) {
8079

8180
// An fp must be within the stack and above (but not equal) sp.
8281
bool fp_safe = (fp <= thread->stack_base()) && (fp > sp);
83-
// An interpreter fp must be within the stack and above (but not equal) sp.
84-
// Moreover, it must be at least the size of the z_ijava_state structure.
85-
bool fp_interp_safe = (fp <= thread->stack_base()) && (fp > sp) &&
86-
((fp - sp) >= z_ijava_state_size);
82+
// An interpreter fp must be fp_safe.
83+
// Moreover, it must be at a distance at least the size of the z_ijava_state structure.
84+
bool fp_interp_safe = fp_safe && ((fp - sp) >= z_ijava_state_size);
8785

8886
// We know sp/unextended_sp are safe, only fp is questionable here
8987

9088
// If the current frame is known to the code cache then we can attempt to
91-
// to construct the sender and do some validation of it. This goes a long way
89+
// construct the sender and do some validation of it. This goes a long way
9290
// toward eliminating issues when we get in frame construction code
9391

9492
if (_cb != NULL ) {
95-
// Entry frame checks
96-
if (is_entry_frame()) {
97-
// An entry frame must have a valid fp.
98-
return fp_safe && is_entry_frame_valid(thread);
99-
}
10093

101-
// Now check if the frame is complete and the test is
102-
// reliable. Unfortunately we can only check frame completeness for
103-
// runtime stubs. Other generic buffer blobs are more
104-
// problematic so we just assume they are OK. Adapter blobs never have a
105-
// complete frame and are never OK. nmethods should be OK on s390.
94+
// First check if the frame is complete and the test is reliable.
95+
// Unfortunately we can only check frame completeness for runtime stubs.
96+
// Other generic buffer blobs are more problematic so we just assume they are OK.
97+
// Adapter blobs never have a complete frame and are never OK.
98+
// nmethods should be OK on s390.
10699
if (!_cb->is_frame_complete_at(_pc)) {
107100
if (_cb->is_adapter_blob() || _cb->is_runtime_stub()) {
108101
return false;
@@ -114,13 +107,26 @@ bool frame::safe_for_sender(JavaThread *thread) {
114107
return false;
115108
}
116109

110+
// Entry frame checks
111+
if (is_entry_frame()) {
112+
// An entry frame must have a valid fp.
113+
return fp_safe && is_entry_frame_valid(thread);
114+
}
115+
117116
if (is_interpreted_frame() && !fp_interp_safe) {
118117
return false;
119118
}
120119

120+
// At this point, there still is a chance that fp_safe is false.
121+
// In particular, (fp == NULL) might be true. So let's check and
122+
// bail out before we actually dereference from fp.
123+
if (!fp_safe) {
124+
return false;
125+
}
126+
121127
z_abi_160* sender_abi = (z_abi_160*) fp;
122128
intptr_t* sender_sp = (intptr_t*) sender_abi->callers_sp;
123-
address sender_pc = (address) sender_abi->return_pc;
129+
address sender_pc = (address) sender_abi->return_pc;
124130

125131
// We must always be able to find a recognizable pc.
126132
CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc);

src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ frame JavaThread::pd_last_frame() {
3434
address pc = _anchor.last_Java_pc();
3535

3636
// Last_Java_pc ist not set, if we come here from compiled code.
37+
// Assume spill slot for link register contains a suitable pc.
38+
// Should have been filled by method entry code.
3739
if (pc == NULL) {
3840
pc = (address) *(sp + 2);
3941
}
@@ -64,6 +66,17 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
6466
return false;
6567
}
6668

69+
if (ret_frame.fp() == NULL) {
70+
// The found frame does not have a valid frame pointer.
71+
// Bail out because this will create big trouble later on, either
72+
// - when using istate, calculated as (NULL - ijava_state_size) or
73+
// - when using fp() directly in safe_for_sender()
74+
//
75+
// There is no conclusive description (yet) how this could happen, but it does.
76+
// For more details on what was observed, see thread_linux_s390.cpp
77+
return false;
78+
}
79+
6780
if (ret_frame.is_interpreted_frame()) {
6881
frame::ijava_state *istate = ret_frame.get_ijava_state();
6982
const Method *m = (const Method*)(istate->method);

src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ frame JavaThread::pd_last_frame() {
3434
address pc = _anchor.last_Java_pc();
3535

3636
// Last_Java_pc ist not set if we come here from compiled code.
37+
// Assume spill slot for Z_R14 (return register) contains a suitable pc.
38+
// Should have been filled by method entry code.
3739
if (pc == NULL) {
3840
pc = (address) *(sp + 14);
3941
}
@@ -51,6 +53,9 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
5153
return true;
5254
}
5355

56+
// At this point, we don't have a last_Java_frame, so
57+
// we try to glean some information out of the ucontext
58+
// if we were running Java code when SIGPROF came in.
5459
if (isInJava) {
5560
ucontext_t* uc = (ucontext_t*) ucontext;
5661
frame ret_frame((intptr_t*)uc->uc_mcontext.gregs[15/*Z_SP*/],
@@ -61,6 +66,38 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
6166
return false;
6267
}
6368

69+
if (ret_frame.fp() == NULL) {
70+
// The found frame does not have a valid frame pointer.
71+
// Bail out because this will create big trouble later on, either
72+
// - when using istate, calculated as (NULL - z_ijava_state_size (= 0x70 (dbg) or 0x68 (rel)) or
73+
// - when using fp() directly in safe_for_sender()
74+
//
75+
// There is no conclusive description (yet) how this could happen, but it does:
76+
//
77+
// We observed a SIGSEGV with the following stack trace (openjdk.jdk11u-dev, 2021-07-07, linuxs390x fastdebug)
78+
// V [libjvm.so+0x12c8f12] JavaThread::pd_get_top_frame_for_profiling(frame*, void*, bool)+0x142
79+
// V [libjvm.so+0xb1020c] JfrGetCallTrace::get_topframe(void*, frame&)+0x3c
80+
// V [libjvm.so+0xba0b08] OSThreadSampler::protected_task(os::SuspendedThreadTaskContext const&)+0x98
81+
// V [libjvm.so+0xff33c4] os::SuspendedThreadTask::internal_do_task()+0x14c
82+
// V [libjvm.so+0xfe3c9c] os::SuspendedThreadTask::run()+0x24
83+
// V [libjvm.so+0xba0c66] JfrThreadSampleClosure::sample_thread_in_java(JavaThread*, JfrStackFrame*, unsigned int)+0x66
84+
// V [libjvm.so+0xba1718] JfrThreadSampleClosure::do_sample_thread(JavaThread*, JfrStackFrame*, unsigned int, JfrSampleType)+0x278
85+
// V [libjvm.so+0xba4f54] JfrThreadSampler::task_stacktrace(JfrSampleType, JavaThread**) [clone .constprop.62]+0x284
86+
// V [libjvm.so+0xba5e54] JfrThreadSampler::run()+0x2ec
87+
// V [libjvm.so+0x12adc9c] Thread::call_run()+0x9c
88+
// V [libjvm.so+0xff5ab0] thread_native_entry(Thread*)+0x128
89+
// siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR), si_addr: 0xfffffffffffff000
90+
// failing instruction: e320 6008 0004 LG r2,8(r0,r6)
91+
// contents of r6: 0xffffffffffffff90
92+
//
93+
// Here is the sequence of what happens:
94+
// - ret_frame is constructed with _fp == NULL (for whatever reason)
95+
// - ijava_state_unchecked() calculates it's result as
96+
// istate = fp() - z_ijava_state_size() = NULL - 0x68 DEBUG_ONLY(-8)
97+
// - istate->method dereferences memory at offset 8 from istate
98+
return false;
99+
}
100+
64101
if (ret_frame.is_interpreted_frame()) {
65102
frame::z_ijava_state* istate = ret_frame.ijava_state_unchecked();
66103
if (stack_base() >= (address)istate && (address)istate > stack_end()) {

0 commit comments

Comments
 (0)