8299790: os::print_hex_dump is racy

Reviewed-by: shade, dholmes
This commit is contained in:
Thomas Stuefe 2023-08-10 07:21:47 +00:00
parent e080a0b4c0
commit 8f28809aa8
2 changed files with 68 additions and 27 deletions

View File

@ -928,13 +928,58 @@ bool os::print_function_and_library_name(outputStream* st,
return have_function_name || have_library_name;
}
ATTRIBUTE_NO_ASAN static void print_hex_readable_pointer(outputStream* st, address p,
int unitsize) {
switch (unitsize) {
case 1: st->print("%02x", *(u1*)p); break;
case 2: st->print("%04x", *(u2*)p); break;
case 4: st->print("%08x", *(u4*)p); break;
case 8: st->print("%016" FORMAT64_MODIFIER "x", *(u8*)p); break;
ATTRIBUTE_NO_ASAN static bool read_safely_from(intptr_t* p, intptr_t* result) {
const intptr_t errval = 0x1717;
intptr_t i = SafeFetchN(p, errval);
if (i == errval) {
i = SafeFetchN(p, ~errval);
if (i == ~errval) {
return false;
}
}
(*result) = i;
return true;
}
static void print_hex_location(outputStream* st, address p, int unitsize) {
address pa = align_down(p, sizeof(intptr_t));
#ifndef _LP64
// Special handling for printing qwords on 32-bit platforms
if (unitsize == 8) {
intptr_t i1, i2;
if (read_safely_from((intptr_t*)pa, &i1) &&
read_safely_from((intptr_t*)pa + 1, &i2)) {
const uint64_t value =
LITTLE_ENDIAN_ONLY((((uint64_t)i2) << 32) | i1)
BIG_ENDIAN_ONLY((((uint64_t)i1) << 32) | i2);
st->print("%016" FORMAT64_MODIFIER "x", value);
} else {
st->print_raw("????????????????");
}
return;
}
#endif // 32-bit, qwords
intptr_t i = 0;
if (read_safely_from((intptr_t*)pa, &i)) {
const int offset = (int)(p - (address)pa);
const int bitoffset =
LITTLE_ENDIAN_ONLY(offset * BitsPerByte)
BIG_ENDIAN_ONLY((int)(sizeof(intptr_t) - 1 - offset) * BitsPerByte);
const int bitfieldsize = unitsize * BitsPerByte;
intptr_t value = bitfield(i, bitoffset, bitfieldsize);
switch (unitsize) {
case 1: st->print("%02x", (u1)value); break;
case 2: st->print("%04x", (u2)value); break;
case 4: st->print("%08x", (u4)value); break;
case 8: st->print("%016" FORMAT64_MODIFIER "x", (u8)value); break;
}
} else {
switch (unitsize) {
case 1: st->print_raw("??"); break;
case 2: st->print_raw("????"); break;
case 4: st->print_raw("????????"); break;
case 8: st->print_raw("????????????????"); break;
}
}
}
@ -955,11 +1000,7 @@ void os::print_hex_dump(outputStream* st, address start, address end, int unitsi
// Print out the addresses as if we were starting from logical_start.
st->print(PTR_FORMAT ": ", p2i(logical_p));
while (p < end) {
if (is_readable_pointer(p)) {
print_hex_readable_pointer(st, p, unitsize);
} else {
st->print("%*.*s", 2*unitsize, 2*unitsize, "????????????????");
}
print_hex_location(st, p, unitsize);
p += unitsize;
logical_p += unitsize;
cols++;

View File

@ -169,31 +169,31 @@ static void do_test_print_hex_dump(address addr, size_t len, int unitsize, const
buf[0] = '\0';
stringStream ss(buf, sizeof(buf));
os::print_hex_dump(&ss, addr, addr + len, unitsize);
// tty->print_cr("expected: %s", expected);
// tty->print_cr("result: %s", buf);
ASSERT_NE(strstr(buf, expected), (char*)NULL);
// tty->print_cr("expected: %s", expected);
// tty->print_cr("result: %s", buf);
EXPECT_THAT(buf, testing::HasSubstr(expected));
}
TEST_VM(os, test_print_hex_dump) {
const char* pattern [4] = {
#ifdef VM_LITTLE_ENDIAN
"00 01 02 03 04 05 06 07",
"0100 0302 0504 0706",
"03020100 07060504",
"0706050403020100"
"00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f",
"0100 0302 0504 0706 0908 0b0a 0d0c 0f0e",
"03020100 07060504 0b0a0908 0f0e0d0c",
"0706050403020100 0f0e0d0c0b0a0908"
#else
"00 01 02 03 04 05 06 07",
"0001 0203 0405 0607",
"00010203 04050607",
"0001020304050607"
"00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f",
"0001 0203 0405 0607 0809 0a0b 0c0d 0e0f",
"00010203 04050607 08090a0b 0c0d0e0f",
"0001020304050607 08090a0b0c0d0e0f"
#endif
};
const char* pattern_not_readable [4] = {
"?? ?? ?? ?? ?? ?? ?? ??",
"???? ???? ???? ????",
"???????? ????????",
"????????????????"
"?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??",
"???? ???? ???? ???? ???? ???? ???? ????",
"???????? ???????? ???????? ????????",
"???????????????? ????????????????"
};
// On AIX, zero page is readable.