comparison src/os_cpu/solaris_sparc/vm/thread_solaris_sparc.cpp @ 107:93b6525e3b82

6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on Summary: Rewrite frame::safe_for_sender and friends to be safe for collector/analyzer Reviewed-by: dcubed, kvn
author sgoldman
date Tue, 08 Apr 2008 12:23:15 -0400
parents a61af66fc99e
children d1605aabd0a1
comparison
equal deleted inserted replaced
106:c9314fa4f757 107:93b6525e3b82
48 48
49 // If we have a walkable last_Java_frame, then we should use it 49 // If we have a walkable last_Java_frame, then we should use it
50 // even if isInJava == true. It should be more reliable than 50 // even if isInJava == true. It should be more reliable than
51 // ucontext info. 51 // ucontext info.
52 if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) { 52 if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) {
53 #if 0
54 // This sanity check may not be needed with the new frame
55 // walking code. Remove it for now.
56 if (!jt->frame_anchor()->post_Java_state_is_pc()
57 && frame::next_younger_sp_or_null(last_Java_sp(),
58 jt->frame_anchor()->post_Java_sp()) == NULL) {
59 // the anchor contains an SP, but the frame is not walkable
60 // because post_Java_sp isn't valid relative to last_Java_sp
61 return false;
62 }
63 #endif
64 *fr_addr = jt->pd_last_frame(); 53 *fr_addr = jt->pd_last_frame();
65 return true; 54 return true;
66 } 55 }
67 56
68 ucontext_t* uc = (ucontext_t*) ucontext; 57 ucontext_t* uc = (ucontext_t*) ucontext;
75 if (addr.pc() == NULL || ret_sp == NULL) { 64 if (addr.pc() == NULL || ret_sp == NULL) {
76 // ucontext wasn't useful 65 // ucontext wasn't useful
77 return false; 66 return false;
78 } 67 }
79 68
69 frame ret_frame(ret_sp, frame::unpatchable, addr.pc());
70
80 // we were running Java code when SIGPROF came in 71 // we were running Java code when SIGPROF came in
81 if (isInJava) { 72 if (isInJava) {
73
74
75 // If the frame we got is safe then it is most certainly valid
76 if (ret_frame.safe_for_sender(jt)) {
77 *fr_addr = ret_frame;
78 return true;
79 }
80
81 // If it isn't safe then we can try several things to try and get
82 // a good starting point.
83 //
84 // On sparc the frames are almost certainly walkable in the sense
85 // of sp/fp linkages. However because of recycling of windows if
86 // a piece of code does multiple save's where the initial save creates
87 // a real frame with a return pc and the succeeding save's are used to
88 // simply get free registers and have no real pc then the pc linkage on these
89 // "inner" temporary frames will be bogus.
90 // Since there is in general only a nesting level like
91 // this one deep in general we'll try and unwind such an "inner" frame
92 // here ourselves and see if it makes sense
93
94 frame unwind_frame(ret_frame.fp(), frame::unpatchable, addr.pc());
95
96 if (unwind_frame.safe_for_sender(jt)) {
97 *fr_addr = unwind_frame;
98 return true;
99 }
100
101 // Well that didn't work. Most likely we're toast on this tick
102 // The previous code would try this. I think it is dubious in light
103 // of changes to safe_for_sender and the unwind trick above but
104 // if it gets us a safe frame who wants to argue.
105
82 // If we have a last_Java_sp, then the SIGPROF signal caught us 106 // If we have a last_Java_sp, then the SIGPROF signal caught us
83 // right when we were transitioning from _thread_in_Java to a new 107 // right when we were transitioning from _thread_in_Java to a new
84 // JavaThreadState. We use last_Java_sp instead of the sp from 108 // JavaThreadState. We use last_Java_sp instead of the sp from
85 // the ucontext since it should be more reliable. 109 // the ucontext since it should be more reliable.
110
86 if (jt->has_last_Java_frame()) { 111 if (jt->has_last_Java_frame()) {
87 ret_sp = jt->last_Java_sp(); 112 ret_sp = jt->last_Java_sp();
113 frame ret_frame2(ret_sp, frame::unpatchable, addr.pc());
114 if (ret_frame2.safe_for_sender(jt)) {
115 *fr_addr = ret_frame2;
116 return true;
117 }
88 } 118 }
89 // Implied else: we don't have a last_Java_sp so we use what we
90 // got from the ucontext.
91 119
92 frame ret_frame(ret_sp, frame::unpatchable, addr.pc()); 120 // This is the best we can do. We will only be able to decode the top frame
93 if (!ret_frame.safe_for_sender(jt)) { 121
94 // nothing else to try if the frame isn't good
95 return false;
96 }
97 *fr_addr = ret_frame; 122 *fr_addr = ret_frame;
98 return true; 123 return true;
99 } 124 }
100 125
101 // At this point, we know we weren't running Java code. We might 126 // At this point, we know we weren't running Java code. We might
103 // However, we might still be able to construct something useful 128 // However, we might still be able to construct something useful
104 // if the thread was running native code. 129 // if the thread was running native code.
105 if (jt->has_last_Java_frame()) { 130 if (jt->has_last_Java_frame()) {
106 assert(!jt->frame_anchor()->walkable(), "case covered above"); 131 assert(!jt->frame_anchor()->walkable(), "case covered above");
107 132
108 if (jt->thread_state() == _thread_in_native) { 133 frame ret_frame(jt->last_Java_sp(), frame::unpatchable, addr.pc());
109 frame ret_frame(jt->last_Java_sp(), frame::unpatchable, addr.pc()); 134 *fr_addr = ret_frame;
110 if (!ret_frame.safe_for_sender(jt)) { 135 return true;
111 // nothing else to try if the frame isn't good
112 return false;
113 }
114 *fr_addr = ret_frame;
115 return true;
116 }
117 } 136 }
118 137
119 // nothing else to try 138 // nothing else to try but what we found initially
120 return false; 139
140 *fr_addr = ret_frame;
141 return true;
121 } 142 }