[External] : Re: Where does VMError::print_native_stack and os::get_sender_for_C_frame load/use the frame pointer?

Julian Waters tanksherman27 at gmail.com
Thu Jul 11 08:12:40 UTC 2024


Hi Dean,

Thanks for the quick reply. At the risk of testing your patience, I
don't really follow, since that is how os::get_sender_for_C_frame is
implemented on other platforms (I copied it from Linux x86 in this
case). All I got from the comment is that the only reason we usually
have to use the StackWalk API on Windows is because the frame pointer
is not saved when using the Microsoft compiler, however in my case I'm
not using the Microsoft compiler and have verified that the frame
pointer is saved in my custom JVMs. I'm not sure how
VMError::print_native_stack on other platforms manages to work when
they also do

return frame(fr->sender_sp(), fr->link(), fr->sender_pc());

in os::get_sender_for_C_frame like I did here

Thanks for your time and patience!

best regards,
Julian

On Thu, Jul 11, 2024 at 3:17 PM <dean.long at oracle.com> wrote:
>
> Using fr->link() in 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.
>
> dl
>
> On 7/10/24 10:52 PM, Julian Waters wrote:
>
> 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
> }


More information about the hotspot-dev mailing list