Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/utilities/debug.cpp
40949 views
1
/*
2
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
#include "precompiled.hpp"
26
#include "jvm.h"
27
#include "classfile/systemDictionary.hpp"
28
#include "code/codeCache.hpp"
29
#include "code/icBuffer.hpp"
30
#include "code/nmethod.hpp"
31
#include "code/vtableStubs.hpp"
32
#include "compiler/compileBroker.hpp"
33
#include "compiler/disassembler.hpp"
34
#include "gc/shared/collectedHeap.hpp"
35
#include "interpreter/interpreter.hpp"
36
#include "memory/allocation.hpp"
37
#include "memory/resourceArea.hpp"
38
#include "memory/universe.hpp"
39
#include "oops/klass.inline.hpp"
40
#include "oops/oop.inline.hpp"
41
#include "runtime/atomic.hpp"
42
#include "runtime/flags/flagSetting.hpp"
43
#include "runtime/frame.inline.hpp"
44
#include "runtime/handles.inline.hpp"
45
#include "runtime/java.hpp"
46
#include "runtime/os.hpp"
47
#include "runtime/sharedRuntime.hpp"
48
#include "runtime/stubCodeGenerator.hpp"
49
#include "runtime/stubRoutines.hpp"
50
#include "runtime/thread.inline.hpp"
51
#include "runtime/vframe.hpp"
52
#include "runtime/vm_version.hpp"
53
#include "services/heapDumper.hpp"
54
#include "services/memTracker.hpp"
55
#include "utilities/defaultStream.hpp"
56
#include "utilities/events.hpp"
57
#include "utilities/formatBuffer.hpp"
58
#include "utilities/globalDefinitions.hpp"
59
#include "utilities/macros.hpp"
60
#include "utilities/vmError.hpp"
61
62
#include <stdio.h>
63
#include <stdarg.h>
64
65
// Support for showing register content on asserts/guarantees.
66
#ifdef CAN_SHOW_REGISTERS_ON_ASSERT
67
static char g_dummy;
68
char* g_assert_poison = &g_dummy;
69
static intx g_asserting_thread = 0;
70
static void* g_assertion_context = NULL;
71
#endif // CAN_SHOW_REGISTERS_ON_ASSERT
72
73
// Set to suppress secondary error reporting.
74
bool Debugging = false;
75
76
#ifndef ASSERT
77
# ifdef _DEBUG
78
// NOTE: don't turn the lines below into a comment -- if you're getting
79
// a compile error here, change the settings to define ASSERT
80
ASSERT should be defined when _DEBUG is defined. It is not intended to be used for debugging
81
functions that do not slow down the system too much and thus can be left in optimized code.
82
On the other hand, the code should not be included in a production version.
83
# endif // _DEBUG
84
#endif // ASSERT
85
86
87
#ifdef _DEBUG
88
# ifndef ASSERT
89
configuration error: ASSERT must be defined in debug version
90
# endif // ASSERT
91
#endif // _DEBUG
92
93
94
#ifdef PRODUCT
95
# if -defined _DEBUG || -defined ASSERT
96
configuration error: ASSERT et al. must not be defined in PRODUCT version
97
# endif
98
#endif // PRODUCT
99
100
#ifdef ASSERT
101
// This is to test that error reporting works if we assert during dynamic
102
// initialization of the hotspot. See JDK-8214975.
103
struct Crasher {
104
Crasher() {
105
// Using getenv - no other mechanism would work yet.
106
const char* s = ::getenv("HOTSPOT_FATAL_ERROR_DURING_DYNAMIC_INITIALIZATION");
107
if (s != NULL && ::strcmp(s, "1") == 0) {
108
fatal("HOTSPOT_FATAL_ERROR_DURING_DYNAMIC_INITIALIZATION");
109
}
110
}
111
};
112
static Crasher g_crasher;
113
#endif // ASSERT
114
115
ATTRIBUTE_PRINTF(1, 2)
116
void warning(const char* format, ...) {
117
if (PrintWarnings) {
118
FILE* const err = defaultStream::error_stream();
119
jio_fprintf(err, "%s warning: ", VM_Version::vm_name());
120
va_list ap;
121
va_start(ap, format);
122
vfprintf(err, format, ap);
123
va_end(ap);
124
fputc('\n', err);
125
}
126
}
127
128
#ifndef PRODUCT
129
130
#define is_token_break(ch) (isspace(ch) || (ch) == ',')
131
132
static const char* last_file_name = NULL;
133
static int last_line_no = -1;
134
135
// assert/guarantee/... may happen very early during VM initialization.
136
// Don't rely on anything that is initialized by Threads::create_vm(). For
137
// example, don't use tty.
138
bool error_is_suppressed(const char* file_name, int line_no) {
139
// The following 1-element cache requires that passed-in
140
// file names are always only constant literals.
141
if (file_name == last_file_name && line_no == last_line_no) return true;
142
143
int file_name_len = (int)strlen(file_name);
144
char separator = os::file_separator()[0];
145
const char* base_name = strrchr(file_name, separator);
146
if (base_name == NULL)
147
base_name = file_name;
148
149
// scan the SuppressErrorAt option
150
const char* cp = SuppressErrorAt;
151
for (;;) {
152
const char* sfile;
153
int sfile_len;
154
int sline;
155
bool noisy;
156
while ((*cp) != '\0' && is_token_break(*cp)) cp++;
157
if ((*cp) == '\0') break;
158
sfile = cp;
159
while ((*cp) != '\0' && !is_token_break(*cp) && (*cp) != ':') cp++;
160
sfile_len = cp - sfile;
161
if ((*cp) == ':') cp++;
162
sline = 0;
163
while ((*cp) != '\0' && isdigit(*cp)) {
164
sline *= 10;
165
sline += (*cp) - '0';
166
cp++;
167
}
168
// "file:line!" means the assert suppression is not silent
169
noisy = ((*cp) == '!');
170
while ((*cp) != '\0' && !is_token_break(*cp)) cp++;
171
// match the line
172
if (sline != 0) {
173
if (sline != line_no) continue;
174
}
175
// match the file
176
if (sfile_len > 0) {
177
const char* look = file_name;
178
const char* look_max = file_name + file_name_len - sfile_len;
179
const char* foundp;
180
bool match = false;
181
while (!match
182
&& (foundp = strchr(look, sfile[0])) != NULL
183
&& foundp <= look_max) {
184
match = true;
185
for (int i = 1; i < sfile_len; i++) {
186
if (sfile[i] != foundp[i]) {
187
match = false;
188
break;
189
}
190
}
191
look = foundp + 1;
192
}
193
if (!match) continue;
194
}
195
// got a match!
196
if (noisy) {
197
fdStream out(defaultStream::output_fd());
198
out.print_raw("[error suppressed at ");
199
out.print_raw(base_name);
200
char buf[16];
201
jio_snprintf(buf, sizeof(buf), ":%d]", line_no);
202
out.print_raw_cr(buf);
203
} else {
204
// update 1-element cache for fast silent matches
205
last_file_name = file_name;
206
last_line_no = line_no;
207
}
208
return true;
209
}
210
211
if (!VMError::is_error_reported() && !SuppressFatalErrorMessage) {
212
// print a friendly hint:
213
fdStream out(defaultStream::output_fd());
214
out.print_raw_cr("# To suppress the following error report, specify this argument");
215
out.print_raw ("# after -XX: or in .hotspotrc: SuppressErrorAt=");
216
out.print_raw (base_name);
217
char buf[16];
218
jio_snprintf(buf, sizeof(buf), ":%d", line_no);
219
out.print_raw_cr(buf);
220
}
221
return false;
222
}
223
224
#undef is_token_break
225
226
#else
227
228
// Place-holder for non-existent suppression check:
229
#define error_is_suppressed(file_name, line_no) (false)
230
231
#endif // !PRODUCT
232
233
void report_vm_error(const char* file, int line, const char* error_msg)
234
{
235
report_vm_error(file, line, error_msg, "%s", "");
236
}
237
238
239
static void print_error_for_unit_test(const char* message, const char* detail_fmt, va_list detail_args) {
240
#ifdef ASSERT
241
if (ExecutingUnitTests) {
242
char detail_msg[256];
243
if (detail_fmt != NULL) {
244
// Special handling for the sake of gtest death tests which expect the assert
245
// message to be printed in one short line to stderr (see TEST_VM_ASSERT_MSG) and
246
// cannot be tweaked to accept our normal assert message.
247
va_list detail_args_copy;
248
va_copy(detail_args_copy, detail_args);
249
jio_vsnprintf(detail_msg, sizeof(detail_msg), detail_fmt, detail_args_copy);
250
251
// the VM assert tests look for "assert failed: "
252
if (message == NULL) {
253
fprintf(stderr, "assert failed: %s", detail_msg);
254
} else {
255
if (strlen(detail_msg) > 0) {
256
fprintf(stderr, "assert failed: %s: %s", message, detail_msg);
257
} else {
258
fprintf(stderr, "assert failed: Error: %s", message);
259
}
260
}
261
::fflush(stderr);
262
va_end(detail_args_copy);
263
}
264
}
265
#endif // ASSERT
266
}
267
268
void report_vm_error(const char* file, int line, const char* error_msg, const char* detail_fmt, ...)
269
{
270
if (Debugging || error_is_suppressed(file, line)) return;
271
va_list detail_args;
272
va_start(detail_args, detail_fmt);
273
void* context = NULL;
274
#ifdef CAN_SHOW_REGISTERS_ON_ASSERT
275
if (g_assertion_context != NULL && os::current_thread_id() == g_asserting_thread) {
276
context = g_assertion_context;
277
}
278
#endif // CAN_SHOW_REGISTERS_ON_ASSERT
279
280
print_error_for_unit_test(error_msg, detail_fmt, detail_args);
281
282
VMError::report_and_die(Thread::current_or_null(), context, file, line, error_msg, detail_fmt, detail_args);
283
va_end(detail_args);
284
}
285
286
void report_vm_status_error(const char* file, int line, const char* error_msg,
287
int status, const char* detail) {
288
report_vm_error(file, line, error_msg, "error %s(%d), %s", os::errno_name(status), status, detail);
289
}
290
291
void report_fatal(VMErrorType error_type, const char* file, int line, const char* detail_fmt, ...) {
292
if (Debugging || error_is_suppressed(file, line)) return;
293
va_list detail_args;
294
va_start(detail_args, detail_fmt);
295
void* context = NULL;
296
#ifdef CAN_SHOW_REGISTERS_ON_ASSERT
297
if (g_assertion_context != NULL && os::current_thread_id() == g_asserting_thread) {
298
context = g_assertion_context;
299
}
300
#endif // CAN_SHOW_REGISTERS_ON_ASSERT
301
302
print_error_for_unit_test("fatal error", detail_fmt, detail_args);
303
304
VMError::report_and_die(error_type, "fatal error", detail_fmt, detail_args,
305
Thread::current_or_null(), NULL, NULL, context,
306
file, line, 0);
307
va_end(detail_args);
308
}
309
310
void report_vm_out_of_memory(const char* file, int line, size_t size,
311
VMErrorType vm_err_type, const char* detail_fmt, ...) {
312
if (Debugging) return;
313
va_list detail_args;
314
va_start(detail_args, detail_fmt);
315
316
print_error_for_unit_test(NULL, detail_fmt, detail_args);
317
318
VMError::report_and_die(Thread::current_or_null(), file, line, size, vm_err_type, detail_fmt, detail_args);
319
va_end(detail_args);
320
321
// The UseOSErrorReporting option in report_and_die() may allow a return
322
// to here. If so then we'll have to figure out how to handle it.
323
guarantee(false, "report_and_die() should not return here");
324
}
325
326
void report_should_not_call(const char* file, int line) {
327
report_vm_error(file, line, "ShouldNotCall()");
328
}
329
330
void report_should_not_reach_here(const char* file, int line) {
331
report_vm_error(file, line, "ShouldNotReachHere()");
332
}
333
334
void report_unimplemented(const char* file, int line) {
335
report_vm_error(file, line, "Unimplemented()");
336
}
337
338
void report_untested(const char* file, int line, const char* message) {
339
#ifndef PRODUCT
340
warning("Untested: %s in %s: %d\n", message, file, line);
341
#endif // !PRODUCT
342
}
343
344
void report_java_out_of_memory(const char* message) {
345
static int out_of_memory_reported = 0;
346
347
// A number of threads may attempt to report OutOfMemoryError at around the
348
// same time. To avoid dumping the heap or executing the data collection
349
// commands multiple times we just do it once when the first threads reports
350
// the error.
351
if (Atomic::cmpxchg(&out_of_memory_reported, 0, 1) == 0) {
352
// create heap dump before OnOutOfMemoryError commands are executed
353
if (HeapDumpOnOutOfMemoryError) {
354
tty->print_cr("java.lang.OutOfMemoryError: %s", message);
355
HeapDumper::dump_heap_from_oome();
356
}
357
358
if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
359
VMError::report_java_out_of_memory(message);
360
}
361
362
if (CrashOnOutOfMemoryError) {
363
tty->print_cr("Aborting due to java.lang.OutOfMemoryError: %s", message);
364
report_fatal(OOM_JAVA_HEAP_FATAL, __FILE__, __LINE__, "OutOfMemory encountered: %s", message);
365
}
366
367
if (ExitOnOutOfMemoryError) {
368
tty->print_cr("Terminating due to java.lang.OutOfMemoryError: %s", message);
369
os::exit(3);
370
}
371
}
372
}
373
374
// ------ helper functions for debugging go here ------------
375
376
// All debug entries should be wrapped with a stack allocated
377
// Command object. It makes sure a resource mark is set and
378
// flushes the logfile to prevent file sharing problems.
379
380
class Command : public StackObj {
381
private:
382
ResourceMark rm;
383
bool debug_save;
384
public:
385
static int level;
386
Command(const char* str) {
387
debug_save = Debugging;
388
Debugging = true;
389
if (level++ > 0) return;
390
tty->cr();
391
tty->print_cr("\"Executing %s\"", str);
392
}
393
394
~Command() {
395
tty->flush();
396
Debugging = debug_save;
397
level--;
398
}
399
};
400
401
int Command::level = 0;
402
403
extern "C" JNIEXPORT void blob(CodeBlob* cb) {
404
Command c("blob");
405
cb->print();
406
}
407
408
409
extern "C" JNIEXPORT void dump_vtable(address p) {
410
Command c("dump_vtable");
411
Klass* k = (Klass*)p;
412
k->vtable().print();
413
}
414
415
416
extern "C" JNIEXPORT void nm(intptr_t p) {
417
// Actually we look through all CodeBlobs (the nm name has been kept for backwards compatability)
418
Command c("nm");
419
CodeBlob* cb = CodeCache::find_blob((address)p);
420
if (cb == NULL) {
421
tty->print_cr("NULL");
422
} else {
423
cb->print();
424
}
425
}
426
427
428
extern "C" JNIEXPORT void disnm(intptr_t p) {
429
Command c("disnm");
430
CodeBlob* cb = CodeCache::find_blob((address) p);
431
if (cb != NULL) {
432
nmethod* nm = cb->as_nmethod_or_null();
433
if (nm != NULL) {
434
nm->print();
435
} else {
436
cb->print();
437
}
438
Disassembler::decode(cb);
439
}
440
}
441
442
443
extern "C" JNIEXPORT void printnm(intptr_t p) {
444
char buffer[256];
445
sprintf(buffer, "printnm: " INTPTR_FORMAT, p);
446
Command c(buffer);
447
CodeBlob* cb = CodeCache::find_blob((address) p);
448
if (cb->is_nmethod()) {
449
nmethod* nm = (nmethod*)cb;
450
nm->print_nmethod(true);
451
}
452
}
453
454
455
extern "C" JNIEXPORT void universe() {
456
Command c("universe");
457
Universe::print_on(tty);
458
}
459
460
461
extern "C" JNIEXPORT void verify() {
462
// try to run a verify on the entire system
463
// note: this may not be safe if we're not at a safepoint; for debugging,
464
// this manipulates the safepoint settings to avoid assertion failures
465
Command c("universe verify");
466
bool safe = SafepointSynchronize::is_at_safepoint();
467
if (!safe) {
468
tty->print_cr("warning: not at safepoint -- verify may fail");
469
SafepointSynchronize::set_is_at_safepoint();
470
}
471
// Ensure Eden top is correct before verification
472
Universe::heap()->prepare_for_verify();
473
Universe::verify();
474
if (!safe) SafepointSynchronize::set_is_not_at_safepoint();
475
}
476
477
478
extern "C" JNIEXPORT void pp(void* p) {
479
Command c("pp");
480
FlagSetting fl(DisplayVMOutput, true);
481
if (Universe::heap()->is_in(p)) {
482
oop obj = cast_to_oop(p);
483
obj->print();
484
} else {
485
tty->print(PTR_FORMAT, p2i(p));
486
}
487
}
488
489
490
extern "C" JNIEXPORT void findpc(intptr_t x);
491
492
extern "C" JNIEXPORT void ps() { // print stack
493
if (Thread::current_or_null() == NULL) return;
494
Command c("ps");
495
496
// Prints the stack of the current Java thread
497
JavaThread* p = JavaThread::active();
498
tty->print(" for thread: ");
499
p->print();
500
tty->cr();
501
502
if (p->has_last_Java_frame()) {
503
// If the last_Java_fp is set we are in C land and
504
// can call the standard stack_trace function.
505
p->print_stack();
506
#ifndef PRODUCT
507
if (Verbose) p->trace_stack();
508
} else {
509
frame f = os::current_frame();
510
RegisterMap reg_map(p);
511
f = f.sender(&reg_map);
512
tty->print("(guessing starting frame id=" PTR_FORMAT " based on current fp)\n", p2i(f.id()));
513
p->trace_stack_from(vframe::new_vframe(&f, &reg_map, p));
514
f.pd_ps();
515
#endif
516
}
517
}
518
519
extern "C" JNIEXPORT void pfl() {
520
// print frame layout
521
Command c("pfl");
522
JavaThread* p = JavaThread::active();
523
tty->print(" for thread: ");
524
p->print();
525
tty->cr();
526
if (p->has_last_Java_frame()) {
527
p->print_frame_layout();
528
}
529
}
530
531
extern "C" JNIEXPORT void psf() { // print stack frames
532
{
533
Command c("psf");
534
JavaThread* p = JavaThread::active();
535
tty->print(" for thread: ");
536
p->print();
537
tty->cr();
538
if (p->has_last_Java_frame()) {
539
p->trace_frames();
540
}
541
}
542
}
543
544
545
extern "C" JNIEXPORT void threads() {
546
Command c("threads");
547
Threads::print(false, true);
548
}
549
550
551
extern "C" JNIEXPORT void psd() {
552
Command c("psd");
553
SystemDictionary::print();
554
}
555
556
557
extern "C" JNIEXPORT void pss() { // print all stacks
558
if (Thread::current_or_null() == NULL) return;
559
Command c("pss");
560
Threads::print(true, PRODUCT_ONLY(false) NOT_PRODUCT(true));
561
}
562
563
// #ifndef PRODUCT
564
565
extern "C" JNIEXPORT void debug() { // to set things up for compiler debugging
566
Command c("debug");
567
NOT_PRODUCT(WizardMode = true;)
568
PrintCompilation = true;
569
PrintInlining = PrintAssembly = true;
570
tty->flush();
571
}
572
573
574
extern "C" JNIEXPORT void ndebug() { // undo debug()
575
Command c("ndebug");
576
PrintCompilation = false;
577
PrintInlining = PrintAssembly = false;
578
tty->flush();
579
}
580
581
582
extern "C" JNIEXPORT void flush() {
583
Command c("flush");
584
tty->flush();
585
}
586
587
extern "C" JNIEXPORT void events() {
588
Command c("events");
589
Events::print();
590
}
591
592
extern "C" JNIEXPORT Method* findm(intptr_t pc) {
593
Command c("findm");
594
nmethod* nm = CodeCache::find_nmethod((address)pc);
595
return (nm == NULL) ? (Method*)NULL : nm->method();
596
}
597
598
599
extern "C" JNIEXPORT nmethod* findnm(intptr_t addr) {
600
Command c("findnm");
601
return CodeCache::find_nmethod((address)addr);
602
}
603
604
extern "C" JNIEXPORT void find(intptr_t x) {
605
Command c("find");
606
os::print_location(tty, x, false);
607
}
608
609
610
extern "C" JNIEXPORT void findpc(intptr_t x) {
611
Command c("findpc");
612
os::print_location(tty, x, true);
613
}
614
615
616
// Need method pointer to find bcp, when not in permgen.
617
extern "C" JNIEXPORT void findbcp(intptr_t method, intptr_t bcp) {
618
Command c("findbcp");
619
Method* mh = (Method*)method;
620
if (!mh->is_native()) {
621
tty->print_cr("bci_from(%p) = %d; print_codes():",
622
mh, mh->bci_from(address(bcp)));
623
mh->print_codes_on(tty);
624
}
625
}
626
627
// int versions of all methods to avoid having to type type casts in the debugger
628
629
void pp(intptr_t p) { pp((void*)p); }
630
void pp(oop p) { pp((void*)p); }
631
632
void help() {
633
Command c("help");
634
tty->print_cr("basic");
635
tty->print_cr(" pp(void* p) - try to make sense of p");
636
tty->print_cr(" ps() - print current thread stack");
637
tty->print_cr(" pss() - print all thread stacks");
638
tty->print_cr(" pm(int pc) - print Method* given compiled PC");
639
tty->print_cr(" findm(intptr_t pc) - finds Method*");
640
tty->print_cr(" find(intptr_t x) - finds & prints nmethod/stub/bytecode/oop based on pointer into it");
641
tty->print_cr(" pns(void* sp, void* fp, void* pc) - print native (i.e. mixed) stack trace. E.g.");
642
tty->print_cr(" pns($sp, $rbp, $pc) on Linux/amd64 or");
643
tty->print_cr(" pns($sp, $ebp, $pc) on Linux/x86 or");
644
tty->print_cr(" pns($sp, $fp, $pc) on Linux/AArch64 or");
645
tty->print_cr(" pns($sp, 0, $pc) on Linux/ppc64 or");
646
tty->print_cr(" pns($sp, $s8, $pc) on Linux/mips or");
647
tty->print_cr(" - in gdb do 'set overload-resolution off' before calling pns()");
648
tty->print_cr(" - in dbx do 'frame 1' before calling pns()");
649
650
tty->print_cr("misc.");
651
tty->print_cr(" flush() - flushes the log file");
652
tty->print_cr(" events() - dump events from ring buffers");
653
654
655
tty->print_cr("compiler debugging");
656
tty->print_cr(" debug() - to set things up for compiler debugging");
657
tty->print_cr(" ndebug() - undo debug");
658
}
659
660
#ifndef PRODUCT
661
extern "C" JNIEXPORT void pns(void* sp, void* fp, void* pc) { // print native stack
662
Command c("pns");
663
static char buf[O_BUFLEN];
664
Thread* t = Thread::current_or_null();
665
// Call generic frame constructor (certain arguments may be ignored)
666
frame fr(sp, fp, pc);
667
VMError::print_native_stack(tty, fr, t, buf, sizeof(buf));
668
}
669
670
//
671
// This version of pns() will not work when called from the debugger, but is
672
// useful when called from within hotspot code. The advantages over pns()
673
// are not having to pass in any arguments, and it will work on Windows/x64.
674
//
675
// WARNING: Only intended for use when debugging. Do not leave calls to
676
// pns2() in committed source (product or debug).
677
//
678
extern "C" JNIEXPORT void pns2() { // print native stack
679
Command c("pns2");
680
static char buf[O_BUFLEN];
681
if (os::platform_print_native_stack(tty, NULL, buf, sizeof(buf))) {
682
// We have printed the native stack in platform-specific code,
683
// so nothing else to do in this case.
684
} else {
685
Thread* t = Thread::current_or_null();
686
frame fr = os::current_frame();
687
VMError::print_native_stack(tty, fr, t, buf, sizeof(buf));
688
}
689
}
690
#endif
691
692
693
//////////////////////////////////////////////////////////////////////////////
694
// Test multiple STATIC_ASSERT forms in various scopes.
695
696
#ifndef PRODUCT
697
698
// namespace scope
699
STATIC_ASSERT(true);
700
STATIC_ASSERT(true);
701
STATIC_ASSERT(1 == 1);
702
STATIC_ASSERT(0 == 0);
703
704
void test_multiple_static_assert_forms_in_function_scope() {
705
STATIC_ASSERT(true);
706
STATIC_ASSERT(true);
707
STATIC_ASSERT(0 == 0);
708
STATIC_ASSERT(1 == 1);
709
}
710
711
// class scope
712
struct TestMultipleStaticAssertFormsInClassScope {
713
STATIC_ASSERT(true);
714
STATIC_ASSERT(true);
715
STATIC_ASSERT(0 == 0);
716
STATIC_ASSERT(1 == 1);
717
};
718
719
#endif // !PRODUCT
720
721
// Support for showing register content on asserts/guarantees.
722
#ifdef CAN_SHOW_REGISTERS_ON_ASSERT
723
724
static ucontext_t g_stored_assertion_context;
725
726
void initialize_assert_poison() {
727
char* page = os::reserve_memory(os::vm_page_size());
728
if (page) {
729
MemTracker::record_virtual_memory_type(page, mtInternal);
730
if (os::commit_memory(page, os::vm_page_size(), false) &&
731
os::protect_memory(page, os::vm_page_size(), os::MEM_PROT_NONE)) {
732
g_assert_poison = page;
733
}
734
}
735
}
736
737
void disarm_assert_poison() {
738
g_assert_poison = &g_dummy;
739
}
740
741
static void store_context(const void* context) {
742
memcpy(&g_stored_assertion_context, context, sizeof(ucontext_t));
743
#if defined(LINUX) && defined(PPC64)
744
// on Linux ppc64, ucontext_t contains pointers into itself which have to be patched up
745
// after copying the context (see comment in sys/ucontext.h):
746
*((void**) &g_stored_assertion_context.uc_mcontext.regs) = &(g_stored_assertion_context.uc_mcontext.gp_regs);
747
#endif
748
}
749
750
bool handle_assert_poison_fault(const void* ucVoid, const void* faulting_address) {
751
if (faulting_address == g_assert_poison) {
752
// Disarm poison page.
753
if (os::protect_memory((char*)g_assert_poison, os::vm_page_size(), os::MEM_PROT_RWX) == false) {
754
#ifdef ASSERT
755
fprintf(stderr, "Assertion poison page cannot be unprotected - mprotect failed with %d (%s)",
756
errno, os::strerror(errno));
757
fflush(stderr);
758
#endif
759
return false; // unprotecting memory may fail in OOM situations, as surprising as this sounds.
760
}
761
// Store Context away.
762
if (ucVoid) {
763
const intx my_tid = os::current_thread_id();
764
if (Atomic::cmpxchg(&g_asserting_thread, (intx)0, my_tid) == 0) {
765
store_context(ucVoid);
766
g_assertion_context = &g_stored_assertion_context;
767
}
768
}
769
return true;
770
}
771
return false;
772
}
773
#endif // CAN_SHOW_REGISTERS_ON_ASSERT
774
775