JDK-8024364 : Win/x64: os::current_frame() and os::fetch_frame_from_context() returns wrong frame pointer.
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 9
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: windows
  • CPU: x86
  • Submitted: 2013-09-05
  • Updated: 2018-01-04
  • Resolved: 2018-01-04
Related Reports
Relates :  
Relates :  
Relates :  
Description
See http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2013-September/009131.html

src/os_cpu/windows_x86/vm/os_windows_x86.cpp:

     frame os::current_frame() {

     #ifdef AMD64
       // apparently _asm not supported on windows amd64
       typedef intptr_t*      get_fp_func           ();
       get_fp_func* func = CAST_TO_FN_PTR(get_fp_func*, StubRoutines::x86::get_previous_fp_entry());
       if (func == NULL) return frame();
       intptr_t* fp = (*func)();
     #else
     ...

The code in get_previous_fp_entry() assumes the we have a frame pointer register (which is not always true), and RBP is that register (which is not always true). In some cases, especially when the C stack is shallow (e.g., when using -XX:ErrorHandlerTest=9), RBP can actually be NULL, because is has never been used by any of the C functions.

It turns out we also have the same problem in here:

    ExtendedPC os::fetch_frame_from_context(void* ucVoid,
                        intptr_t** ret_sp, intptr_t** ret_fp) {

      ExtendedPC  epc;
      CONTEXT* uc = (CONTEXT*)ucVoid;

      if (uc != NULL) {
        epc = ExtendedPC((address)uc->REG_PC);
        if (ret_sp) *ret_sp = (intptr_t*)uc->REG_SP;
        if (ret_fp) *ret_fp = (intptr_t*)uc->REG_FP;
      } else {
        // construct empty ExtendedPC for return value checking
        epc = ExtendedPC(NULL);
        if (ret_sp) *ret_sp = (intptr_t *)NULL;
        if (ret_fp) *ret_fp = (intptr_t *)NULL;
      }

      return epc;
    }

    frame os::fetch_frame_from_context(void* ucVoid) {
      intptr_t* sp;
      intptr_t* fp;
      ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
      return frame(sp, fp, epc.pc());
    }

There is no guarantee that "fp" would be related to "sp" in any way. It could be NULL, or could be just garbage.

So the use of os::current_frame() and os::fetch_frame_from_context(_context) is simply wrong on Win/x64. We haven't got much problem because most of the use is in debug code:

    ps() in debug.cpp
    oop::register_oop()

Comments
This is not on our list of current priorities. If there are additional specific customer requirements, we will consider reopening this issue. Closing as WNF.
04-01-2018

-XX:+CheckUnhandledOops support can not be turned on for Windows fastdebug builds until this issue os:current_frame() is fixed. Calls during universe_post_init() to oop::register_oop() and oop:unregister_oop in oops/oopsHierarchy.cpp will fail with a NULL frame pointer.
01-10-2013