diff --git a/gdb/inline-frame.c b/gdb/inline-frame.c index 8ba886c3efc..759c526a7c2 100644 --- a/gdb/inline-frame.c +++ b/gdb/inline-frame.c @@ -550,15 +550,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)); - 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)); - function_symbols = &it->function_symbols; - skipped_frames = it->skipped_frames; - addr = it->saved_pc; + addr = get_frame_pc (get_current_frame ()); + local_function_symbols.emplace (gather_inline_frames (addr)); + + function_symbols = &(local_function_symbols.value ()); + skipped_frames = 0; + } } else { diff --git a/gdb/testsuite/gdb.base/maint-info-inline-frames-and-blocks.exp b/gdb/testsuite/gdb.base/maint-info-inline-frames-and-blocks.exp index 16be22a9963..97e5d99e405 100644 --- a/gdb/testsuite/gdb.base/maint-info-inline-frames-and-blocks.exp +++ b/gdb/testsuite/gdb.base/maint-info-inline-frames-and-blocks.exp @@ -173,6 +173,20 @@ gdb_test "maint info blocks" [make_blocks_result normal_func \ inline_func_a inline_func_b] \ "maint info blocks within inline function, all blocks still visible" +# Use 'stepi' and check 'maint info inline-frames' still works. +gdb_test "stepi" ".*" "perform stepi" +gdb_test "maint info inline-frames" \ + [multi_line \ + "^Inline state information for thread $decimal\\." \ + "program counter = $hex" \ + "skipped frames = 0" \ + "> inline_func_b"] \ + "check inline-frames state when within inline_func_b after stepi" + +gdb_test "maint info blocks" [make_blocks_result normal_func \ + inline_func_a inline_func_b] \ + "maint info blocks within inline function after stepi, all blocks still visible" + # Use the recorded $pc value to check inline frames. gdb_test "maint info inline-frames $pc" \ [multi_line \