Hotspot generally allows ResourceMark nesting for stringStream object. This can corrupt
memory when the stringStream object is expanded under the second level ResourceMark.
Please see the following example. The stringStream object is expanded by calling
function "print", and the long string is copied into the expanded memory. After a
destruction from rm2, the expanded memory is freed so that the content of s is lost.
Even worse, the stringStream object "s" has access to unknown memory.
{
ResourceMark rm;
stringStream s;
{
ResourceMark rm2;
s.print("---------- nest test!kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
kkkkkkkkkkkkkkkkkkkkkkkkkkkkkdddddddddddddddddddddddaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
adddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddfffffffffffffffffffffffaaaaaaaaaaaaaaaaaaaaa end of string");
}
tty->print_cr(s.as_string()); // the string is already corrupted
}
Similar programming pattern has been seen in MethodHandlePrinter. As we see from the
following code, a "walk" function keeps appending to the stringStream object in
printer(namely _strbuf) under 2nd level ResourceMark(see Klass::oop_print_value_on).
static void print(Handle root, bool verbose, outputStream* out, TRAPS) {
ResourceMark rm;
MethodHandlePrinter printer(root, verbose, out, CHECK);
printer.walk(CHECK);
out->print("\n");
}
There's no test case associated with this issue, however embedding the aformentioned
code in hotspot can easily reveal the problem.