<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <p>Using <span style="white-space: pre-wrap">fr->link() </span>in
      <span style="white-space: pre-wrap">get_sender_for_C_frame() gives the wrong answer because it refers to the current frame, not the sender frame.  There is no frame::sender_fp() because the information we need could be anywhere in the frame or even nowhere in the frame.  This is what the comment about StackWalk() API is hinting at.  Even debuggers can have trouble giving an accurate stack trace if external debug information is missing and frames do not contain the needed information themselves.</span></p>
    <p><span style="white-space: pre-wrap">dl
</span></p>
    <div class="moz-cite-prefix">On 7/10/24 10:52 PM, Julian Waters
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CAP2b4GNfyhviAjRakViZ6nqjBev9S3hYE0ejJ+zb+CNpa_r4GA@mail.gmail.com">
      <pre class="moz-quote-pre" wrap="">Hi Dean,

I eventually did find frame::link(), but ultimately it didn't seem to help as VMError::print_native_stack still doesn't work properly on Windows. It seems as though frame::link() calls addr_at on x86, which in turn calls frame::fp(), which returns _fp. I think whatever sets _fp for VMError::print_native_stack is the missing link here, but unfortunately I don't know where it's set

The code that I tried on Windows x64 is attached below

best regards,
Julian

// VC++ does not save frame pointer on stack in optimized build. It
// can be turned off by -Oy-. If we really want to walk C frames,
// we can use the StackWalk() API.
frame os::get_sender_for_C_frame(frame* fr) {
#ifdef __GNUC__
  return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
#elif defined(_MSC_VER)
  ShouldNotReachHere();
  return frame();
#endif
}

frame os::current_frame() {
#ifdef __GNUC__
  frame f(reinterpret_cast<intptr_t*>(os::current_stack_pointer()),
          reinterpret_cast<intptr_t*>(__builtin_frame_address(1)),
          CAST_FROM_FN_PTR(address, &os::current_frame));
  if (os::is_first_C_frame(&f)) {
    // stack is not walkable
    return frame();
  } else {
    return os::get_sender_for_C_frame(&f);
  }
#elif defined(_MSC_VER)
  return frame();  // cannot walk Windows frames this way.  See os::get_native_stack
                   // and os::platform_print_native_stack
#endif
}</pre>
    </blockquote>
  </body>
</html>