@@ -87,24 +87,130 @@ char* os::non_memory_address_word() {
8787}
8888
8989address os::Posix::ucontext_get_pc (const ucontext_t * uc) {
90- ShouldNotCallThis ();
91- return NULL ; // silence compile warnings
90+ if (DecodeErrorContext) {
91+ #if defined(IA32)
92+ return (address)uc->uc_mcontext .gregs [REG_EIP];
93+ #elif defined(AMD64)
94+ return (address)uc->uc_mcontext .gregs [REG_RIP];
95+ #elif defined(ARM)
96+ return (address)uc->uc_mcontext .arm_pc ;
97+ #elif defined(AARCH64)
98+ return (address)uc->uc_mcontext .pc ;
99+ #elif defined(PPC)
100+ return (address)uc->uc_mcontext .regs ->nip ;
101+ #elif defined(RISCV)
102+ return (address)uc->uc_mcontext .__gregs [REG_PC];
103+ #elif defined(S390)
104+ return (address)uc->uc_mcontext .psw .addr ;
105+ #else
106+ // Non-arch-specific Zero code does not really know the PC.
107+ // If possible, add the arch-specific definition in this method.
108+ fatal (" Cannot handle ucontext_get_pc" );
109+ #endif
110+ }
111+
112+ // Answer the default and hope for the best
113+ return nullptr ;
92114}
93115
94- void os::Posix::ucontext_set_pc (ucontext_t * uc, address pc) {
116+ void os::Posix::ucontext_set_pc (ucontext_t * uc, address pc) {
95117 ShouldNotCallThis ();
96118}
97119
120+ intptr_t * os::Linux::ucontext_get_sp (const ucontext_t * uc) {
121+ if (DecodeErrorContext) {
122+ #if defined(IA32)
123+ return (intptr_t *)uc->uc_mcontext .gregs [REG_UESP];
124+ #elif defined(AMD64)
125+ return (intptr_t *)uc->uc_mcontext .gregs [REG_RSP];
126+ #elif defined(ARM)
127+ return (intptr_t *)uc->uc_mcontext .arm_sp ;
128+ #elif defined(AARCH64)
129+ return (intptr_t *)uc->uc_mcontext .sp ;
130+ #elif defined(PPC)
131+ return (intptr_t *)uc->uc_mcontext .regs ->gpr [1 /* REG_SP*/ ];
132+ #elif defined(RISCV)
133+ return (intptr_t *)uc->uc_mcontext .__gregs [REG_SP];
134+ #elif defined(S390)
135+ return (intptr_t *)uc->uc_mcontext .gregs [15 /* REG_SP*/ ];
136+ #else
137+ // Non-arch-specific Zero code does not really know the SP.
138+ // If possible, add the arch-specific definition in this method.
139+ fatal (" Cannot handle ucontext_get_sp" );
140+ #endif
141+ }
142+
143+ // Answer the default and hope for the best
144+ return nullptr ;
145+ }
146+
147+ intptr_t * os::Linux::ucontext_get_fp (const ucontext_t * uc) {
148+ if (DecodeErrorContext) {
149+ #if defined(IA32)
150+ return (intptr_t *)uc->uc_mcontext .gregs [REG_EBP];
151+ #elif defined(AMD64)
152+ return (intptr_t *)uc->uc_mcontext .gregs [REG_RBP];
153+ #elif defined(ARM)
154+ return (intptr_t *)uc->uc_mcontext .arm_fp ;
155+ #elif defined(AARCH64)
156+ return (intptr_t *)uc->uc_mcontext .regs [29 /* REG_FP */ ];
157+ #elif defined(PPC)
158+ return nullptr ;
159+ #elif defined(RISCV)
160+ return (intptr_t *)uc->uc_mcontext .__gregs [8 /* REG_FP */ ];
161+ #elif defined(S390)
162+ return nullptr ;
163+ #else
164+ // Non-arch-specific Zero code does not really know the FP.
165+ // If possible, add the arch-specific definition in this method.
166+ fatal (" Cannot handle ucontext_get_fp" );
167+ #endif
168+ }
169+
170+ // Answer the default and hope for the best
171+ return nullptr ;
172+ }
173+
98174address os::fetch_frame_from_context (const void * ucVoid,
99175 intptr_t ** ret_sp,
100176 intptr_t ** ret_fp) {
101- ShouldNotCallThis ();
102- return NULL ; // silence compile warnings
177+ address epc;
178+ const ucontext_t * uc = (const ucontext_t *)ucVoid;
179+
180+ if (uc != NULL ) {
181+ epc = os::Posix::ucontext_get_pc (uc);
182+ if (ret_sp) {
183+ *ret_sp = (intptr_t *) os::Linux::ucontext_get_sp (uc);
184+ }
185+ if (ret_fp) {
186+ *ret_fp = (intptr_t *) os::Linux::ucontext_get_fp (uc);
187+ }
188+ } else {
189+ epc = NULL ;
190+ if (ret_sp) {
191+ *ret_sp = nullptr ;
192+ }
193+ if (ret_fp) {
194+ *ret_fp = nullptr ;
195+ }
196+ }
197+
198+ return epc;
103199}
104200
105201frame os::fetch_frame_from_context (const void * ucVoid) {
106- ShouldNotCallThis ();
107- return frame (NULL , NULL ); // silence compile warnings
202+ // This code is only called from error handler to get PC and SP.
203+ // We don't have the ready ZeroFrame* at this point, so fake the
204+ // frame with bare minimum.
205+ if (ucVoid != NULL ) {
206+ const ucontext_t * uc = (const ucontext_t *)ucVoid;
207+ frame dummy = frame ();
208+ dummy.set_pc (os::Posix::ucontext_get_pc (uc));
209+ dummy.set_sp ((intptr_t *)os::Linux::ucontext_get_sp (uc));
210+ return dummy;
211+ } else {
212+ return frame (nullptr , nullptr );
213+ }
108214}
109215
110216bool PosixSignals::pd_hotspot_signal_handler (int sig, siginfo_t * info,
@@ -288,16 +394,27 @@ size_t os::current_stack_size() {
288394// ///////////////////////////////////////////////////////////////////////////
289395// helper functions for fatal error handler
290396
291- void os::print_context (outputStream* st, const void * context ) {
292- ShouldNotCallThis ( );
397+ void os::print_context (outputStream* st, const void * ucVoid ) {
398+ st-> print_cr ( " No context information. " );
293399}
294400
295- void os::print_tos_pc (outputStream *st, const void *context) {
296- ShouldNotCallThis ();
401+ void os::print_tos_pc (outputStream *st, const void * ucVoid) {
402+ const ucontext_t * uc = (const ucontext_t *)ucVoid;
403+
404+ address sp = (address)os::Linux::ucontext_get_sp (uc);
405+ print_tos (st, sp);
406+ st->cr ();
407+
408+ // Note: it may be unsafe to inspect memory near pc. For example, pc may
409+ // point to garbage if entry point in an nmethod is corrupted. Leave
410+ // this at the end, and hope for the best.
411+ address pc = os::Posix::ucontext_get_pc (uc);
412+ print_instructions (st, pc, sizeof (char ));
413+ st->cr ();
297414}
298415
299- void os::print_register_info (outputStream *st, const void *context ) {
300- ShouldNotCallThis ( );
416+ void os::print_register_info (outputStream *st, const void * ucVoid ) {
417+ st-> print_cr ( " No register info. " );
301418}
302419
303420// ///////////////////////////////////////////////////////////////////////////
0 commit comments