jdk

Форк
0
758 строк · 23.9 Кб
1
/*
2
 * Copyright (c) 1997, 2024, 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/classPrinter.hpp"
27
#include "classfile/systemDictionary.hpp"
28
#include "code/codeCache.hpp"
29
#include "code/nmethod.hpp"
30
#include "code/vtableStubs.hpp"
31
#include "compiler/compileBroker.hpp"
32
#include "compiler/disassembler.hpp"
33
#include "gc/shared/collectedHeap.hpp"
34
#include "interpreter/interpreter.hpp"
35
#include "jvm.h"
36
#include "memory/allocation.hpp"
37
#include "memory/resourceArea.hpp"
38
#include "memory/universe.hpp"
39
#include "nmt/mallocTracker.hpp"
40
#include "nmt/memTracker.hpp"
41
#include "nmt/virtualMemoryTracker.hpp"
42
#include "oops/klass.inline.hpp"
43
#include "oops/oop.inline.hpp"
44
#include "runtime/atomic.hpp"
45
#include "runtime/flags/flagSetting.hpp"
46
#include "runtime/frame.inline.hpp"
47
#include "runtime/handles.inline.hpp"
48
#include "runtime/java.hpp"
49
#include "runtime/javaThread.hpp"
50
#include "runtime/os.inline.hpp"
51
#include "runtime/safefetch.hpp"
52
#include "runtime/sharedRuntime.hpp"
53
#include "runtime/stubCodeGenerator.hpp"
54
#include "runtime/stubRoutines.hpp"
55
#include "runtime/threads.hpp"
56
#include "runtime/vframe.hpp"
57
#include "runtime/vm_version.hpp"
58
#include "services/heapDumper.hpp"
59
#include "utilities/defaultStream.hpp"
60
#include "utilities/events.hpp"
61
#include "utilities/formatBuffer.hpp"
62
#include "utilities/globalDefinitions.hpp"
63
#include "utilities/macros.hpp"
64
#include "utilities/unsigned5.hpp"
65
#include "utilities/vmError.hpp"
66

67
#include <stdio.h>
68
#include <stdarg.h>
69

70
// These functions needs to be exported on Windows only
71
#define DEBUGEXPORT WINDOWS_ONLY(JNIEXPORT)
72

73
// Support for showing register content on asserts/guarantees.
74
#ifdef CAN_SHOW_REGISTERS_ON_ASSERT
75
static char g_dummy;
76
char* g_assert_poison = &g_dummy;
77
static intx g_asserting_thread = 0;
78
static void* g_assertion_context = nullptr;
79
#endif // CAN_SHOW_REGISTERS_ON_ASSERT
80

81
int DebuggingContext::_enabled = 0; // Initially disabled.
82

83
DebuggingContext::DebuggingContext() {
84
  _enabled += 1;                // Increase nesting count.
85
}
86

87
DebuggingContext::~DebuggingContext() {
88
  if (is_enabled()) {
89
    _enabled -= 1;              // Decrease nesting count.
90
  } else {
91
    fatal("Debugging nesting confusion");
92
  }
93
}
94

95
#ifndef ASSERT
96
#  ifdef _DEBUG
97
   // NOTE: don't turn the lines below into a comment -- if you're getting
98
   // a compile error here, change the settings to define ASSERT
99
   ASSERT should be defined when _DEBUG is defined.  It is not intended to be used for debugging
100
   functions that do not slow down the system too much and thus can be left in optimized code.
101
   On the other hand, the code should not be included in a production version.
102
#  endif // _DEBUG
103
#endif // ASSERT
104

105

106
#ifdef _DEBUG
107
#  ifndef ASSERT
108
     configuration error: ASSERT must be defined in debug version
109
#  endif // ASSERT
110
#endif // _DEBUG
111

112

113
#ifdef PRODUCT
114
#  if -defined _DEBUG || -defined ASSERT
115
     configuration error: ASSERT et al. must not be defined in PRODUCT version
116
#  endif
117
#endif // PRODUCT
118

119
#ifdef ASSERT
120
// This is to test that error reporting works if we assert during dynamic
121
// initialization of the hotspot. See JDK-8214975.
122
struct Crasher {
123
  Crasher() {
124
    // Using getenv - no other mechanism would work yet.
125
    const char* s = ::getenv("HOTSPOT_FATAL_ERROR_DURING_DYNAMIC_INITIALIZATION");
126
    if (s != nullptr && ::strcmp(s, "1") == 0) {
127
      fatal("HOTSPOT_FATAL_ERROR_DURING_DYNAMIC_INITIALIZATION");
128
    }
129
  }
130
};
131
static Crasher g_crasher;
132
#endif // ASSERT
133

134
ATTRIBUTE_PRINTF(1, 2)
135
void warning(const char* format, ...) {
136
  if (PrintWarnings) {
137
    FILE* const err = defaultStream::error_stream();
138
    jio_fprintf(err, "%s warning: ", VM_Version::vm_name());
139
    va_list ap;
140
    va_start(ap, format);
141
    vfprintf(err, format, ap);
142
    va_end(ap);
143
    fputc('\n', err);
144
  }
145
}
146

147
void report_vm_error(const char* file, int line, const char* error_msg)
148
{
149
  report_vm_error(file, line, error_msg, "%s", "");
150
}
151

152

153
static void print_error_for_unit_test(const char* message, const char* detail_fmt, va_list detail_args) {
154
  if (ExecutingUnitTests) {
155
    char detail_msg[256];
156
    if (detail_fmt != nullptr) {
157
      // Special handling for the sake of gtest death tests which expect the assert
158
      // message to be printed in one short line to stderr (see TEST_VM_ASSERT_MSG) and
159
      // cannot be tweaked to accept our normal assert message.
160
      va_list detail_args_copy;
161
      va_copy(detail_args_copy, detail_args);
162
      jio_vsnprintf(detail_msg, sizeof(detail_msg), detail_fmt, detail_args_copy);
163

164
      // the VM assert tests look for "assert failed: "
165
      if (message == nullptr) {
166
        fprintf(stderr, "assert failed: %s", detail_msg);
167
      } else {
168
        if (strlen(detail_msg) > 0) {
169
          fprintf(stderr, "assert failed: %s: %s", message, detail_msg);
170
        } else {
171
          fprintf(stderr, "assert failed: Error: %s", message);
172
        }
173
      }
174
      ::fflush(stderr);
175
      va_end(detail_args_copy);
176
    }
177
  }
178
}
179

180
void report_vm_error(const char* file, int line, const char* error_msg, const char* detail_fmt, ...)
181
{
182
  va_list detail_args;
183
  va_start(detail_args, detail_fmt);
184
  void* context = nullptr;
185
#ifdef CAN_SHOW_REGISTERS_ON_ASSERT
186
  if (g_assertion_context != nullptr && os::current_thread_id() == g_asserting_thread) {
187
    context = g_assertion_context;
188
  }
189
#endif // CAN_SHOW_REGISTERS_ON_ASSERT
190

191
  print_error_for_unit_test(error_msg, detail_fmt, detail_args);
192

193
  VMError::report_and_die(Thread::current_or_null(), context, file, line, error_msg, detail_fmt, detail_args);
194
  va_end(detail_args);
195
}
196

197
void report_vm_status_error(const char* file, int line, const char* error_msg,
198
                            int status, const char* detail) {
199
  report_vm_error(file, line, error_msg, "error %s(%d), %s", os::errno_name(status), status, detail);
200
}
201

202
void report_fatal(VMErrorType error_type, const char* file, int line, const char* detail_fmt, ...) {
203
  va_list detail_args;
204
  va_start(detail_args, detail_fmt);
205
  void* context = nullptr;
206
#ifdef CAN_SHOW_REGISTERS_ON_ASSERT
207
  if (g_assertion_context != nullptr && os::current_thread_id() == g_asserting_thread) {
208
    context = g_assertion_context;
209
  }
210
#endif // CAN_SHOW_REGISTERS_ON_ASSERT
211

212
  print_error_for_unit_test("fatal error", detail_fmt, detail_args);
213

214
  VMError::report_and_die(error_type, "fatal error", detail_fmt, detail_args,
215
                          Thread::current_or_null(), nullptr, nullptr, context,
216
                          file, line, 0);
217
  va_end(detail_args);
218
}
219

220
void report_vm_out_of_memory(const char* file, int line, size_t size,
221
                             VMErrorType vm_err_type, const char* detail_fmt, ...) {
222
  va_list detail_args;
223
  va_start(detail_args, detail_fmt);
224

225
  print_error_for_unit_test(nullptr, detail_fmt, detail_args);
226

227
  VMError::report_and_die(Thread::current_or_null(), file, line, size, vm_err_type, detail_fmt, detail_args);
228
  va_end(detail_args);
229

230
  // The UseOSErrorReporting option in report_and_die() may allow a return
231
  // to here. If so then we'll have to figure out how to handle it.
232
  guarantee(false, "report_and_die() should not return here");
233
}
234

235
void report_should_not_call(const char* file, int line) {
236
  report_vm_error(file, line, "ShouldNotCall()");
237
}
238

239
void report_should_not_reach_here(const char* file, int line) {
240
  report_vm_error(file, line, "ShouldNotReachHere()");
241
}
242

243
void report_unimplemented(const char* file, int line) {
244
  report_vm_error(file, line, "Unimplemented()");
245
}
246

247
void report_untested(const char* file, int line, const char* message) {
248
#ifndef PRODUCT
249
  warning("Untested: %s in %s: %d\n", message, file, line);
250
#endif // !PRODUCT
251
}
252

253
void report_java_out_of_memory(const char* message) {
254
  static int out_of_memory_reported = 0;
255

256
  // A number of threads may attempt to report OutOfMemoryError at around the
257
  // same time. To avoid dumping the heap or executing the data collection
258
  // commands multiple times we just do it once when the first threads reports
259
  // the error.
260
  if (Atomic::cmpxchg(&out_of_memory_reported, 0, 1) == 0) {
261
    // create heap dump before OnOutOfMemoryError commands are executed
262
    if (HeapDumpOnOutOfMemoryError) {
263
      tty->print_cr("java.lang.OutOfMemoryError: %s", message);
264
      HeapDumper::dump_heap_from_oome();
265
    }
266

267
    if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
268
      VMError::report_java_out_of_memory(message);
269
    }
270

271
    if (CrashOnOutOfMemoryError) {
272
      tty->print_cr("Aborting due to java.lang.OutOfMemoryError: %s", message);
273
      report_fatal(OOM_JAVA_HEAP_FATAL, __FILE__, __LINE__, "OutOfMemory encountered: %s", message);
274
    }
275

276
    if (ExitOnOutOfMemoryError) {
277
      tty->print_cr("Terminating due to java.lang.OutOfMemoryError: %s", message);
278
      os::_exit(3); // quick exit with no cleanup hooks run
279
    }
280
  }
281
}
282

283
// ------ helper functions for debugging go here ------------
284

285
// All debug entries should be wrapped with a stack allocated
286
// Command object. It makes sure a resource mark is set and
287
// flushes the logfile to prevent file sharing problems.
288

289
class Command : public StackObj {
290
 private:
291
  ResourceMark _rm;
292
  DebuggingContext _debugging;
293
 public:
294
  static int level;
295
  Command(const char* str) {
296
    if (level++ > 0)  return;
297
    tty->cr();
298
    tty->print_cr("\"Executing %s\"", str);
299
  }
300

301
  ~Command() {
302
    tty->flush();
303
    level--;
304
  }
305
};
306

307
int Command::level = 0;
308

309
extern "C" DEBUGEXPORT void blob(CodeBlob* cb) {
310
  Command c("blob");
311
  cb->print();
312
}
313

314

315
extern "C" DEBUGEXPORT void dump_vtable(address p) {
316
  Command c("dump_vtable");
317
  Klass* k = (Klass*)p;
318
  k->vtable().print();
319
}
320

321

322
extern "C" DEBUGEXPORT void nm(intptr_t p) {
323
  // Actually we look through all CodeBlobs (the nm name has been kept for backwards compatibility)
324
  Command c("nm");
325
  CodeBlob* cb = CodeCache::find_blob((address)p);
326
  if (cb == nullptr) {
327
    tty->print_cr("null");
328
  } else {
329
    cb->print();
330
  }
331
}
332

333

334
extern "C" DEBUGEXPORT void disnm(intptr_t p) {
335
  Command c("disnm");
336
  CodeBlob* cb = CodeCache::find_blob((address) p);
337
  if (cb != nullptr) {
338
    nmethod* nm = cb->as_nmethod_or_null();
339
    if (nm != nullptr) {
340
      nm->print();
341
    } else {
342
      cb->print();
343
    }
344
    Disassembler::decode(cb);
345
  }
346
}
347

348

349
extern "C" DEBUGEXPORT void printnm(intptr_t p) {
350
  char buffer[256];
351
  os::snprintf_checked(buffer, sizeof(buffer), "printnm: " INTPTR_FORMAT, p);
352
  Command c(buffer);
353
  CodeBlob* cb = CodeCache::find_blob((address) p);
354
  if (cb != nullptr && cb->is_nmethod()) {
355
    nmethod* nm = (nmethod*)cb;
356
    nm->print_nmethod(true);
357
  } else {
358
    tty->print_cr("Invalid address");
359
  }
360
}
361

362

363
extern "C" DEBUGEXPORT void universe() {
364
  Command c("universe");
365
  Universe::print_on(tty);
366
}
367

368

369
extern "C" DEBUGEXPORT void verify() {
370
  // try to run a verify on the entire system
371
  // note: this may not be safe if we're not at a safepoint; for debugging,
372
  // this manipulates the safepoint settings to avoid assertion failures
373
  Command c("universe verify");
374
  bool safe = SafepointSynchronize::is_at_safepoint();
375
  if (!safe) {
376
    tty->print_cr("warning: not at safepoint -- verify may fail");
377
    SafepointSynchronize::set_is_at_safepoint();
378
  }
379
  // Ensure Eden top is correct before verification
380
  Universe::heap()->prepare_for_verify();
381
  Universe::verify();
382
  if (!safe) SafepointSynchronize::set_is_not_at_safepoint();
383
}
384

385

386
extern "C" DEBUGEXPORT void pp(void* p) {
387
  Command c("pp");
388
  FlagSetting fl(DisplayVMOutput, true);
389
  if (p == nullptr) {
390
    tty->print_cr("null");
391
    return;
392
  }
393
  if (Universe::heap()->is_in(p)) {
394
    oop obj = cast_to_oop(p);
395
    obj->print();
396
  } else {
397
    // Ask NMT about this pointer.
398
    // GDB note: We will be using SafeFetch to access the supposed malloc header. If the address is
399
    // not readable, this will generate a signal. That signal will trip up the debugger: gdb will
400
    // catch the signal and disable the pp() command for further use.
401
    // In order to avoid that, switch off SIGSEGV handling with "handle SIGSEGV nostop" before
402
    // invoking pp()
403
    if (MemTracker::print_containing_region(p, tty)) {
404
      return;
405
    }
406
    tty->print_cr(PTR_FORMAT, p2i(p));
407
  }
408
}
409

410

411
extern "C" DEBUGEXPORT void findpc(intptr_t x);
412

413
extern "C" DEBUGEXPORT void ps() { // print stack
414
  if (Thread::current_or_null() == nullptr) return;
415
  Command c("ps");
416

417
  // Prints the stack of the current Java thread
418
  JavaThread* p = JavaThread::active();
419
  tty->print(" for thread: ");
420
  p->print();
421
  tty->cr();
422

423
  if (p->has_last_Java_frame()) {
424
    // If the last_Java_fp is set we are in C land and
425
    // can call the standard stack_trace function.
426
    p->print_stack();
427
#ifndef PRODUCT
428
    if (Verbose) p->trace_stack();
429
  } else {
430
    frame f = os::current_frame();
431
    RegisterMap reg_map(p,
432
                        RegisterMap::UpdateMap::include,
433
                        RegisterMap::ProcessFrames::include,
434
                        RegisterMap::WalkContinuation::skip);
435
    f = f.sender(&reg_map);
436
    tty->print("(guessing starting frame id=" PTR_FORMAT " based on current fp)\n", p2i(f.id()));
437
    p->trace_stack_from(vframe::new_vframe(&f, &reg_map, p));
438
#endif
439
  }
440
}
441

442
extern "C" DEBUGEXPORT void pfl() {
443
  // print frame layout
444
  Command c("pfl");
445
  JavaThread* p = JavaThread::active();
446
  tty->print(" for thread: ");
447
  p->print();
448
  tty->cr();
449
  if (p->has_last_Java_frame()) {
450
    p->print_frame_layout();
451
  }
452
}
453

454
extern "C" DEBUGEXPORT void psf() { // print stack frames
455
  {
456
    Command c("psf");
457
    JavaThread* p = JavaThread::active();
458
    tty->print(" for thread: ");
459
    p->print();
460
    tty->cr();
461
    if (p->has_last_Java_frame()) {
462
      p->trace_frames();
463
    }
464
  }
465
}
466

467

468
extern "C" DEBUGEXPORT void threads() {
469
  Command c("threads");
470
  Threads::print(false, true);
471
}
472

473

474
extern "C" DEBUGEXPORT void psd() {
475
  Command c("psd");
476
  SystemDictionary::print();
477
}
478

479

480
extern "C" DEBUGEXPORT void pss() { // print all stacks
481
  if (Thread::current_or_null() == nullptr) return;
482
  Command c("pss");
483
  Threads::print(true, PRODUCT_ONLY(false) NOT_PRODUCT(true));
484
}
485

486
// #ifndef PRODUCT
487

488
extern "C" DEBUGEXPORT void debug() {               // to set things up for compiler debugging
489
  Command c("debug");
490
  NOT_PRODUCT(WizardMode = true;)
491
  PrintCompilation = true;
492
  PrintInlining = PrintAssembly = true;
493
  tty->flush();
494
}
495

496

497
extern "C" DEBUGEXPORT void ndebug() {              // undo debug()
498
  Command c("ndebug");
499
  PrintCompilation = false;
500
  PrintInlining = PrintAssembly = false;
501
  tty->flush();
502
}
503

504

505
extern "C" DEBUGEXPORT void flush()  {
506
  Command c("flush");
507
  tty->flush();
508
}
509

510
extern "C" DEBUGEXPORT void events() {
511
  Command c("events");
512
  Events::print();
513
}
514

515
extern "C" DEBUGEXPORT Method* findm(intptr_t pc) {
516
  Command c("findm");
517
  nmethod* nm = CodeCache::find_nmethod((address)pc);
518
  return (nm == nullptr) ? (Method*)nullptr : nm->method();
519
}
520

521

522
extern "C" DEBUGEXPORT nmethod* findnm(intptr_t addr) {
523
  Command c("findnm");
524
  return  CodeCache::find_nmethod((address)addr);
525
}
526

527
extern "C" DEBUGEXPORT void find(intptr_t x) {
528
  Command c("find");
529
  os::print_location(tty, x, false);
530
}
531

532

533
extern "C" DEBUGEXPORT void findpc(intptr_t x) {
534
  Command c("findpc");
535
  os::print_location(tty, x, true);
536
}
537

538
// For findmethod() and findclass():
539
//   See comments in classPrinter.hpp about the meanings of class_name_pattern, method_pattern and flags.
540
// Examples (in gdb):
541
//   call findclass("java/lang/Object", 0x3)             -> find j.l.Object and disasm all of its methods
542
//   call findmethod("*ang/Object*", "wait", 0xff)       -> detailed disasm of all "wait" methods in j.l.Object
543
//   call findmethod("*ang/Object*", "wait:(*J*)V", 0x1) -> list all "wait" methods in j.l.Object that have a long parameter
544
extern "C" DEBUGEXPORT void findclass(const char* class_name_pattern, int flags) {
545
  Command c("findclass");
546
  ClassPrinter::print_flags_help(tty);
547
  ClassPrinter::print_classes(class_name_pattern, flags, tty);
548
}
549

550
extern "C" DEBUGEXPORT void findmethod(const char* class_name_pattern,
551
                                     const char* method_pattern, int flags) {
552
  Command c("findmethod");
553
  ClassPrinter::print_flags_help(tty);
554
  ClassPrinter::print_methods(class_name_pattern, method_pattern, flags, tty);
555
}
556

557
// Need method pointer to find bcp
558
extern "C" DEBUGEXPORT void findbcp(intptr_t method, intptr_t bcp) {
559
  Command c("findbcp");
560
  Method* mh = (Method*)method;
561
  if (!mh->is_native()) {
562
    tty->print_cr("bci_from(%p) = %d; print_codes():",
563
                        mh, mh->bci_from(address(bcp)));
564
    mh->print_codes_on(tty);
565
  }
566
}
567

568
// check and decode a single u5 value
569
extern "C" DEBUGEXPORT u4 u5decode(intptr_t addr) {
570
  Command c("u5decode");
571
  u1* arr = (u1*)addr;
572
  size_t off = 0, lim = 5;
573
  if (!UNSIGNED5::check_length(arr, off, lim)) {
574
    return 0;
575
  }
576
  return UNSIGNED5::read_uint(arr, off, lim);
577
}
578

579
// Sets up a Reader from addr/limit and prints count items.
580
// A limit of zero means no set limit; stop at the first null
581
// or after count items are printed.
582
// A count of zero or less is converted to -1, which means
583
// there is no limit on the count of items printed; the
584
// printing stops when an null is printed or at limit.
585
// See documentation for UNSIGNED5::Reader::print(count).
586
extern "C" DEBUGEXPORT intptr_t u5p(intptr_t addr,
587
                                  intptr_t limit,
588
                                  int count) {
589
  Command c("u5p");
590
  u1* arr = (u1*)addr;
591
  if (limit && limit < addr)  limit = addr;
592
  size_t lim = !limit ? 0 : (limit - addr);
593
  size_t endpos = UNSIGNED5::print_count(count > 0 ? count : -1,
594
                                         arr, (size_t)0, lim);
595
  return addr + endpos;
596
}
597

598

599
// int versions of all methods to avoid having to type type casts in the debugger
600

601
void pp(intptr_t p)          { pp((void*)p); }
602
void pp(oop p)               { pp((void*)p); }
603

604
void help() {
605
  Command c("help");
606
  tty->print_cr("basic");
607
  tty->print_cr("  pp(void* p)   - try to make sense of p");
608
  tty->print_cr("  ps()          - print current thread stack");
609
  tty->print_cr("  pss()         - print all thread stacks");
610
  tty->print_cr("  pm(int pc)    - print Method* given compiled PC");
611
  tty->print_cr("  findm(intptr_t pc) - finds Method*");
612
  tty->print_cr("  find(intptr_t x)   - finds & prints nmethod/stub/bytecode/oop based on pointer into it");
613
  tty->print_cr("  pns(void* sp, void* fp, void* pc)  - print native (i.e. mixed) stack trace. E.g.");
614
  tty->print_cr("                   pns($sp, $rbp, $pc) on Linux/amd64 or");
615
  tty->print_cr("                   pns($sp, $ebp, $pc) on Linux/x86 or");
616
  tty->print_cr("                   pns($sp, $fp, $pc)  on Linux/AArch64 or");
617
  tty->print_cr("                   pns($sp, 0, $pc)    on Linux/ppc64 or");
618
  tty->print_cr("                   pns($sp, $s8, $pc)  on Linux/mips or");
619
  tty->print_cr("                 - in gdb do 'set overload-resolution off' before calling pns()");
620
  tty->print_cr("                 - in dbx do 'frame 1' before calling pns()");
621
  tty->print_cr("class metadata.");
622
  tty->print_cr("  findclass(name_pattern, flags)");
623
  tty->print_cr("  findmethod(class_name_pattern, method_pattern, flags)");
624

625
  tty->print_cr("misc.");
626
  tty->print_cr("  flush()       - flushes the log file");
627
  tty->print_cr("  events()      - dump events from ring buffers");
628

629

630
  tty->print_cr("compiler debugging");
631
  tty->print_cr("  debug()       - to set things up for compiler debugging");
632
  tty->print_cr("  ndebug()      - undo debug");
633
}
634

635
#ifndef PRODUCT
636
extern "C" DEBUGEXPORT void pns(void* sp, void* fp, void* pc) { // print native stack
637
  Command c("pns");
638
  static char buf[O_BUFLEN];
639
  Thread* t = Thread::current_or_null();
640
  // Call generic frame constructor (certain arguments may be ignored)
641
  frame fr(sp, fp, pc);
642
  VMError::print_native_stack(tty, fr, t, false, -1, buf, sizeof(buf));
643
}
644

645
//
646
// This version of pns() will not work when called from the debugger, but is
647
// useful when called from within hotspot code. The advantages over pns()
648
// are not having to pass in any arguments, and it will work on Windows/x64.
649
//
650
// WARNING: Only intended for use when debugging. Do not leave calls to
651
// pns2() in committed source (product or debug).
652
//
653
extern "C" DEBUGEXPORT void pns2() { // print native stack
654
  Command c("pns2");
655
  static char buf[O_BUFLEN];
656
  address lastpc = nullptr;
657
  if (os::platform_print_native_stack(tty, nullptr, buf, sizeof(buf), lastpc)) {
658
    // We have printed the native stack in platform-specific code,
659
    // so nothing else to do in this case.
660
  } else {
661
    Thread* t = Thread::current_or_null();
662
    frame fr = os::current_frame();
663
    VMError::print_native_stack(tty, fr, t, false, -1, buf, sizeof(buf));
664
  }
665
}
666
#endif
667

668

669
// Returns true iff the address p is readable and *(intptr_t*)p != errvalue
670
extern "C" bool dbg_is_safe(const void* p, intptr_t errvalue) {
671
  return p != nullptr && SafeFetchN((intptr_t*)const_cast<void*>(p), errvalue) != errvalue;
672
}
673

674
extern "C" bool dbg_is_good_oop(oopDesc* o) {
675
  return dbg_is_safe(o, -1) && dbg_is_safe(o->klass(), -1) && oopDesc::is_oop(o) && o->klass()->is_klass();
676
}
677

678
//////////////////////////////////////////////////////////////////////////////
679
// Test multiple STATIC_ASSERT forms in various scopes.
680

681
#ifndef PRODUCT
682

683
// namespace scope
684
STATIC_ASSERT(true);
685
STATIC_ASSERT(true);
686
STATIC_ASSERT(1 == 1);
687
STATIC_ASSERT(0 == 0);
688

689
void test_multiple_static_assert_forms_in_function_scope() {
690
  STATIC_ASSERT(true);
691
  STATIC_ASSERT(true);
692
  STATIC_ASSERT(0 == 0);
693
  STATIC_ASSERT(1 == 1);
694
}
695

696
// class scope
697
struct TestMultipleStaticAssertFormsInClassScope {
698
  STATIC_ASSERT(true);
699
  STATIC_ASSERT(true);
700
  STATIC_ASSERT(0 == 0);
701
  STATIC_ASSERT(1 == 1);
702
};
703

704
#endif // !PRODUCT
705

706
// Support for showing register content on asserts/guarantees.
707
#ifdef CAN_SHOW_REGISTERS_ON_ASSERT
708

709
static ucontext_t g_stored_assertion_context;
710

711
void initialize_assert_poison() {
712
  char* page = os::reserve_memory(os::vm_page_size());
713
  if (page) {
714
    MemTracker::record_virtual_memory_type(page, mtInternal);
715
    if (os::commit_memory(page, os::vm_page_size(), false) &&
716
        os::protect_memory(page, os::vm_page_size(), os::MEM_PROT_NONE)) {
717
      g_assert_poison = page;
718
    }
719
  }
720
}
721

722
void disarm_assert_poison() {
723
  g_assert_poison = &g_dummy;
724
}
725

726
static void store_context(const void* context) {
727
  memcpy(&g_stored_assertion_context, context, sizeof(ucontext_t));
728
#if defined(LINUX) && defined(PPC64)
729
  // on Linux ppc64, ucontext_t contains pointers into itself which have to be patched up
730
  //  after copying the context (see comment in sys/ucontext.h):
731
  *((void**) &g_stored_assertion_context.uc_mcontext.regs) = &(g_stored_assertion_context.uc_mcontext.gp_regs);
732
#endif
733
}
734

735
bool handle_assert_poison_fault(const void* ucVoid, const void* faulting_address) {
736
  if (faulting_address == g_assert_poison) {
737
    // Disarm poison page.
738
    if (os::protect_memory((char*)g_assert_poison, os::vm_page_size(), os::MEM_PROT_RWX) == false) {
739
#ifdef ASSERT
740
      fprintf(stderr, "Assertion poison page cannot be unprotected - mprotect failed with %d (%s)",
741
              errno, os::strerror(errno));
742
      fflush(stderr);
743
#endif
744
      return false; // unprotecting memory may fail in OOM situations, as surprising as this sounds.
745
    }
746
    // Store Context away.
747
    if (ucVoid) {
748
      const intx my_tid = os::current_thread_id();
749
      if (Atomic::cmpxchg(&g_asserting_thread, (intx)0, my_tid) == 0) {
750
        store_context(ucVoid);
751
        g_assertion_context = &g_stored_assertion_context;
752
      }
753
    }
754
    return true;
755
  }
756
  return false;
757
}
758
#endif // CAN_SHOW_REGISTERS_ON_ASSERT
759

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.