diff options
Diffstat (limited to 'gdb/inline-frame.c')
-rw-r--r-- | gdb/inline-frame.c | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/gdb/inline-frame.c b/gdb/inline-frame.c index 8ba886c..2191282 100644 --- a/gdb/inline-frame.c +++ b/gdb/inline-frame.c @@ -1,6 +1,6 @@ /* Inline frame unwinder for GDB. - Copyright (C) 2008-2024 Free Software Foundation, Inc. + Copyright (C) 2008-2025 Free Software Foundation, Inc. This file is part of GDB. @@ -22,6 +22,7 @@ #include "addrmap.h" #include "block.h" #include "frame-unwind.h" +#include "gdbsupport/gdb_vecs.h" #include "inferior.h" #include "gdbthread.h" #include "regcache.h" @@ -269,15 +270,16 @@ inline_frame_sniffer (const struct frame_unwind *self, return 1; } -const struct frame_unwind inline_frame_unwind = { +const struct frame_unwind_legacy inline_frame_unwind ( "inline", INLINE_FRAME, + FRAME_UNWIND_GDB, default_frame_unwind_stop_reason, inline_frame_this_id, inline_frame_prev_register, NULL, inline_frame_sniffer -}; +); /* Return non-zero if BLOCK, an inlined function block containing PC, has a group of contiguous instructions starting at PC (but not @@ -550,15 +552,38 @@ maintenance_info_inline_frames (const char *arg, int from_tty) return thread == istate.thread; }); - /* Stopped threads always have cached inline_state information. */ - gdb_assert (it != inline_states.end ()); + /* Stopped threads don't always have cached inline_state + information. We always skip computing the inline_state after a + stepi or nexti, but also in some other cases when we can be sure + that the inferior isn't at the start of an inlined function. + Check out the call to skip_inline_frames in handle_signal_stop + for more details. */ + if (it != inline_states.end ()) + { + /* We do have cached inline frame information, use it. This + gives us access to the current skipped_frames count so we can + correctly indicate when the inferior is not in the inner most + inlined function. */ + gdb_printf (_("Cached inline state information for thread %s.\n"), + print_thread_id (thread)); + + function_symbols = &it->function_symbols; + skipped_frames = it->skipped_frames; + addr = it->saved_pc; + } + else + { + /* No cached inline frame information, lookup the information for + the current address. */ + gdb_printf (_("Inline state information for thread %s.\n"), + print_thread_id (thread)); - gdb_printf (_("Cached inline state information for thread %s.\n"), - print_thread_id (thread)); + addr = get_frame_pc (get_current_frame ()); + local_function_symbols.emplace (gather_inline_frames (addr)); - function_symbols = &it->function_symbols; - skipped_frames = it->skipped_frames; - addr = it->saved_pc; + function_symbols = &(local_function_symbols.value ()); + skipped_frames = 0; + } } else { @@ -590,9 +615,7 @@ maintenance_info_inline_frames (const char *arg, int from_tty) -void _initialize_inline_frame (); -void -_initialize_inline_frame () +INIT_GDB_FILE (inline_frame) { add_cmd ("inline-frames", class_maintenance, maintenance_info_inline_frames, _("\ |