Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-aarch32-jdk8u
Path: blob/jdk8u272-b10-aarch32-20201026/hotspot/src/share/vm/utilities/debug.cpp
83404 views
1
/*
2
* Copyright (c) 1997, 2017, 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 "classfile/systemDictionary.hpp"
27
#include "code/codeCache.hpp"
28
#include "code/icBuffer.hpp"
29
#include "code/nmethod.hpp"
30
#include "code/vtableStubs.hpp"
31
#include "compiler/compileBroker.hpp"
32
#include "compiler/disassembler.hpp"
33
#include "gc_implementation/shared/markSweep.hpp"
34
#include "gc_interface/collectedHeap.hpp"
35
#include "interpreter/bytecodeHistogram.hpp"
36
#include "interpreter/interpreter.hpp"
37
#include "memory/resourceArea.hpp"
38
#include "memory/universe.hpp"
39
#include "oops/oop.inline.hpp"
40
#include "prims/privilegedStack.hpp"
41
#include "runtime/arguments.hpp"
42
#include "runtime/frame.hpp"
43
#include "runtime/java.hpp"
44
#include "runtime/sharedRuntime.hpp"
45
#include "runtime/stubCodeGenerator.hpp"
46
#include "runtime/stubRoutines.hpp"
47
#include "runtime/thread.inline.hpp"
48
#include "runtime/vframe.hpp"
49
#include "services/heapDumper.hpp"
50
#include "utilities/defaultStream.hpp"
51
#include "utilities/events.hpp"
52
#include "utilities/top.hpp"
53
#include "utilities/vmError.hpp"
54
#ifdef TARGET_OS_FAMILY_linux
55
# include "os_linux.inline.hpp"
56
#endif
57
#ifdef TARGET_OS_FAMILY_solaris
58
# include "os_solaris.inline.hpp"
59
#endif
60
#ifdef TARGET_OS_FAMILY_windows
61
# include "os_windows.inline.hpp"
62
#endif
63
#ifdef TARGET_OS_FAMILY_bsd
64
# include "os_bsd.inline.hpp"
65
#endif
66
67
#ifndef ASSERT
68
# ifdef _DEBUG
69
// NOTE: don't turn the lines below into a comment -- if you're getting
70
// a compile error here, change the settings to define ASSERT
71
ASSERT should be defined when _DEBUG is defined. It is not intended to be used for debugging
72
functions that do not slow down the system too much and thus can be left in optimized code.
73
On the other hand, the code should not be included in a production version.
74
# endif // _DEBUG
75
#endif // ASSERT
76
77
78
#ifdef _DEBUG
79
# ifndef ASSERT
80
configuration error: ASSERT must be defined in debug version
81
# endif // ASSERT
82
#endif // _DEBUG
83
84
85
#ifdef PRODUCT
86
# if -defined _DEBUG || -defined ASSERT
87
configuration error: ASSERT et al. must not be defined in PRODUCT version
88
# endif
89
#endif // PRODUCT
90
91
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
92
93
FormatBufferResource::FormatBufferResource(const char * format, ...)
94
: FormatBufferBase((char*)resource_allocate_bytes(RES_BUFSZ)) {
95
va_list argp;
96
va_start(argp, format);
97
jio_vsnprintf(_buf, RES_BUFSZ, format, argp);
98
va_end(argp);
99
}
100
101
ATTRIBUTE_PRINTF(1, 2)
102
void warning(const char* format, ...) {
103
if (PrintWarnings) {
104
FILE* const err = defaultStream::error_stream();
105
jio_fprintf(err, "%s warning: ", VM_Version::vm_name());
106
va_list ap;
107
va_start(ap, format);
108
vfprintf(err, format, ap);
109
va_end(ap);
110
fputc('\n', err);
111
}
112
if (BreakAtWarning) BREAKPOINT;
113
}
114
115
#ifndef PRODUCT
116
117
#define is_token_break(ch) (isspace(ch) || (ch) == ',')
118
119
static const char* last_file_name = NULL;
120
static int last_line_no = -1;
121
122
// assert/guarantee/... may happen very early during VM initialization.
123
// Don't rely on anything that is initialized by Threads::create_vm(). For
124
// example, don't use tty.
125
bool error_is_suppressed(const char* file_name, int line_no) {
126
// The following 1-element cache requires that passed-in
127
// file names are always only constant literals.
128
if (file_name == last_file_name && line_no == last_line_no) return true;
129
130
int file_name_len = (int)strlen(file_name);
131
char separator = os::file_separator()[0];
132
const char* base_name = strrchr(file_name, separator);
133
if (base_name == NULL)
134
base_name = file_name;
135
136
// scan the SuppressErrorAt option
137
const char* cp = SuppressErrorAt;
138
for (;;) {
139
const char* sfile;
140
int sfile_len;
141
int sline;
142
bool noisy;
143
while ((*cp) != '\0' && is_token_break(*cp)) cp++;
144
if ((*cp) == '\0') break;
145
sfile = cp;
146
while ((*cp) != '\0' && !is_token_break(*cp) && (*cp) != ':') cp++;
147
sfile_len = cp - sfile;
148
if ((*cp) == ':') cp++;
149
sline = 0;
150
while ((*cp) != '\0' && isdigit(*cp)) {
151
sline *= 10;
152
sline += (*cp) - '0';
153
cp++;
154
}
155
// "file:line!" means the assert suppression is not silent
156
noisy = ((*cp) == '!');
157
while ((*cp) != '\0' && !is_token_break(*cp)) cp++;
158
// match the line
159
if (sline != 0) {
160
if (sline != line_no) continue;
161
}
162
// match the file
163
if (sfile_len > 0) {
164
const char* look = file_name;
165
const char* look_max = file_name + file_name_len - sfile_len;
166
const char* foundp;
167
bool match = false;
168
while (!match
169
&& (foundp = strchr(look, sfile[0])) != NULL
170
&& foundp <= look_max) {
171
match = true;
172
for (int i = 1; i < sfile_len; i++) {
173
if (sfile[i] != foundp[i]) {
174
match = false;
175
break;
176
}
177
}
178
look = foundp + 1;
179
}
180
if (!match) continue;
181
}
182
// got a match!
183
if (noisy) {
184
fdStream out(defaultStream::output_fd());
185
out.print_raw("[error suppressed at ");
186
out.print_raw(base_name);
187
char buf[16];
188
jio_snprintf(buf, sizeof(buf), ":%d]", line_no);
189
out.print_raw_cr(buf);
190
} else {
191
// update 1-element cache for fast silent matches
192
last_file_name = file_name;
193
last_line_no = line_no;
194
}
195
return true;
196
}
197
198
if (!is_error_reported()) {
199
// print a friendly hint:
200
fdStream out(defaultStream::output_fd());
201
out.print_raw_cr("# To suppress the following error report, specify this argument");
202
out.print_raw ("# after -XX: or in .hotspotrc: SuppressErrorAt=");
203
out.print_raw (base_name);
204
char buf[16];
205
jio_snprintf(buf, sizeof(buf), ":%d", line_no);
206
out.print_raw_cr(buf);
207
}
208
return false;
209
}
210
211
#undef is_token_break
212
213
#else
214
215
// Place-holder for non-existent suppression check:
216
#define error_is_suppressed(file_name, line_no) (false)
217
218
#endif // !PRODUCT
219
220
void report_vm_error(const char* file, int line, const char* error_msg,
221
const char* detail_msg)
222
{
223
if (Debugging || error_is_suppressed(file, line)) return;
224
Thread* const thread = ThreadLocalStorage::get_thread_slow();
225
VMError err(thread, file, line, error_msg, detail_msg);
226
err.report_and_die();
227
}
228
229
void report_fatal(const char* file, int line, const char* message)
230
{
231
report_vm_error(file, line, "fatal error", message);
232
}
233
234
void report_vm_out_of_memory(const char* file, int line, size_t size,
235
VMErrorType vm_err_type, const char* message) {
236
if (Debugging) return;
237
238
Thread* thread = ThreadLocalStorage::get_thread_slow();
239
VMError(thread, file, line, size, vm_err_type, message).report_and_die();
240
241
// The UseOSErrorReporting option in report_and_die() may allow a return
242
// to here. If so then we'll have to figure out how to handle it.
243
guarantee(false, "report_and_die() should not return here");
244
}
245
246
void report_should_not_call(const char* file, int line) {
247
report_vm_error(file, line, "ShouldNotCall()");
248
}
249
250
void report_should_not_reach_here(const char* file, int line) {
251
report_vm_error(file, line, "ShouldNotReachHere()");
252
}
253
254
void report_unimplemented(const char* file, int line) {
255
report_vm_error(file, line, "Unimplemented()");
256
}
257
258
void report_untested(const char* file, int line, const char* message) {
259
#ifndef PRODUCT
260
warning("Untested: %s in %s: %d\n", message, file, line);
261
#endif // !PRODUCT
262
}
263
264
void report_out_of_shared_space(SharedSpaceType shared_space) {
265
static const char* name[] = {
266
"native memory for metadata",
267
"shared read only space",
268
"shared read write space",
269
"shared miscellaneous data space",
270
"shared miscellaneous code space"
271
};
272
static const char* flag[] = {
273
"Metaspace",
274
"SharedReadOnlySize",
275
"SharedReadWriteSize",
276
"SharedMiscDataSize",
277
"SharedMiscCodeSize"
278
};
279
280
warning("\nThe %s is not large enough\n"
281
"to preload requested classes. Use -XX:%s=<size>\n"
282
"to increase the initial size of %s.\n",
283
name[shared_space], flag[shared_space], name[shared_space]);
284
exit(2);
285
}
286
287
void report_java_out_of_memory(const char* message) {
288
static jint out_of_memory_reported = 0;
289
290
// A number of threads may attempt to report OutOfMemoryError at around the
291
// same time. To avoid dumping the heap or executing the data collection
292
// commands multiple times we just do it once when the first threads reports
293
// the error.
294
if (Atomic::cmpxchg(1, &out_of_memory_reported, 0) == 0) {
295
// create heap dump before OnOutOfMemoryError commands are executed
296
if (HeapDumpOnOutOfMemoryError) {
297
tty->print_cr("java.lang.OutOfMemoryError: %s", message);
298
HeapDumper::dump_heap_from_oome();
299
}
300
301
if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
302
VMError err(message);
303
err.report_java_out_of_memory();
304
}
305
306
if (CrashOnOutOfMemoryError) {
307
tty->print_cr("Aborting due to java.lang.OutOfMemoryError: %s", message);
308
fatal(err_msg("OutOfMemory encountered: %s", message));
309
}
310
311
if (ExitOnOutOfMemoryError) {
312
tty->print_cr("Terminating due to java.lang.OutOfMemoryError: %s", message);
313
exit(3);
314
}
315
}
316
}
317
318
void report_insufficient_metaspace(size_t required_size) {
319
warning("\nThe MaxMetaspaceSize of " SIZE_FORMAT " bytes is not large enough.\n"
320
"Either don't specify the -XX:MaxMetaspaceSize=<size>\n"
321
"or increase the size to at least " SIZE_FORMAT ".\n",
322
MaxMetaspaceSize, required_size);
323
exit(2);
324
}
325
326
static bool error_reported = false;
327
328
// call this when the VM is dying--it might loosen some asserts
329
void set_error_reported() {
330
error_reported = true;
331
}
332
333
bool is_error_reported() {
334
return error_reported;
335
}
336
337
#ifndef PRODUCT
338
#include <signal.h>
339
340
void test_error_handler() {
341
uintx test_num = ErrorHandlerTest;
342
if (test_num == 0) return;
343
344
// If asserts are disabled, use the corresponding guarantee instead.
345
size_t n = test_num;
346
NOT_DEBUG(if (n <= 2) n += 2);
347
348
const char* const str = "hello";
349
const size_t num = (size_t)os::vm_page_size();
350
351
const char* const eol = os::line_separator();
352
const char* const msg = "this message should be truncated during formatting";
353
char * const dataPtr = NULL; // bad data pointer
354
const void (*funcPtr)(void) = (const void(*)()) 0xF; // bad function pointer
355
356
// Keep this in sync with test/runtime/6888954/vmerrors.sh.
357
switch (n) {
358
case 1: assert(str == NULL, "expected null");
359
case 2: assert(num == 1023 && *str == 'X',
360
err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
361
case 3: guarantee(str == NULL, "expected null");
362
case 4: guarantee(num == 1023 && *str == 'X',
363
err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
364
case 5: fatal("expected null");
365
case 6: fatal(err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
366
case 7: fatal(err_msg("%s%s# %s%s# %s%s# %s%s# %s%s# "
367
"%s%s# %s%s# %s%s# %s%s# %s%s# "
368
"%s%s# %s%s# %s%s# %s%s# %s",
369
msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
370
msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
371
msg, eol, msg, eol, msg, eol, msg, eol, msg));
372
case 8: vm_exit_out_of_memory(num, OOM_MALLOC_ERROR, "ChunkPool::allocate");
373
case 9: ShouldNotCallThis();
374
case 10: ShouldNotReachHere();
375
case 11: Unimplemented();
376
// There's no guarantee the bad data pointer will crash us
377
// so "break" out to the ShouldNotReachHere().
378
case 12: *dataPtr = '\0'; break;
379
// There's no guarantee the bad function pointer will crash us
380
// so "break" out to the ShouldNotReachHere().
381
case 13: (*funcPtr)(); break;
382
383
default: tty->print_cr("ERROR: %d: unexpected test_num value.", n);
384
}
385
ShouldNotReachHere();
386
}
387
#endif // !PRODUCT
388
389
// ------ helper functions for debugging go here ------------
390
391
// All debug entries should be wrapped with a stack allocated
392
// Command object. It makes sure a resource mark is set and
393
// flushes the logfile to prevent file sharing problems.
394
395
class Command : public StackObj {
396
private:
397
ResourceMark rm;
398
ResetNoHandleMark rnhm;
399
HandleMark hm;
400
bool debug_save;
401
public:
402
static int level;
403
Command(const char* str) {
404
debug_save = Debugging;
405
Debugging = true;
406
if (level++ > 0) return;
407
tty->cr();
408
tty->print_cr("\"Executing %s\"", str);
409
}
410
411
~Command() {
412
tty->flush();
413
Debugging = debug_save;
414
level--;
415
}
416
};
417
418
int Command::level = 0;
419
420
#ifndef PRODUCT
421
422
extern "C" void blob(CodeBlob* cb) {
423
Command c("blob");
424
cb->print();
425
}
426
427
428
extern "C" void dump_vtable(address p) {
429
Command c("dump_vtable");
430
Klass* k = (Klass*)p;
431
InstanceKlass::cast(k)->vtable()->print();
432
}
433
434
435
extern "C" void nm(intptr_t p) {
436
// Actually we look through all CodeBlobs (the nm name has been kept for backwards compatability)
437
Command c("nm");
438
CodeBlob* cb = CodeCache::find_blob((address)p);
439
if (cb == NULL) {
440
tty->print_cr("NULL");
441
} else {
442
cb->print();
443
}
444
}
445
446
447
extern "C" void disnm(intptr_t p) {
448
Command c("disnm");
449
CodeBlob* cb = CodeCache::find_blob((address) p);
450
nmethod* nm = cb->as_nmethod_or_null();
451
if (nm) {
452
nm->print();
453
Disassembler::decode(nm);
454
} else {
455
cb->print();
456
Disassembler::decode(cb);
457
}
458
}
459
460
461
extern "C" void printnm(intptr_t p) {
462
char buffer[256];
463
sprintf(buffer, "printnm: " INTPTR_FORMAT, p);
464
Command c(buffer);
465
CodeBlob* cb = CodeCache::find_blob((address) p);
466
if (cb->is_nmethod()) {
467
nmethod* nm = (nmethod*)cb;
468
nm->print_nmethod(true);
469
}
470
}
471
472
473
extern "C" void universe() {
474
Command c("universe");
475
Universe::print();
476
}
477
478
479
extern "C" void verify() {
480
// try to run a verify on the entire system
481
// note: this may not be safe if we're not at a safepoint; for debugging,
482
// this manipulates the safepoint settings to avoid assertion failures
483
Command c("universe verify");
484
bool safe = SafepointSynchronize::is_at_safepoint();
485
if (!safe) {
486
tty->print_cr("warning: not at safepoint -- verify may fail");
487
SafepointSynchronize::set_is_at_safepoint();
488
}
489
// Ensure Eden top is correct before verification
490
Universe::heap()->prepare_for_verify();
491
Universe::verify();
492
if (!safe) SafepointSynchronize::set_is_not_at_safepoint();
493
}
494
495
496
extern "C" void pp(void* p) {
497
Command c("pp");
498
FlagSetting fl(PrintVMMessages, true);
499
FlagSetting f2(DisplayVMOutput, true);
500
if (Universe::heap()->is_in(p)) {
501
oop obj = oop(p);
502
obj->print();
503
} else {
504
tty->print(PTR_FORMAT, p);
505
}
506
}
507
508
509
// pv: print vm-printable object
510
extern "C" void pa(intptr_t p) { ((AllocatedObj*) p)->print(); }
511
extern "C" void findpc(intptr_t x);
512
513
#endif // !PRODUCT
514
515
extern "C" void ps() { // print stack
516
if (Thread::current() == NULL) return;
517
Command c("ps");
518
519
520
// Prints the stack of the current Java thread
521
JavaThread* p = JavaThread::active();
522
tty->print(" for thread: ");
523
p->print();
524
tty->cr();
525
526
if (p->has_last_Java_frame()) {
527
// If the last_Java_fp is set we are in C land and
528
// can call the standard stack_trace function.
529
#ifdef PRODUCT
530
p->print_stack();
531
} else {
532
tty->print_cr("Cannot find the last Java frame, printing stack disabled.");
533
#else // !PRODUCT
534
p->trace_stack();
535
} else {
536
frame f = os::current_frame();
537
RegisterMap reg_map(p);
538
f = f.sender(&reg_map);
539
tty->print("(guessing starting frame id=%#p based on current fp)\n", f.id());
540
p->trace_stack_from(vframe::new_vframe(&f, &reg_map, p));
541
pd_ps(f);
542
#endif // PRODUCT
543
}
544
545
}
546
547
extern "C" void pfl() {
548
// print frame layout
549
Command c("pfl");
550
JavaThread* p = JavaThread::active();
551
tty->print(" for thread: ");
552
p->print();
553
tty->cr();
554
if (p->has_last_Java_frame()) {
555
p->print_frame_layout();
556
}
557
}
558
559
#ifndef PRODUCT
560
561
extern "C" void psf() { // print stack frames
562
{
563
Command c("psf");
564
JavaThread* p = JavaThread::active();
565
tty->print(" for thread: ");
566
p->print();
567
tty->cr();
568
if (p->has_last_Java_frame()) {
569
p->trace_frames();
570
}
571
}
572
}
573
574
575
extern "C" void threads() {
576
Command c("threads");
577
Threads::print(false, true);
578
}
579
580
581
extern "C" void psd() {
582
Command c("psd");
583
SystemDictionary::print();
584
}
585
586
587
extern "C" void safepoints() {
588
Command c("safepoints");
589
SafepointSynchronize::print_state();
590
}
591
592
#endif // !PRODUCT
593
594
extern "C" void pss() { // print all stacks
595
if (Thread::current() == NULL) return;
596
Command c("pss");
597
Threads::print(true, PRODUCT_ONLY(false) NOT_PRODUCT(true));
598
}
599
600
#ifndef PRODUCT
601
602
extern "C" void debug() { // to set things up for compiler debugging
603
Command c("debug");
604
WizardMode = true;
605
PrintVMMessages = PrintCompilation = true;
606
PrintInlining = PrintAssembly = true;
607
tty->flush();
608
}
609
610
611
extern "C" void ndebug() { // undo debug()
612
Command c("ndebug");
613
PrintCompilation = false;
614
PrintInlining = PrintAssembly = false;
615
tty->flush();
616
}
617
618
619
extern "C" void flush() {
620
Command c("flush");
621
tty->flush();
622
}
623
624
extern "C" void events() {
625
Command c("events");
626
Events::print();
627
}
628
629
extern "C" Method* findm(intptr_t pc) {
630
Command c("findm");
631
nmethod* nm = CodeCache::find_nmethod((address)pc);
632
return (nm == NULL) ? (Method*)NULL : nm->method();
633
}
634
635
636
extern "C" nmethod* findnm(intptr_t addr) {
637
Command c("findnm");
638
return CodeCache::find_nmethod((address)addr);
639
}
640
641
// Another interface that isn't ambiguous in dbx.
642
// Can we someday rename the other find to hsfind?
643
extern "C" void hsfind(intptr_t x) {
644
Command c("hsfind");
645
os::print_location(tty, x, false);
646
}
647
648
649
extern "C" void find(intptr_t x) {
650
Command c("find");
651
os::print_location(tty, x, false);
652
}
653
654
655
extern "C" void findpc(intptr_t x) {
656
Command c("findpc");
657
os::print_location(tty, x, true);
658
}
659
660
661
// Need method pointer to find bcp, when not in permgen.
662
extern "C" void findbcp(intptr_t method, intptr_t bcp) {
663
Command c("findbcp");
664
Method* mh = (Method*)method;
665
if (!mh->is_native()) {
666
tty->print_cr("bci_from(%p) = %d; print_codes():",
667
mh, mh->bci_from(address(bcp)));
668
mh->print_codes_on(tty);
669
}
670
}
671
672
// int versions of all methods to avoid having to type type casts in the debugger
673
674
void pp(intptr_t p) { pp((void*)p); }
675
void pp(oop p) { pp((void*)p); }
676
677
void help() {
678
Command c("help");
679
tty->print_cr("basic");
680
tty->print_cr(" pp(void* p) - try to make sense of p");
681
tty->print_cr(" pv(intptr_t p)- ((PrintableResourceObj*) p)->print()");
682
tty->print_cr(" ps() - print current thread stack");
683
tty->print_cr(" pss() - print all thread stacks");
684
tty->print_cr(" pm(int pc) - print Method* given compiled PC");
685
tty->print_cr(" findm(intptr_t pc) - finds Method*");
686
tty->print_cr(" find(intptr_t x) - finds & prints nmethod/stub/bytecode/oop based on pointer into it");
687
tty->print_cr(" pns(void* sp, void* fp, void* pc) - print native (i.e. mixed) stack trace. E.g.");
688
tty->print_cr(" pns($sp, $rbp, $pc) on Linux/amd64 and Solaris/amd64 or");
689
tty->print_cr(" pns($sp, $ebp, $pc) on Linux/x86 or");
690
tty->print_cr(" pns($sp, 0, $pc) on Linux/ppc64 or");
691
tty->print_cr(" pns($sp + 0x7ff, 0, $pc) on Solaris/SPARC");
692
tty->print_cr(" - in gdb do 'set overload-resolution off' before calling pns()");
693
tty->print_cr(" - in dbx do 'frame 1' before calling pns()");
694
695
tty->print_cr("misc.");
696
tty->print_cr(" flush() - flushes the log file");
697
tty->print_cr(" events() - dump events from ring buffers");
698
699
700
tty->print_cr("compiler debugging");
701
tty->print_cr(" debug() - to set things up for compiler debugging");
702
tty->print_cr(" ndebug() - undo debug");
703
}
704
705
#endif // !PRODUCT
706
707
void print_native_stack(outputStream* st, frame fr, Thread* t, char* buf, int buf_size) {
708
709
// see if it's a valid frame
710
if (fr.pc()) {
711
st->print_cr("Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)");
712
713
int count = 0;
714
while (count++ < StackPrintLimit) {
715
fr.print_on_error(st, buf, buf_size);
716
st->cr();
717
// Compiled code may use EBP register on x86 so it looks like
718
// non-walkable C frame. Use frame.sender() for java frames.
719
if (t && t->is_Java_thread()) {
720
// Catch very first native frame by using stack address.
721
// For JavaThread stack_base and stack_size should be set.
722
if (!t->on_local_stack((address)(fr.real_fp() + 1))) {
723
break;
724
}
725
if (fr.is_java_frame() || fr.is_native_frame() || fr.is_runtime_frame()) {
726
RegisterMap map((JavaThread*)t, false); // No update
727
fr = fr.sender(&map);
728
} else {
729
fr = os::get_sender_for_C_frame(&fr);
730
}
731
} else {
732
// is_first_C_frame() does only simple checks for frame pointer,
733
// it will pass if java compiled code has a pointer in EBP.
734
if (os::is_first_C_frame(&fr)) break;
735
fr = os::get_sender_for_C_frame(&fr);
736
}
737
}
738
739
if (count > StackPrintLimit) {
740
st->print_cr("...<more frames>...");
741
}
742
743
st->cr();
744
}
745
}
746
747
#ifndef PRODUCT
748
749
extern "C" void pns(void* sp, void* fp, void* pc) { // print native stack
750
Command c("pns");
751
static char buf[O_BUFLEN];
752
Thread* t = ThreadLocalStorage::get_thread_slow();
753
// Call generic frame constructor (certain arguments may be ignored)
754
frame fr(sp, fp, pc);
755
print_native_stack(tty, fr, t, buf, sizeof(buf));
756
}
757
758
#endif // !PRODUCT
759
760