8280289: Enhance debug pp() command with NMT info

Reviewed-by: stuefe, iklam
This commit is contained in:
Zhengyu Gu 2022-01-25 01:31:24 +00:00
parent f35df5bfb5
commit a59d717fd6
5 changed files with 113 additions and 30 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -31,6 +31,8 @@
#include "utilities/debug.hpp"
#include "utilities/ostream.hpp"
#include "jvm_io.h"
size_t MallocMemorySummary::_snapshot[CALC_OBJ_SIZE_IN_TYPE(MallocMemorySnapshot, size_t)];
#ifdef ASSERT
@ -115,7 +117,7 @@ void MallocHeader::mark_block_as_dead() {
void MallocHeader::release() {
assert(MemTracker::enabled(), "Sanity");
check_block_integrity();
assert_block_integrity();
MallocMemorySummary::record_free(size(), flags());
MallocMemorySummary::record_free_malloc_header(sizeof(MallocHeader));
@ -153,13 +155,18 @@ void MallocHeader::print_block_on_error(outputStream* st, address bad_address) c
os::print_hex_dump(st, from1, to2, 1);
}
}
void MallocHeader::assert_block_integrity() const {
char msg[256];
address corruption = NULL;
if (!check_block_integrity(msg, sizeof(msg), &corruption)) {
if (corruption != NULL) {
print_block_on_error(tty, (address)this);
}
fatal("NMT corruption: Block at " PTR_FORMAT ": %s", p2i(this), msg);
}
}
// Check block integrity. If block is broken, print out a report
// to tty (optionally with hex dump surrounding the broken block),
// then trigger a fatal error.
void MallocHeader::check_block_integrity() const {
#define PREFIX "NMT corruption: "
bool MallocHeader::check_block_integrity(char* msg, size_t msglen, address* p_corruption) const {
// Note: if you modify the error messages here, make sure you
// adapt the associated gtests too.
@ -167,7 +174,8 @@ void MallocHeader::check_block_integrity() const {
// values. Note that we should not call this for ::free(NULL),
// which should be handled by os::free() above us.
if (((size_t)p2i(this)) < K) {
fatal(PREFIX "Block at " PTR_FORMAT ": invalid block address", p2i(this));
jio_snprintf(msg, msglen, "invalid block address");
return false;
}
// From here on we assume the block pointer to be valid. We could
@ -186,37 +194,42 @@ void MallocHeader::check_block_integrity() const {
// Should we ever start using std::max_align_t, this would be one place to
// fix up.
if (!is_aligned(this, sizeof(uint64_t))) {
print_block_on_error(tty, (address)this);
fatal(PREFIX "Block at " PTR_FORMAT ": block address is unaligned", p2i(this));
*p_corruption = (address)this;
jio_snprintf(msg, msglen, "block address is unaligned");
return false;
}
// Check header canary
if (_canary != _header_canary_life_mark) {
print_block_on_error(tty, (address)this);
fatal(PREFIX "Block at " PTR_FORMAT ": header canary broken.", p2i(this));
*p_corruption = (address)this;
jio_snprintf(msg, msglen, "header canary broken");
return false;
}
#ifndef _LP64
// On 32-bit we have a second canary, check that one too.
if (_alt_canary != _header_alt_canary_life_mark) {
print_block_on_error(tty, (address)this);
fatal(PREFIX "Block at " PTR_FORMAT ": header alternate canary broken.", p2i(this));
*p_corruption = (address)this;
jio_snprintf(msg, msglen, "header canary broken");
return false;
}
#endif
// Does block size seems reasonable?
if (_size >= max_reasonable_malloc_size) {
print_block_on_error(tty, (address)this);
fatal(PREFIX "Block at " PTR_FORMAT ": header looks invalid (weirdly large block size)", p2i(this));
*p_corruption = (address)this;
jio_snprintf(msg, msglen, "header looks invalid (weirdly large block size)");
return false;
}
// Check footer canary
if (get_footer() != _footer_canary_life_mark) {
print_block_on_error(tty, footer_address());
fatal(PREFIX "Block at " PTR_FORMAT ": footer canary broken at " PTR_FORMAT " (buffer overflow?)",
p2i(this), p2i(footer_address()));
*p_corruption = footer_address();
jio_snprintf(msg, msglen, "footer canary broken at " PTR_FORMAT " (buffer overflow?)",
p2i(footer_address()));
return false;
}
#undef PREFIX
return true;
}
bool MallocHeader::record_malloc_site(const NativeCallStack& stack, size_t size,