8200613: SA: jstack throws UnmappedAddressException with a CDS core file
Dump the closed archive heap space into the corefile on Linux by setting bit 2 of the coredump_filter file to dump the file backed private mappings. Reviewed-by: iklam, cjplummer, kevinw, coleenp
This commit is contained in:
parent
f4016e5582
commit
fdf7d4ec11
@ -67,6 +67,11 @@
|
||||
" of quotas (if set), when true. Otherwise, use the CPU" \
|
||||
" shares value, provided it is less than quota.") \
|
||||
\
|
||||
diagnostic(bool, DumpPrivateMappingsInCore, true, \
|
||||
"If true, sets bit 2 of /proc/PID/coredump_filter, thus " \
|
||||
"resulting in file-backed private mappings of the process to "\
|
||||
"be dumped into the corefile, if UseSharedSpaces is true.") \
|
||||
\
|
||||
diagnostic(bool, UseCpuAllocPath, false, \
|
||||
"Use CPU_ALLOC code path in os::active_processor_count ")
|
||||
|
||||
|
@ -128,8 +128,12 @@
|
||||
// for timer info max values which include all bits
|
||||
#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
|
||||
|
||||
#define LARGEPAGES_BIT (1 << 6)
|
||||
#define DAX_SHARED_BIT (1 << 8)
|
||||
enum CoredumpFilterBit {
|
||||
FILE_BACKED_PVT_BIT = 1 << 2,
|
||||
LARGEPAGES_BIT = 1 << 6,
|
||||
DAX_SHARED_BIT = 1 << 8
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// global variables
|
||||
julong os::Linux::_physical_memory = 0;
|
||||
@ -1350,6 +1354,9 @@ void os::shutdown() {
|
||||
void os::abort(bool dump_core, void* siginfo, const void* context) {
|
||||
os::shutdown();
|
||||
if (dump_core) {
|
||||
if (UseSharedSpaces && DumpPrivateMappingsInCore) {
|
||||
ClassLoader::close_jrt_image();
|
||||
}
|
||||
#ifndef PRODUCT
|
||||
fdStream out(defaultStream::output_fd());
|
||||
out.print_raw("Current thread is ");
|
||||
@ -3401,10 +3408,9 @@ bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) {
|
||||
// - (bit 7) dax private memory
|
||||
// - (bit 8) dax shared memory
|
||||
//
|
||||
static void set_coredump_filter(bool largepages, bool dax_shared) {
|
||||
static void set_coredump_filter(CoredumpFilterBit bit) {
|
||||
FILE *f;
|
||||
long cdm;
|
||||
bool filter_changed = false;
|
||||
|
||||
if ((f = fopen("/proc/self/coredump_filter", "r+")) == NULL) {
|
||||
return;
|
||||
@ -3415,17 +3421,11 @@ static void set_coredump_filter(bool largepages, bool dax_shared) {
|
||||
return;
|
||||
}
|
||||
|
||||
long saved_cdm = cdm;
|
||||
rewind(f);
|
||||
cdm |= bit;
|
||||
|
||||
if (largepages && (cdm & LARGEPAGES_BIT) == 0) {
|
||||
cdm |= LARGEPAGES_BIT;
|
||||
filter_changed = true;
|
||||
}
|
||||
if (dax_shared && (cdm & DAX_SHARED_BIT) == 0) {
|
||||
cdm |= DAX_SHARED_BIT;
|
||||
filter_changed = true;
|
||||
}
|
||||
if (filter_changed) {
|
||||
if (cdm != saved_cdm) {
|
||||
fprintf(f, "%#lx", cdm);
|
||||
}
|
||||
|
||||
@ -3564,7 +3564,7 @@ void os::large_page_init() {
|
||||
size_t large_page_size = Linux::setup_large_page_size();
|
||||
UseLargePages = Linux::setup_large_page_type(large_page_size);
|
||||
|
||||
set_coredump_filter(true /*largepages*/, false /*dax_shared*/);
|
||||
set_coredump_filter(LARGEPAGES_BIT);
|
||||
}
|
||||
|
||||
#ifndef SHM_HUGETLB
|
||||
@ -5072,8 +5072,13 @@ jint os::init_2(void) {
|
||||
prio_init();
|
||||
|
||||
if (!FLAG_IS_DEFAULT(AllocateHeapAt)) {
|
||||
set_coredump_filter(false /*largepages*/, true /*dax_shared*/);
|
||||
set_coredump_filter(DAX_SHARED_BIT);
|
||||
}
|
||||
|
||||
if (UseSharedSpaces && DumpPrivateMappingsInCore) {
|
||||
set_coredump_filter(FILE_BACKED_PVT_BIT);
|
||||
}
|
||||
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
|
@ -363,6 +363,13 @@ void ClassPathZipEntry::contents_do(void f(const char* name, void* context), voi
|
||||
}
|
||||
}
|
||||
|
||||
void ClassPathImageEntry::close_jimage() {
|
||||
if (_jimage != NULL) {
|
||||
(*JImageClose)(_jimage);
|
||||
_jimage = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ClassPathImageEntry::ClassPathImageEntry(JImageFile* jimage, const char* name) :
|
||||
ClassPathEntry(),
|
||||
_jimage(jimage) {
|
||||
@ -614,6 +621,12 @@ void ClassLoader::update_module_path_entry_list(const char *path, TRAPS) {
|
||||
void ClassLoader::setup_module_search_path(const char* path, TRAPS) {
|
||||
update_module_path_entry_list(path, THREAD);
|
||||
}
|
||||
|
||||
void ClassLoader::close_jrt_image() {
|
||||
assert(ClassLoader::has_jrt_entry(), "Not applicable for exploded builds");
|
||||
_jrt_entry->close_jimage();
|
||||
}
|
||||
|
||||
#endif // INCLUDE_CDS
|
||||
|
||||
// Construct the array of module/path pairs as specified to --patch-module
|
||||
|
@ -55,6 +55,7 @@ public:
|
||||
virtual bool is_jar_file() const = 0;
|
||||
virtual const char* name() const = 0;
|
||||
virtual JImageFile* jimage() const = 0;
|
||||
virtual void close_jimage() = 0;
|
||||
// Constructor
|
||||
ClassPathEntry() : _next(NULL) {}
|
||||
// Attempt to locate file_name through this class path entry.
|
||||
@ -70,6 +71,7 @@ class ClassPathDirEntry: public ClassPathEntry {
|
||||
bool is_jar_file() const { return false; }
|
||||
const char* name() const { return _dir; }
|
||||
JImageFile* jimage() const { return NULL; }
|
||||
void close_jimage() {}
|
||||
ClassPathDirEntry(const char* dir);
|
||||
virtual ~ClassPathDirEntry() {}
|
||||
ClassFileStream* open_stream(const char* name, TRAPS);
|
||||
@ -98,6 +100,7 @@ class ClassPathZipEntry: public ClassPathEntry {
|
||||
bool is_jar_file() const { return true; }
|
||||
const char* name() const { return _zip_name; }
|
||||
JImageFile* jimage() const { return NULL; }
|
||||
void close_jimage() {}
|
||||
ClassPathZipEntry(jzfile* zip, const char* zip_name, bool is_boot_append);
|
||||
virtual ~ClassPathZipEntry();
|
||||
u1* open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS);
|
||||
@ -117,6 +120,7 @@ public:
|
||||
bool is_open() const { return _jimage != NULL; }
|
||||
const char* name() const { return _name == NULL ? "" : _name; }
|
||||
JImageFile* jimage() const { return _jimage; }
|
||||
void close_jimage();
|
||||
ClassPathImageEntry(JImageFile* jimage, const char* name);
|
||||
virtual ~ClassPathImageEntry();
|
||||
ClassFileStream* open_stream(const char* name, TRAPS);
|
||||
@ -333,6 +337,7 @@ class ClassLoader: AllStatic {
|
||||
// Modular java runtime image is present vs. a build with exploded modules
|
||||
static bool has_jrt_entry() { return (_jrt_entry != NULL); }
|
||||
static ClassPathEntry* get_jrt_entry() { return _jrt_entry; }
|
||||
static void close_jrt_image();
|
||||
|
||||
// Add a module's exploded directory to the boot loader's exploded module build list
|
||||
static void add_to_exploded_build_list(Symbol* module_name, TRAPS);
|
||||
|
@ -23,8 +23,8 @@
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8174994
|
||||
* @summary Test the clhsdb commands 'printmdo', 'printall' on a CDS enabled corefile.
|
||||
* @bug 8174994 8200613
|
||||
* @summary Test the clhsdb commands 'printmdo', 'printall', 'jstack' on a CDS enabled corefile.
|
||||
* @requires vm.cds
|
||||
* @requires vm.hasSA
|
||||
* @requires os.family != "windows"
|
||||
@ -156,7 +156,7 @@ public class ClhsdbCDSCore {
|
||||
throw new SkippedException("The CDS archive is not mapped");
|
||||
}
|
||||
|
||||
cmds = List.of("printmdo -a", "printall");
|
||||
cmds = List.of("printmdo -a", "printall", "jstack -v");
|
||||
|
||||
Map<String, List<String>> expStrMap = new HashMap<>();
|
||||
Map<String, List<String>> unExpStrMap = new HashMap<>();
|
||||
@ -182,6 +182,11 @@ public class ClhsdbCDSCore {
|
||||
"illegal code",
|
||||
"Failure occurred at bci",
|
||||
"No suitable match for type of address"));
|
||||
expStrMap.put("jstack -v", List.of(
|
||||
"Common-Cleaner",
|
||||
"Method*"));
|
||||
unExpStrMap.put("jstack -v", List.of(
|
||||
"sun.jvm.hotspot.debugger.UnmappedAddressException"));
|
||||
test.runOnCore(TEST_CDS_CORE_FILE_NAME, cmds, expStrMap, unExpStrMap);
|
||||
} catch (SkippedException e) {
|
||||
throw e;
|
||||
|
Loading…
x
Reference in New Issue
Block a user