diff --git a/src/hotspot/share/runtime/os.cpp b/src/hotspot/share/runtime/os.cpp index 6cb57e9dcb6..a8f3bc5c1d5 100644 --- a/src/hotspot/share/runtime/os.cpp +++ b/src/hotspot/share/runtime/os.cpp @@ -1016,11 +1016,14 @@ static void print_hex_location(outputStream* st, const_address p, int unitsize, } void os::print_hex_dump(outputStream* st, const_address start, const_address end, int unitsize, - bool print_ascii, int bytes_per_line, const_address logical_start) { + bool print_ascii, int bytes_per_line, const_address logical_start, const_address highlight_address) { constexpr int max_bytes_per_line = 64; assert(unitsize == 1 || unitsize == 2 || unitsize == 4 || unitsize == 8, "just checking"); assert(bytes_per_line > 0 && bytes_per_line <= max_bytes_per_line && is_power_of_2(bytes_per_line), "invalid bytes_per_line"); + assert(highlight_address == nullptr || (highlight_address >= start && highlight_address < end), + "address %p to highlight not in range %p - %p", highlight_address, start, end); + start = align_down(start, unitsize); logical_start = align_down(logical_start, unitsize); @@ -1037,7 +1040,11 @@ void os::print_hex_dump(outputStream* st, const_address start, const_address end // Print out the addresses as if we were starting from logical_start. while (p < end) { if (cols == 0) { - st->print(PTR_FORMAT ": ", p2i(logical_p)); + // highlight start of line if address of interest is located in the line + const bool should_highlight = (highlight_address >= p && highlight_address < p + bytes_per_line); + const char* const prefix = + (highlight_address != nullptr) ? (should_highlight ? "=>" : " ") : ""; + st->print("%s" PTR_FORMAT ": ", prefix, p2i(logical_p)); } print_hex_location(st, p, unitsize, ascii_form); p += unitsize; @@ -1082,7 +1089,7 @@ void os::print_tos(outputStream* st, address sp) { void os::print_instructions(outputStream* st, address pc, int unitsize) { st->print_cr("Instructions: (pc=" PTR_FORMAT ")", p2i(pc)); - print_hex_dump(st, pc - 256, pc + 256, unitsize, /* print_ascii=*/false); + print_hex_dump(st, pc - 256, pc + 256, unitsize, /* print_ascii=*/false, pc); } void os::print_environment_variables(outputStream* st, const char** env_list) { diff --git a/src/hotspot/share/runtime/os.hpp b/src/hotspot/share/runtime/os.hpp index 63ea1721667..1d81612c033 100644 --- a/src/hotspot/share/runtime/os.hpp +++ b/src/hotspot/share/runtime/os.hpp @@ -857,9 +857,9 @@ class os: AllStatic { static frame current_frame(); static void print_hex_dump(outputStream* st, const_address start, const_address end, int unitsize, bool print_ascii, - int bytes_per_line, const_address logical_start); - static void print_hex_dump(outputStream* st, const_address start, const_address end, int unitsize, bool print_ascii = true) { - print_hex_dump(st, start, end, unitsize, print_ascii, /*bytes_per_line=*/16, /*logical_start=*/start); + int bytes_per_line, const_address logical_start, const_address highlight_address = nullptr); + static void print_hex_dump(outputStream* st, const_address start, const_address end, int unitsize, bool print_ascii = true, const_address highlight_address = nullptr) { + print_hex_dump(st, start, end, unitsize, print_ascii, /*bytes_per_line=*/16, /*logical_start=*/start, highlight_address); } // returns a string to describe the exception/signal; diff --git a/test/hotspot/gtest/runtime/test_os.cpp b/test/hotspot/gtest/runtime/test_os.cpp index 4d3e6ba7f52..78e5212ab37 100644 --- a/test/hotspot/gtest/runtime/test_os.cpp +++ b/test/hotspot/gtest/runtime/test_os.cpp @@ -178,6 +178,16 @@ static void do_test_print_hex_dump(const_address from, const_address to, int uni EXPECT_STREQ(buf, expected); } +// version with a highlighted pc location +static void do_test_print_hex_dump_highlighted(const_address from, const_address to, int unitsize, int bytes_per_line, + const_address logical_start, const char* expected, const_address highlight) { + char buf[2048]; + buf[0] = '\0'; + stringStream ss(buf, sizeof(buf)); + os::print_hex_dump(&ss, from, to, unitsize, /* print_ascii=*/true, bytes_per_line, logical_start, highlight); + EXPECT_STREQ(buf, expected); +} + TEST_VM(os, test_print_hex_dump) { #ifdef _LP64 @@ -197,6 +207,24 @@ TEST_VM(os, test_print_hex_dump) { ADDRESS2 ": ff ff e0 dc 23 00 6a 64 6b 2f 69 6e 74 65 72 6e 61 6c 2f 6c 6f 61 64 65 72 2f 4e 61 74 69 76 65 " ASCII_1 "\n" \ ADDRESS3 ": 4c 69 62 72 61 72 69 65 73 00 00 00 00 00 00 00 " ASCII_2 "\n" +#define PAT_HL_1A "=>" ADDRESS1 ": ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??\n" \ + " " ADDRESS2 ": ff ff e0 dc 23 00 6a 64 6b 2f 69 6e 74 65 72 6e 61 6c 2f 6c 6f 61 64 65 72 2f 4e 61 74 69 76 65 " ASCII_1 "\n" \ + " " ADDRESS3 ": 4c 69 62 72 61 72 69 65 73 00 00 00 00 00 00 00 " ASCII_2 "\n" + +#define PAT_HL_1B " " ADDRESS1 ": ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??\n" \ + "=>" ADDRESS2 ": ff ff e0 dc 23 00 6a 64 6b 2f 69 6e 74 65 72 6e 61 6c 2f 6c 6f 61 64 65 72 2f 4e 61 74 69 76 65 " ASCII_1 "\n" \ + " " ADDRESS3 ": 4c 69 62 72 61 72 69 65 73 00 00 00 00 00 00 00 " ASCII_2 "\n" + +#ifdef VM_LITTLE_ENDIAN +#define PAT_HL_1C " " ADDRESS1 ": ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ????\n" \ + "=>" ADDRESS2 ": ffff dce0 0023 646a 2f6b 6e69 6574 6e72 6c61 6c2f 616f 6564 2f72 614e 6974 6576 " ASCII_1 "\n" \ + " " ADDRESS3 ": 694c 7262 7261 6569 0073 0000 0000 0000 " ASCII_2 "\n" +#else +#define PAT_HL_1C " " ADDRESS1 ": ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ????\n" \ + "=>" ADDRESS2 ": ffff e0dc 2300 6a64 6b2f 696e 7465 726e 616c 2f6c 6f61 6465 722f 4e61 7469 7665 " ASCII_1 "\n" \ + " " ADDRESS3 ": 4c69 6272 6172 6965 7300 0000 0000 0000 " ASCII_2 "\n" +#endif + #ifdef VM_LITTLE_ENDIAN #define PAT_2 ADDRESS1 ": ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ???? ????\n" \ ADDRESS2 ": ffff dce0 0023 646a 2f6b 6e69 6574 6e72 6c61 6c2f 616f 6564 2f72 614e 6974 6576 " ASCII_1 "\n" \ @@ -252,6 +280,12 @@ TEST_VM(os, test_print_hex_dump) { do_test_print_hex_dump(from + 1, to, 4, 32, logical_start, PAT_4); do_test_print_hex_dump(from + 1, to, 8, 32, logical_start, PAT_8); + // print with highlighted address + do_test_print_hex_dump_highlighted(from, to, 1, 32, logical_start, PAT_HL_1A, from+5); + do_test_print_hex_dump_highlighted(from, to, 1, 32, logical_start, PAT_HL_1B, from+32); + do_test_print_hex_dump_highlighted(from, to, 1, 32, logical_start, PAT_HL_1B, from+60); + do_test_print_hex_dump_highlighted(from, to, 2, 32, logical_start, PAT_HL_1C, from+60); + os::release_memory(two_pages, ps * 2); } #endif // not AIX