Mercurial > hg > truffle
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 } |