alternate pns() debug function

Thomas Stüfe thomas.stuefe at gmail.com
Wed Nov 8 19:26:44 UTC 2017


Hi Chris,


On Wed 8. Nov 2017 at 19:46, Chris Plummer <chris.plummer at oracle.com> wrote:

> Hi Thomas,
>
>
> On 11/8/17 7:33 AM, Thomas Stüfe wrote:
>
> Hi Chris, Ioi,
>
> On Tue, Nov 7, 2017 at 8:20 AM, Ioi Lam <ioi.lam at oracle.com> wrote:
>
>>
>>
>> On 11/6/17 9:05 PM, Chris Plummer wrote:
>>
>>> Hi,
>>>
>>> I'd like to add an alternate version of pns() to debug.cpp, and would
>>> like some initial comments first before filing a bug and sending out an
>>> RFR. pns() is used to print out the native stack:
>>>
>>> extern "C" void pns(void* sp, void* fp, void* pc) { // print native stack
>>>   Command c("pns");
>>>   static char buf[O_BUFLEN];
>>>   Thread* t = Thread::current_or_null();
>>>   // Call generic frame constructor (certain arguments may be ignored)
>>>   frame fr(sp, fp, pc);
>>>   VMError::print_native_stack(tty, fr, t, buf, sizeof(buf));
>>> }
>>>
>>> And here's the help output for it:
>>>
>>>   pns(void* sp, void* fp, void* pc)  - print native (i.e. mixed) stack
>>> trace. E.g.");
>>>                    pns($sp, $rbp, $pc) on Linux/amd64 and Solaris/amd64
>>> or");
>>>                    pns($sp, $ebp, $pc) on Linux/x86 or");
>>>                    pns($sp, 0, $pc)    on Linux/ppc64 or");
>>>                    pns($sp + 0x7ff, 0, $pc) on Solaris/SPARC");
>>>                  - in gdb do 'set overload-resolution off' before
>>> calling pns()");
>>>                  - in dbx do 'frame 1' before calling pns()");
>>>
>>> The intent is to call it from gdb, but it is potentially useful to call
>>> it from within hotspot when debugging. I'd like to propose the following
>>> alternative, since it does away with needing to pass in register values
>>> (not easy to do from C):
>>>
>>> extern "C" void pns2() { // print native stack
>>>   Command c("pns2");
>>>   static char buf[O_BUFLEN];
>>>   Thread* t = Thread::current_or_null();
>>>   frame fr = os::current_frame();
>>>   VMError::print_native_stack(tty, fr, t, buf, sizeof(buf));
>>> }
>>>
>>> I actually used this quite a bit with some recent debugging. There were
>>> places in hotspot where I wanted to know what the native stack looked like
>>> when called, and it was a lot easier to just add a call to pns2() than to
>>> setup the test to run in gdb. This seems to work on Linux/x64, macosx/64,
>>> and solaris/sparc. For some reason it crashes on Windows/x64, but I don't
>>> see any indication from the above help for pns() that it works on
>>> Windows/x64 anyway.
>>>
>>> #
>>> # A fatal error has been detected by the Java Runtime Environment:
>>> #
>>> #  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000003bcfae1466,
>>> pid=9872, tid=12212
>>> #
>>> # JRE version: Java(TM) SE Runtime Environment (10.0) (fastdebug build
>>> 10-internal+0-2017-11-07-0256309.chris.plummer.jdk10-hs)
>>> # Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug
>>> 10-internal+0-2017-11-07-0256309.chris.plummer.jdk10-hs, mixed mode,
>>> tiered, compressed oops, g1 gc, windows-amd64)
>>> # Problematic frame:
>>> # v  ~StubRoutines::get_previous_fp
>>> #
>>>
>>> I'm starting to suspect that os::current_frame() normally is never even
>>> called on Windows (there are calls to it in the VmError code, but I suspect
>>> they are never triggered on Windows) and that
>>> StubRoutines::get_previous_fp() is not working on Windows, but I could be
>>> wrong.
>>>
>>> Hi Chris,
>>
>> I like this new pns2() function.
>>
>> To make this work on Windows, you probably need to follow this pattern in
>> vmError.cpp.
>>
>>
>>      if (os::platform_print_native_stack(st, _context, buf, sizeof(buf)))
>> {
>>        // We have printed the native stack in platform-specific code
>>        // Windows/x64 needs special handling.
>>      } else {
>>        frame fr = _context ? os::fetch_frame_from_context(_context)
>>                            : os::current_frame();
>>
>>        print_native_stack(st, fr, _thread, buf, sizeof(buf));
>>      }
>>
>> Thanks
>> - Ioi
>>
>>
> Note that os::platform_print_native_stack() on Windows and AIX only print
> native C/C++ frames. So, calling this from the debugger may not be that
> useful.
>
> With the recent debug session I had, it was useful even with just the VM
> part of the backtrace.
>

Interesting. What did you see what the debugger would not show you?


> On AIX, it probably will not even be possible to invoke a function in the
> debugger - never tried, but given that not much else works in that thing, I
> am pessimistic.
>
> I was also pessimistic with gdb, so I tried it yesterday, and it didn't
> work. It's not in the proper context for os::current_frame() to provide the
> right information. So this will only be useful when inserted in hotspot
> code for debugging purposes.
>
>
> But pns() may still be useful as a tracing option, though.
>
> Not sure if you are talking about the original or my version. Both have
> their use: pns() from the debugger and pns2() from within hotspot code.
>
>
> On Windows x64, we do not have frame pointers, so we cannot walk the frame
> VM-Style, so os::platform_print_native_stack() is the only way to print a
> stack.
>
> Yes, and I got this to work Windows/x64, but unfortunately no symbols are
> printed.
>

When you let the Vm crash with e.g. -XX:ErrorHandlerTest=14, does the
resulting hs-err file show a correct callstack with symbols? If not, what
does the dbghelp.dll loader say (the one line below the loaded libraries
section)?


> On AIX, both ways work - VMError::print_native_stack() and
> os::platform_print_native_stack() - the former gives a mixed stack, the
> latter the pure C/C++ stack, but with many more information.
>
> In the end, for consistency, I'd suggest the same as Ioi, to follow the
> pattern in VMError().
>
> I've made that change already.
>
> And we could probably factor that out to an own function?
>
> I see your point, but given the simplicity of the change (the addition of
> one function with no disruption to existing code), I'm inclined to choose
> simplicity over elegance.
>
>
Sure! But having the generic os::current_frame function assert on windows
x64 is a bit of a trap. Maybe we should fix this at some point.

thanks,
>
> Chris
>
>
Best regards, Thomas

>
> Kind Regards, Thomas
>
>
>
>>
>> Let me know what you think.
>>>
>>> thanks,
>>>
>>> Chris
>>>
>>>
>>
>
>


More information about the hotspot-runtime-dev mailing list