X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Finline-frame.c;h=c650195e570e8d44b455aa5a3e13aaf29b7fe5f6;hb=cbd7581f343d85b4216db2eefdf601f6d988062d;hp=c6caf9d0c6ef937f676e641a4e7df322a903ab8e;hpb=991ff2922affa0b3afb837d2246d01f0c1fdb364;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/inline-frame.c b/gdb/inline-frame.c index c6caf9d0c6..c650195e57 100644 --- a/gdb/inline-frame.c +++ b/gdb/inline-frame.c @@ -1,6 +1,6 @@ /* Inline frame unwinder for GDB. - Copyright (C) 2008-2018 Free Software Foundation, Inc. + Copyright (C) 2008-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -27,7 +27,6 @@ #include "gdbthread.h" #include "regcache.h" #include "symtab.h" -#include "vec.h" #include "frame.h" #include @@ -38,9 +37,9 @@ struct inline_state { inline_state (thread_info *thread_, int skipped_frames_, CORE_ADDR saved_pc_, - symbol *skipped_symbol_) + std::vector &&skipped_symbols_) : thread (thread_), skipped_frames (skipped_frames_), saved_pc (saved_pc_), - skipped_symbol (skipped_symbol_) + skipped_symbols (std::move (skipped_symbols_)) {} /* The thread this data relates to. It should be a currently @@ -57,10 +56,10 @@ struct inline_state any skipped frames. */ CORE_ADDR saved_pc; - /* Only valid if SKIPPED_FRAMES is non-zero. This is the symbol - of the outermost skipped inline function. It's used to find the - call site of the current frame. */ - struct symbol *skipped_symbol; + /* Only valid if SKIPPED_FRAMES is non-zero. This is the list of all + function symbols that have been skipped, from inner most to outer + most. It is used to find the call site of the current frame. */ + std::vector skipped_symbols; }; static std::vector inline_states; @@ -96,37 +95,54 @@ find_inline_frame_state (thread_info *thread) return &state; } -/* Forget about any hidden inlined functions in PTID, which is new or - about to be resumed. PTID may be minus_one_ptid (all processes) - or a PID (all threads in this process). */ +/* See inline-frame.h. */ void -clear_inline_frame_state (ptid_t ptid) +clear_inline_frame_state (process_stratum_target *target, ptid_t filter_ptid) { - if (ptid == minus_one_ptid) - { - inline_states.clear (); - return; - } + gdb_assert (target != NULL); - if (ptid.is_pid ()) + if (filter_ptid == minus_one_ptid || filter_ptid.is_pid ()) { - int pid = ptid.pid (); + auto matcher = [target, &filter_ptid] (const inline_state &state) + { + thread_info *t = state.thread; + return (t->inf->process_target () == target + && t->ptid.matches (filter_ptid)); + }; + auto it = std::remove_if (inline_states.begin (), inline_states.end (), - [pid] (const inline_state &state) - { - return pid == state.thread->inf->pid; - }); + matcher); inline_states.erase (it, inline_states.end ()); return; } + + auto matcher = [target, &filter_ptid] (const inline_state &state) + { + thread_info *t = state.thread; + return (t->inf->process_target () == target + && filter_ptid == t->ptid); + }; + auto it = std::find_if (inline_states.begin (), inline_states.end (), - [&ptid] (const inline_state &state) + matcher); + + if (it != inline_states.end ()) + unordered_remove (inline_states, it); +} + +/* See inline-frame.h. */ + +void +clear_inline_frame_state (thread_info *thread) +{ + auto it = std::find_if (inline_states.begin (), inline_states.end (), + [thread] (const inline_state &state) { - return ptid == state.thread->ptid; + return thread == state.thread; }); if (it != inline_states.end ()) @@ -165,7 +181,7 @@ inline_frame_this_id (struct frame_info *this_frame, in the frame ID (and eventually, to set breakpoints). */ func = get_frame_function (this_frame); gdb_assert (func != NULL); - (*this_id).code_addr = BLOCK_START (SYMBOL_BLOCK_VALUE (func)); + (*this_id).code_addr = BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (func)); (*this_id).artificial_depth++; } @@ -266,13 +282,14 @@ static int block_starting_point_at (CORE_ADDR pc, const struct block *block) { const struct blockvector *bv; - struct block *new_block; + const struct block *new_block; bv = blockvector_for_pc (pc, NULL); if (BLOCKVECTOR_MAP (bv) == NULL) return 0; - new_block = (struct block *) addrmap_find (BLOCKVECTOR_MAP (bv), pc - 1); + new_block = (const struct block *) addrmap_find (BLOCKVECTOR_MAP (bv), + pc - 1); if (new_block == NULL) return 1; @@ -324,7 +341,7 @@ void skip_inline_frames (thread_info *thread, bpstat stop_chain) { const struct block *frame_block, *cur_block; - struct symbol *last_sym = NULL; + std::vector skipped_syms; int skip_count = 0; /* This function is called right after reinitializing the frame @@ -341,8 +358,8 @@ skip_inline_frames (thread_info *thread, bpstat stop_chain) if (block_inlined_p (cur_block)) { /* See comments in inline_frame_this_id about this use - of BLOCK_START. */ - if (BLOCK_START (cur_block) == this_pc + of BLOCK_ENTRY_PC. */ + if (BLOCK_ENTRY_PC (cur_block) == this_pc || block_starting_point_at (this_pc, cur_block)) { /* Do not skip the inlined frame if execution @@ -352,7 +369,7 @@ skip_inline_frames (thread_info *thread, bpstat stop_chain) break; skip_count++; - last_sym = BLOCK_FUNCTION (cur_block); + skipped_syms.push_back (BLOCK_FUNCTION (cur_block)); } else break; @@ -365,7 +382,8 @@ skip_inline_frames (thread_info *thread, bpstat stop_chain) } gdb_assert (find_inline_frame_state (thread) == NULL); - inline_states.emplace_back (thread, skip_count, this_pc, last_sym); + inline_states.emplace_back (thread, skip_count, this_pc, + std::move (skipped_syms)); if (skip_count != 0) reinit_frame_cache (); @@ -404,9 +422,16 @@ struct symbol * inline_skipped_symbol (thread_info *thread) { inline_state *state = find_inline_frame_state (thread); - gdb_assert (state != NULL); - return state->skipped_symbol; + + /* This should only be called when we are skipping at least one frame, + hence SKIPPED_FRAMES will be greater than zero when we get here. + We initialise SKIPPED_FRAMES at the same time as we build + SKIPPED_SYMBOLS, hence it should be true that SKIPPED_FRAMES never + indexes outside of the SKIPPED_SYMBOLS vector. */ + gdb_assert (state->skipped_frames > 0); + gdb_assert (state->skipped_frames <= state->skipped_symbols.size ()); + return state->skipped_symbols[state->skipped_frames - 1]; } /* Return the number of functions inlined into THIS_FRAME. Some of