/* 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.
#include "gdbthread.h"
#include "regcache.h"
#include "symtab.h"
-#include "vec.h"
#include "frame.h"
#include <algorithm>
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 ())
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++;
}
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;
bp_location *loc = s->bp_location_at;
enum bp_loc_type t = loc->loc_type;
- if ((t == bp_loc_software_breakpoint
- || t == bp_loc_hardware_breakpoint)
- && frame_block == SYMBOL_BLOCK_VALUE (loc->symbol))
- return true;
+ if (t == bp_loc_software_breakpoint
+ || t == bp_loc_hardware_breakpoint)
+ {
+ /* If the location has a function symbol, check whether
+ the frame was for that inlined function. If it has
+ no function symbol, then assume it is. I.e., default
+ to presenting the stop at the innermost inline
+ function. */
+ if (loc->symbol == nullptr
+ || frame_block == SYMBOL_BLOCK_VALUE (loc->symbol))
+ return true;
+ }
}
}
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