8299790: os::print_hex_dump is racy
Reviewed-by: shade, dholmes
This commit is contained in:
parent
e080a0b4c0
commit
8f28809aa8
@ -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++;
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user