outputStream's position not updated by disassembler

Krystal Mok rednaxelafx at gmail.com
Fri Sep 9 00:11:19 PDT 2011

Hi all,

I tried to add disassembly support in VM error reporting, but had a couple
of issues.
The result I'm looking for is something like this:

Instructions: (pc=0x00002b148974ddf2)
0x00002b148974ddd2:   48 8b 05 17 0d 42 00 41 c7 85 48 02 00 00 06 00
0x00002b148974dde2:   00 00 8b 38 e8 ed 3f 9a ff c6 80 6c 02 00 00 01
0x00002b148974ddf2:   45 89 26 c6 80 6c 02 00 00 00 48 8b 5b 48 48 8b
0x00002b148974de02:   7b 10 4c 8b 63 08 48 83 3f 00 74 09 e8 cd 6f a3

[Disassembling for mach='i386:x86-64']
  0x00002b148974ddf2: mov    %r12d,(%r14)
  0x00002b148974ddf5: movb   $0x0,0x26c(%rax)
  0x00002b148974ddfc: mov    0x48(%rbx),%rbx
  0x00002b148974de00: mov    0x10(%rbx),%rdi

I'm working on Linux/x64, HS20-b11. If I made this change to reuse
the disassembler plugin (if available):

diff -r f0f676c5a2c6 src/os_cpu/linux_x86/vm/os_linux_x86.cpp
--- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp  Tue Mar 15 19:30:16 2011
+++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp  Fri Sep 09 14:50:16 2011
@@ -29,6 +29,7 @@
 #include "classfile/vmSymbols.hpp"
 #include "code/icBuffer.hpp"
 #include "code/vtableStubs.hpp"
+#include "compiler/disassembler.hpp"
 #include "interpreter/interpreter.hpp"
 #include "jvm_linux.h"
 #include "memory/allocation.inline.hpp"
@@ -808,6 +809,11 @@
   address pc = os::Linux::ucontext_get_pc(uc);
   st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
   print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
+  // dump disassembly near pc
+  st->cr();
+  Disassembler::decode(pc, pc + 32, st);
+  st->cr();

 void os::print_register_info(outputStream *st, void *context) {

Then the disassembly output I'm getting misses all newlines at the end of
each instruction, like this:

[Disassembling for mach='i386:x86-64']
  0x00002b148974ddf2: mov    %r12d,(%r14)  0x00002b148974ddf5: movb
$0x0,0x26c(%rax) ...

Tracing down, the newlines are requested by the disassembler plugin (hsdis
in this case), handled by printf_to_env(void* env_pv, const char* format,
...), which in turn calls outputStream::bol().
bol() decides whether or not to write a newline depending on the current
position. By instrumenting printf_to_env, I found that the position was
always 0 during disassembling, which caused the problem of missing newlines.

But the same plugin, when used in situations like PrintInterpreter, works
fine; the position gets updated correctly, and no newlines are lost.

Does anyone have any idea what might have caused the difference? The
outputStream instances are different, sure, but staticBufferStream used in
error reporting look pretty innocent to me.

P.S. I could just work around this by changing the bol() call to a
cr()call. But that feels hackish, and I'm looking for a cleaner

Kris Mok
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/hotspot-dev/attachments/20110909/1f08f6b7/attachment.html 

More information about the hotspot-dev mailing list