| /* Cache and manage frames for GDB, the GNU debugger. |
| |
| Copyright (C) 1986-2024 Free Software Foundation, Inc. |
| |
| This file is part of GDB. |
| |
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 3 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| |
| #include "frame.h" |
| #include "event-top.h" |
| #include "extract-store-integer.h" |
| #include "target.h" |
| #include "value.h" |
| #include "inferior.h" |
| #include "regcache.h" |
| #include "user-regs.h" |
| #include "gdbsupport/gdb_obstack.h" |
| #include "dummy-frame.h" |
| #include "sentinel-frame.h" |
| #include "gdbcore.h" |
| #include "annotate.h" |
| #include "language.h" |
| #include "frame-unwind.h" |
| #include "frame-base.h" |
| #include "command.h" |
| #include "cli/cli-cmds.h" |
| #include "observable.h" |
| #include "objfiles.h" |
| #include "gdbthread.h" |
| #include "block.h" |
| #include "inline-frame.h" |
| #include "tracepoint.h" |
| #include "hashtab.h" |
| #include "valprint.h" |
| #include "cli/cli-option.h" |
| #include "dwarf2/loc.h" |
| |
| /* The sentinel frame terminates the innermost end of the frame chain. |
| If unwound, it returns the information needed to construct an |
| innermost frame. |
| |
| The current frame, which is the innermost frame, can be found at |
| sentinel_frame->prev. |
| |
| This is an optimization to be able to find the sentinel frame quickly, |
| it could otherwise be found in the frame cache. */ |
| |
| static frame_info *sentinel_frame; |
| |
| /* Number of calls to reinit_frame_cache. */ |
| static unsigned int frame_cache_generation = 0; |
| |
| /* See frame.h. */ |
| |
| unsigned int |
| get_frame_cache_generation () |
| { |
| return frame_cache_generation; |
| } |
| |
| /* The values behind the global "set backtrace ..." settings. */ |
| set_backtrace_options user_set_backtrace_options; |
| |
| static frame_info_ptr get_prev_frame_raw (const frame_info_ptr &this_frame); |
| static const char *frame_stop_reason_symbol_string (enum unwind_stop_reason reason); |
| static frame_info_ptr create_new_frame (frame_id id); |
| |
| /* Status of some values cached in the frame_info object. */ |
| |
| enum cached_copy_status |
| { |
| /* Value is unknown. */ |
| CC_UNKNOWN, |
| |
| /* We have a value. */ |
| CC_VALUE, |
| |
| /* Value was not saved. */ |
| CC_NOT_SAVED, |
| |
| /* Value is unavailable. */ |
| CC_UNAVAILABLE |
| }; |
| |
| enum class frame_id_status |
| { |
| /* Frame id is not computed. */ |
| NOT_COMPUTED = 0, |
| |
| /* Frame id is being computed (compute_frame_id is active). */ |
| COMPUTING, |
| |
| /* Frame id has been computed. */ |
| COMPUTED, |
| }; |
| |
| /* We keep a cache of stack frames, each of which is a "struct |
| frame_info". The innermost one gets allocated (in |
| wait_for_inferior) each time the inferior stops; sentinel_frame |
| points to it. Additional frames get allocated (in get_prev_frame) |
| as needed, and are chained through the next and prev fields. Any |
| time that the frame cache becomes invalid (most notably when we |
| execute something, but also if we change how we interpret the |
| frames (e.g. "set heuristic-fence-post" in mips-tdep.c, or anything |
| which reads new symbols)), we should call reinit_frame_cache. */ |
| |
| struct frame_info |
| { |
| /* Return a string representation of this frame. */ |
| std::string to_string () const; |
| |
| /* Level of this frame. The inner-most (youngest) frame is at level |
| 0. As you move towards the outer-most (oldest) frame, the level |
| increases. This is a cached value. It could just as easily be |
| computed by counting back from the selected frame to the inner |
| most frame. */ |
| /* NOTE: cagney/2002-04-05: Perhaps a level of ``-1'' should be |
| reserved to indicate a bogus frame - one that has been created |
| just to keep GDB happy (GDB always needs a frame). For the |
| moment leave this as speculation. */ |
| int level; |
| |
| /* The frame's program space. */ |
| struct program_space *pspace; |
| |
| /* The frame's address space. */ |
| const address_space *aspace; |
| |
| /* The frame's low-level unwinder and corresponding cache. The |
| low-level unwinder is responsible for unwinding register values |
| for the previous frame. The low-level unwind methods are |
| selected based on the presence, or otherwise, of register unwind |
| information such as CFI. */ |
| void *prologue_cache; |
| const struct frame_unwind *unwind; |
| |
| /* Cached copy of the previous frame's architecture. */ |
| struct |
| { |
| bool p; |
| struct gdbarch *arch; |
| } prev_arch; |
| |
| /* Cached copy of the previous frame's resume address. */ |
| struct { |
| cached_copy_status status; |
| /* Did VALUE require unmasking when being read. */ |
| bool masked; |
| CORE_ADDR value; |
| } prev_pc; |
| |
| /* Cached copy of the previous frame's function address. */ |
| struct |
| { |
| CORE_ADDR addr; |
| cached_copy_status status; |
| } prev_func; |
| |
| /* This frame's ID. */ |
| struct |
| { |
| frame_id_status p; |
| struct frame_id value; |
| } this_id; |
| |
| /* The frame's high-level base methods, and corresponding cache. |
| The high level base methods are selected based on the frame's |
| debug info. */ |
| const struct frame_base *base; |
| void *base_cache; |
| |
| /* Pointers to the next (down, inner, younger) and previous (up, |
| outer, older) frame_info's in the frame cache. */ |
| struct frame_info *next; /* down, inner, younger */ |
| bool prev_p; |
| struct frame_info *prev; /* up, outer, older */ |
| |
| /* The reason why we could not set PREV, or UNWIND_NO_REASON if we |
| could. Only valid when PREV_P is set. */ |
| enum unwind_stop_reason stop_reason; |
| |
| /* A frame specific string describing the STOP_REASON in more detail. |
| Only valid when PREV_P is set, but even then may still be NULL. */ |
| const char *stop_string; |
| }; |
| |
| /* See frame.h. */ |
| |
| void |
| set_frame_previous_pc_masked (const frame_info_ptr &frame) |
| { |
| frame->prev_pc.masked = true; |
| } |
| |
| /* See frame.h. */ |
| |
| bool |
| get_frame_pc_masked (const frame_info_ptr &frame) |
| { |
| gdb_assert (frame->next != nullptr); |
| gdb_assert (frame->next->prev_pc.status == CC_VALUE); |
| |
| return frame->next->prev_pc.masked; |
| } |
| |
| /* A frame stash used to speed up frame lookups. Create a hash table |
| to stash frames previously accessed from the frame cache for |
| quicker subsequent retrieval. The hash table is emptied whenever |
| the frame cache is invalidated. */ |
| |
| static htab_t frame_stash; |
| |
| /* Internal function to calculate a hash from the frame_id addresses, |
| using as many valid addresses as possible. Frames below level 0 |
| are not stored in the hash table. */ |
| |
| static hashval_t |
| frame_addr_hash (const void *ap) |
| { |
| const frame_info *frame = (const frame_info *) ap; |
| const struct frame_id f_id = frame->this_id.value; |
| hashval_t hash = 0; |
| |
| gdb_assert (f_id.stack_status != FID_STACK_INVALID |
| || f_id.code_addr_p |
| || f_id.special_addr_p); |
| |
| if (f_id.stack_status == FID_STACK_VALID) |
| hash = iterative_hash (&f_id.stack_addr, |
| sizeof (f_id.stack_addr), hash); |
| if (f_id.code_addr_p) |
| hash = iterative_hash (&f_id.code_addr, |
| sizeof (f_id.code_addr), hash); |
| if (f_id.special_addr_p) |
| hash = iterative_hash (&f_id.special_addr, |
| sizeof (f_id.special_addr), hash); |
| |
| char user_created_p = f_id.user_created_p; |
| hash = iterative_hash (&user_created_p, sizeof (user_created_p), hash); |
| |
| return hash; |
| } |
| |
| /* Internal equality function for the hash table. This function |
| defers equality operations to frame_id::operator==. */ |
| |
| static int |
| frame_addr_hash_eq (const void *a, const void *b) |
| { |
| const frame_info *f_entry = (const frame_info *) a; |
| const frame_info *f_element = (const frame_info *) b; |
| |
| return f_entry->this_id.value == f_element->this_id.value; |
| } |
| |
| /* Deletion function for the frame cache hash table. */ |
| |
| static void |
| frame_info_del (frame_info *frame) |
| { |
| if (frame->prologue_cache != nullptr |
| && frame->unwind->dealloc_cache != nullptr) |
| frame->unwind->dealloc_cache (frame, frame->prologue_cache); |
| |
| if (frame->base_cache != nullptr |
| && frame->base->unwind->dealloc_cache != nullptr) |
| frame->base->unwind->dealloc_cache (frame, frame->base_cache); |
| } |
| |
| /* Internal function to create the frame_stash hash table. 100 seems |
| to be a good compromise to start the hash table at. */ |
| |
| static void |
| frame_stash_create (void) |
| { |
| frame_stash = htab_create |
| (100, frame_addr_hash, frame_addr_hash_eq, |
| [] (void *p) |
| { |
| auto frame = static_cast<frame_info *> (p); |
| frame_info_del (frame); |
| }); |
| } |
| |
| /* Internal function to add a frame to the frame_stash hash table. |
| Returns false if a frame with the same ID was already stashed, true |
| otherwise. */ |
| |
| static bool |
| frame_stash_add (frame_info *frame) |
| { |
| /* Valid frame levels are -1 (sentinel frames) and above. */ |
| gdb_assert (frame->level >= -1); |
| |
| frame_info **slot = (frame_info **) htab_find_slot (frame_stash, |
| frame, INSERT); |
| |
| /* If we already have a frame in the stack with the same id, we |
| either have a stack cycle (corrupted stack?), or some bug |
| elsewhere in GDB. In any case, ignore the duplicate and return |
| an indication to the caller. */ |
| if (*slot != nullptr) |
| return false; |
| |
| *slot = frame; |
| return true; |
| } |
| |
| /* Internal function to search the frame stash for an entry with the |
| given frame ID. If found, return that frame. Otherwise return |
| NULL. */ |
| |
| static frame_info_ptr |
| frame_stash_find (struct frame_id id) |
| { |
| struct frame_info dummy; |
| frame_info *frame; |
| |
| dummy.this_id.value = id; |
| frame = (frame_info *) htab_find (frame_stash, &dummy); |
| return frame_info_ptr (frame); |
| } |
| |
| /* Internal function to invalidate the frame stash by removing all |
| entries in it. This only occurs when the frame cache is |
| invalidated. */ |
| |
| static void |
| frame_stash_invalidate (void) |
| { |
| htab_empty (frame_stash); |
| } |
| |
| /* See frame.h */ |
| scoped_restore_selected_frame::scoped_restore_selected_frame () |
| { |
| m_lang = current_language->la_language; |
| save_selected_frame (&m_fid, &m_level); |
| } |
| |
| /* See frame.h */ |
| scoped_restore_selected_frame::~scoped_restore_selected_frame () |
| { |
| restore_selected_frame (m_fid, m_level); |
| set_language (m_lang); |
| } |
| |
| /* Flag to control debugging. */ |
| |
| bool frame_debug; |
| |
| static void |
| show_frame_debug (struct ui_file *file, int from_tty, |
| struct cmd_list_element *c, const char *value) |
| { |
| gdb_printf (file, _("Frame debugging is %s.\n"), value); |
| } |
| |
| /* Implementation of "show backtrace past-main". */ |
| |
| static void |
| show_backtrace_past_main (struct ui_file *file, int from_tty, |
| struct cmd_list_element *c, const char *value) |
| { |
| gdb_printf (file, |
| _("Whether backtraces should " |
| "continue past \"main\" is %s.\n"), |
| value); |
| } |
| |
| /* Implementation of "show backtrace past-entry". */ |
| |
| static void |
| show_backtrace_past_entry (struct ui_file *file, int from_tty, |
| struct cmd_list_element *c, const char *value) |
| { |
| gdb_printf (file, _("Whether backtraces should continue past the " |
| "entry point of a program is %s.\n"), |
| value); |
| } |
| |
| /* Implementation of "show backtrace limit". */ |
| |
| static void |
| show_backtrace_limit (struct ui_file *file, int from_tty, |
| struct cmd_list_element *c, const char *value) |
| { |
| gdb_printf (file, |
| _("An upper bound on the number " |
| "of backtrace levels is %s.\n"), |
| value); |
| } |
| |
| /* See frame.h. */ |
| |
| std::string |
| frame_id::to_string () const |
| { |
| const struct frame_id &id = *this; |
| |
| std::string res = "{"; |
| |
| if (id.stack_status == FID_STACK_INVALID) |
| res += "!stack"; |
| else if (id.stack_status == FID_STACK_UNAVAILABLE) |
| res += "stack=<unavailable>"; |
| else if (id.stack_status == FID_STACK_SENTINEL) |
| res += "stack=<sentinel>"; |
| else if (id.stack_status == FID_STACK_OUTER) |
| res += "stack=<outer>"; |
| else |
| res += std::string ("stack=") + hex_string (id.stack_addr); |
| |
| /* Helper function to format 'N=A' if P is true, otherwise '!N'. */ |
| auto field_to_string = [] (const char *n, bool p, CORE_ADDR a) -> std::string |
| { |
| if (p) |
| return std::string (n) + "=" + core_addr_to_string (a); |
| else |
| return std::string ("!") + std::string (n); |
| }; |
| |
| res += (std::string (",") |
| + field_to_string ("code", id.code_addr_p, id.code_addr) |
| + std::string (",") |
| + field_to_string ("special", id.special_addr_p, id.special_addr)); |
| |
| if (id.artificial_depth) |
| res += ",artificial=" + std::to_string (id.artificial_depth); |
| res += "}"; |
| return res; |
| } |
| |
| /* See frame.h. */ |
| |
| const char * |
| frame_type_str (frame_type type) |
| { |
| switch (type) |
| { |
| case NORMAL_FRAME: |
| return "NORMAL_FRAME"; |
| |
| case DUMMY_FRAME: |
| return "DUMMY_FRAME"; |
| |
| case INLINE_FRAME: |
| return "INLINE_FRAME"; |
| |
| case TAILCALL_FRAME: |
| return "TAILCALL_FRAME"; |
| |
| case SIGTRAMP_FRAME: |
| return "SIGTRAMP_FRAME"; |
| |
| case ARCH_FRAME: |
| return "ARCH_FRAME"; |
| |
| case SENTINEL_FRAME: |
| return "SENTINEL_FRAME"; |
| |
| default: |
| return "<unknown type>"; |
| }; |
| } |
| |
| /* See struct frame_info. */ |
| |
| std::string |
| frame_info::to_string () const |
| { |
| const frame_info *fi = this; |
| |
| std::string res; |
| |
| res += string_printf ("{level=%d,", fi->level); |
| |
| if (fi->unwind != NULL) |
| res += string_printf ("type=%s,", frame_type_str (fi->unwind->type)); |
| else |
| res += "type=<unknown>,"; |
| |
| if (fi->unwind != NULL) |
| res += string_printf ("unwinder=\"%s\",", fi->unwind->name); |
| else |
| res += "unwinder=<unknown>,"; |
| |
| if (fi->next == NULL || fi->next->prev_pc.status == CC_UNKNOWN) |
| res += "pc=<unknown>,"; |
| else if (fi->next->prev_pc.status == CC_VALUE) |
| res += string_printf ("pc=%s%s,", hex_string (fi->next->prev_pc.value), |
| fi->next->prev_pc.masked ? "[PAC]" : ""); |
| else if (fi->next->prev_pc.status == CC_NOT_SAVED) |
| res += "pc=<not saved>,"; |
| else if (fi->next->prev_pc.status == CC_UNAVAILABLE) |
| res += "pc=<unavailable>,"; |
| |
| if (fi->this_id.p == frame_id_status::NOT_COMPUTED) |
| res += "id=<not computed>,"; |
| else if (fi->this_id.p == frame_id_status::COMPUTING) |
| res += "id=<computing>,"; |
| else |
| res += string_printf ("id=%s,", fi->this_id.value.to_string ().c_str ()); |
| |
| if (fi->next != NULL && fi->next->prev_func.status == CC_VALUE) |
| res += string_printf ("func=%s", hex_string (fi->next->prev_func.addr)); |
| else |
| res += "func=<unknown>"; |
| |
| res += "}"; |
| |
| return res; |
| } |
| |
| /* Given FRAME, return the enclosing frame as found in real frames read-in from |
| inferior memory. Skip any previous frames which were made up by GDB. |
| Return FRAME if FRAME is a non-artificial frame. |
| Return NULL if FRAME is the start of an artificial-only chain. */ |
| |
| static frame_info_ptr |
| skip_artificial_frames (const frame_info_ptr &initial_frame) |
| { |
| /* Note we use get_prev_frame_always, and not get_prev_frame. The |
| latter will truncate the frame chain, leading to this function |
| unintentionally returning a null_frame_id (e.g., when the user |
| sets a backtrace limit). |
| |
| Note that for record targets we may get a frame chain that consists |
| of artificial frames only. */ |
| frame_info_ptr frame = initial_frame; |
| while (get_frame_type (frame) == INLINE_FRAME |
| || get_frame_type (frame) == TAILCALL_FRAME) |
| { |
| frame = get_prev_frame_always (frame); |
| if (frame == NULL) |
| break; |
| } |
| |
| return frame; |
| } |
| |
| frame_info_ptr |
| skip_unwritable_frames (const frame_info_ptr &initial_frame) |
| { |
| frame_info_ptr frame = initial_frame; |
| while (gdbarch_code_of_frame_writable (get_frame_arch (frame), frame) == 0) |
| { |
| frame = get_prev_frame (frame); |
| if (frame == NULL) |
| break; |
| } |
| |
| return frame; |
| } |
| |
| /* See frame.h. */ |
| |
| frame_info_ptr |
| skip_tailcall_frames (const frame_info_ptr &initial_frame) |
| { |
| frame_info_ptr frame = initial_frame; |
| while (get_frame_type (frame) == TAILCALL_FRAME) |
| { |
| /* Note that for record targets we may get a frame chain that consists of |
| tailcall frames only. */ |
| frame = get_prev_frame (frame); |
| if (frame == NULL) |
| break; |
| } |
| |
| return frame; |
| } |
| |
| /* Compute the frame's uniq ID that can be used to, later, re-find the |
| frame. */ |
| |
| static void |
| compute_frame_id (const frame_info_ptr &fi) |
| { |
| FRAME_SCOPED_DEBUG_ENTER_EXIT; |
| |
| gdb_assert (fi->this_id.p == frame_id_status::NOT_COMPUTED); |
| |
| unsigned int entry_generation = get_frame_cache_generation (); |
| |
| try |
| { |
| /* Mark this frame's id as "being computed. */ |
| fi->this_id.p = frame_id_status::COMPUTING; |
| |
| frame_debug_printf ("fi=%d", fi->level); |
| |
| /* Find the unwinder. */ |
| if (fi->unwind == NULL) |
| frame_unwind_find_by_frame (fi, &fi->prologue_cache); |
| |
| /* Find THIS frame's ID. */ |
| /* Default to outermost if no ID is found. */ |
| fi->this_id.value = outer_frame_id; |
| fi->unwind->this_id (fi, &fi->prologue_cache, &fi->this_id.value); |
| gdb_assert (frame_id_p (fi->this_id.value)); |
| |
| /* Mark this frame's id as "computed". */ |
| fi->this_id.p = frame_id_status::COMPUTED; |
| |
| frame_debug_printf (" -> %s", fi->this_id.value.to_string ().c_str ()); |
| } |
| catch (const gdb_exception &ex) |
| { |
| /* On error, revert the frame id status to not computed. If the frame |
| cache generation changed, the frame object doesn't exist anymore, so |
| don't touch it. */ |
| if (get_frame_cache_generation () == entry_generation) |
| fi->this_id.p = frame_id_status::NOT_COMPUTED; |
| |
| throw; |
| } |
| } |
| |
| /* Return a frame uniq ID that can be used to, later, re-find the |
| frame. */ |
| |
| struct frame_id |
| get_frame_id (const frame_info_ptr &fi) |
| { |
| if (fi == NULL) |
| return null_frame_id; |
| |
| /* It's always invalid to try to get a frame's id while it is being |
| computed. */ |
| gdb_assert (fi->this_id.p != frame_id_status::COMPUTING); |
| |
| if (fi->this_id.p == frame_id_status::NOT_COMPUTED) |
| { |
| /* If we haven't computed the frame id yet, then it must be that |
| this is the current frame. Compute it now, and stash the |
| result. The IDs of other frames are computed as soon as |
| they're created, in order to detect cycles. See |
| get_prev_frame_if_no_cycle. */ |
| gdb_assert (fi->level == 0); |
| |
| /* Compute. */ |
| compute_frame_id (fi); |
| |
| /* Since this is the first frame in the chain, this should |
| always succeed. */ |
| bool stashed = frame_stash_add (fi.get ()); |
| gdb_assert (stashed); |
| } |
| |
| return fi->this_id.value; |
| } |
| |
| struct frame_id |
| get_stack_frame_id (const frame_info_ptr &next_frame) |
| { |
| return get_frame_id (skip_artificial_frames (next_frame)); |
| } |
| |
| struct frame_id |
| frame_unwind_caller_id (const frame_info_ptr &initial_next_frame) |
| { |
| /* Use get_prev_frame_always, and not get_prev_frame. The latter |
| will truncate the frame chain, leading to this function |
| unintentionally returning a null_frame_id (e.g., when a caller |
| requests the frame ID of "main()"s caller. */ |
| |
| frame_info_ptr next_frame = skip_artificial_frames (initial_next_frame); |
| if (next_frame == NULL) |
| return null_frame_id; |
| |
| frame_info_ptr this_frame = get_prev_frame_always (next_frame); |
| if (this_frame) |
| return get_frame_id (skip_artificial_frames (this_frame)); |
| else |
| return null_frame_id; |
| } |
| |
| const struct frame_id null_frame_id = { 0 }; /* All zeros. */ |
| const struct frame_id outer_frame_id = { 0, 0, 0, FID_STACK_OUTER, 0, 1, 0 }; |
| |
| struct frame_id |
| frame_id_build_special (CORE_ADDR stack_addr, CORE_ADDR code_addr, |
| CORE_ADDR special_addr) |
| { |
| struct frame_id id = null_frame_id; |
| |
| id.stack_addr = stack_addr; |
| id.stack_status = FID_STACK_VALID; |
| id.code_addr = code_addr; |
| id.code_addr_p = true; |
| id.special_addr = special_addr; |
| id.special_addr_p = true; |
| return id; |
| } |
| |
| /* See frame.h. */ |
| |
| struct frame_id |
| frame_id_build_unavailable_stack (CORE_ADDR code_addr) |
| { |
| struct frame_id id = null_frame_id; |
| |
| id.stack_status = FID_STACK_UNAVAILABLE; |
| id.code_addr = code_addr; |
| id.code_addr_p = true; |
| return id; |
| } |
| |
| /* See frame.h. */ |
| |
| struct frame_id |
| frame_id_build_unavailable_stack_special (CORE_ADDR code_addr, |
| CORE_ADDR special_addr) |
| { |
| struct frame_id id = null_frame_id; |
| |
| id.stack_status = FID_STACK_UNAVAILABLE; |
| id.code_addr = code_addr; |
| id.code_addr_p = true; |
| id.special_addr = special_addr; |
| id.special_addr_p = true; |
| return id; |
| } |
| |
| struct frame_id |
| frame_id_build (CORE_ADDR stack_addr, CORE_ADDR code_addr) |
| { |
| struct frame_id id = null_frame_id; |
| |
| id.stack_addr = stack_addr; |
| id.stack_status = FID_STACK_VALID; |
| id.code_addr = code_addr; |
| id.code_addr_p = true; |
| return id; |
| } |
| |
| struct frame_id |
| frame_id_build_wild (CORE_ADDR stack_addr) |
| { |
| struct frame_id id = null_frame_id; |
| |
| id.stack_addr = stack_addr; |
| id.stack_status = FID_STACK_VALID; |
| return id; |
| } |
| |
| /* See frame.h. */ |
| |
| frame_id |
| frame_id_build_sentinel (CORE_ADDR stack_addr, CORE_ADDR code_addr) |
| { |
| frame_id id = null_frame_id; |
| |
| id.stack_status = FID_STACK_SENTINEL; |
| id.special_addr_p = 1; |
| |
| if (stack_addr != 0 || code_addr != 0) |
| { |
| /* The purpose of saving these in the sentinel frame ID is to be able to |
| differentiate the IDs of several sentinel frames that could exist |
| simultaneously in the frame cache. */ |
| id.stack_addr = stack_addr; |
| id.code_addr = code_addr; |
| id.code_addr_p = 1; |
| } |
| |
| return id; |
| } |
| |
| bool |
| frame_id_p (frame_id l) |
| { |
| /* The frame is valid iff it has a valid stack address. */ |
| bool p = l.stack_status != FID_STACK_INVALID; |
| |
| frame_debug_printf ("l=%s -> %d", l.to_string ().c_str (), p); |
| |
| return p; |
| } |
| |
| bool |
| frame_id_artificial_p (frame_id l) |
| { |
| if (!frame_id_p (l)) |
| return false; |
| |
| return l.artificial_depth != 0; |
| } |
| |
| bool |
| frame_id::operator== (const frame_id &r) const |
| { |
| bool eq; |
| |
| if (stack_status == FID_STACK_INVALID |
| || r.stack_status == FID_STACK_INVALID) |
| /* Like a NaN, if either ID is invalid, the result is false. |
| Note that a frame ID is invalid iff it is the null frame ID. */ |
| eq = false; |
| else if (stack_status != r.stack_status || stack_addr != r.stack_addr) |
| /* If .stack addresses are different, the frames are different. */ |
| eq = false; |
| else if (code_addr_p && r.code_addr_p && code_addr != r.code_addr) |
| /* An invalid code addr is a wild card. If .code addresses are |
| different, the frames are different. */ |
| eq = false; |
| else if (special_addr_p && r.special_addr_p |
| && special_addr != r.special_addr) |
| /* An invalid special addr is a wild card (or unused). Otherwise |
| if special addresses are different, the frames are different. */ |
| eq = false; |
| else if (artificial_depth != r.artificial_depth) |
| /* If artificial depths are different, the frames must be different. */ |
| eq = false; |
| else if (user_created_p != r.user_created_p) |
| eq = false; |
| else |
| /* Frames are equal. */ |
| eq = true; |
| |
| frame_debug_printf ("l=%s, r=%s -> %d", |
| to_string ().c_str (), r.to_string ().c_str (), eq); |
| |
| return eq; |
| } |
| |
| /* Safety net to check whether frame ID L should be inner to |
| frame ID R, according to their stack addresses. |
| |
| This method cannot be used to compare arbitrary frames, as the |
| ranges of valid stack addresses may be discontiguous (e.g. due |
| to sigaltstack). |
| |
| However, it can be used as safety net to discover invalid frame |
| IDs in certain circumstances. Assuming that NEXT is the immediate |
| inner frame to THIS and that NEXT and THIS are both NORMAL frames: |
| |
| * The stack address of NEXT must be inner-than-or-equal to the stack |
| address of THIS. |
| |
| Therefore, if frame_id_inner (THIS, NEXT) holds, some unwind |
| error has occurred. |
| |
| * If NEXT and THIS have different stack addresses, no other frame |
| in the frame chain may have a stack address in between. |
| |
| Therefore, if frame_id_inner (TEST, THIS) holds, but |
| frame_id_inner (TEST, NEXT) does not hold, TEST cannot refer |
| to a valid frame in the frame chain. |
| |
| The sanity checks above cannot be performed when a SIGTRAMP frame |
| is involved, because signal handlers might be executed on a different |
| stack than the stack used by the routine that caused the signal |
| to be raised. This can happen for instance when a thread exceeds |
| its maximum stack size. In this case, certain compilers implement |
| a stack overflow strategy that cause the handler to be run on a |
| different stack. */ |
| |
| static bool |
| frame_id_inner (struct gdbarch *gdbarch, struct frame_id l, struct frame_id r) |
| { |
| bool inner; |
| |
| if (l.stack_status != FID_STACK_VALID || r.stack_status != FID_STACK_VALID) |
| /* Like NaN, any operation involving an invalid ID always fails. |
| Likewise if either ID has an unavailable stack address. */ |
| inner = false; |
| else if (l.artificial_depth > r.artificial_depth |
| && l.stack_addr == r.stack_addr |
| && l.code_addr_p == r.code_addr_p |
| && l.special_addr_p == r.special_addr_p |
| && l.special_addr == r.special_addr) |
| { |
| /* Same function, different inlined functions. */ |
| const struct block *lb, *rb; |
| |
| gdb_assert (l.code_addr_p && r.code_addr_p); |
| |
| lb = block_for_pc (l.code_addr); |
| rb = block_for_pc (r.code_addr); |
| |
| if (lb == NULL || rb == NULL) |
| /* Something's gone wrong. */ |
| inner = false; |
| else |
| /* This will return true if LB and RB are the same block, or |
| if the block with the smaller depth lexically encloses the |
| block with the greater depth. */ |
| inner = rb->contains (lb); |
| } |
| else |
| /* Only return non-zero when strictly inner than. Note that, per |
| comment in "frame.h", there is some fuzz here. Frameless |
| functions are not strictly inner than (same .stack but |
| different .code and/or .special address). */ |
| inner = gdbarch_inner_than (gdbarch, l.stack_addr, r.stack_addr); |
| |
| frame_debug_printf ("is l=%s inner than r=%s? %d", |
| l.to_string ().c_str (), r.to_string ().c_str (), |
| inner); |
| |
| return inner; |
| } |
| |
| frame_info_ptr |
| frame_find_by_id (struct frame_id id) |
| { |
| frame_info_ptr frame, prev_frame; |
| |
| /* ZERO denotes the null frame, let the caller decide what to do |
| about it. Should it instead return get_current_frame()? */ |
| if (!frame_id_p (id)) |
| return NULL; |
| |
| /* Check for the sentinel frame. */ |
| if (id == frame_id_build_sentinel (0, 0)) |
| return frame_info_ptr (sentinel_frame); |
| |
| /* Try using the frame stash first. Finding it there removes the need |
| to perform the search by looping over all frames, which can be very |
| CPU-intensive if the number of frames is very high (the loop is O(n) |
| and get_prev_frame performs a series of checks that are relatively |
| expensive). This optimization is particularly useful when this function |
| is called from another function (such as value_fetch_lazy, case |
| val->lval () == lval_register) which already loops over all frames, |
| making the overall behavior O(n^2). */ |
| frame = frame_stash_find (id); |
| if (frame) |
| return frame; |
| |
| for (frame = get_current_frame (); ; frame = prev_frame) |
| { |
| struct frame_id self = get_frame_id (frame); |
| |
| if (id == self) |
| /* An exact match. */ |
| return frame; |
| |
| prev_frame = get_prev_frame (frame); |
| if (!prev_frame) |
| return NULL; |
| |
| /* As a safety net to avoid unnecessary backtracing while trying |
| to find an invalid ID, we check for a common situation where |
| we can detect from comparing stack addresses that no other |
| frame in the current frame chain can have this ID. See the |
| comment at frame_id_inner for details. */ |
| if (get_frame_type (frame) == NORMAL_FRAME |
| && !frame_id_inner (get_frame_arch (frame), id, self) |
| && frame_id_inner (get_frame_arch (prev_frame), id, |
| get_frame_id (prev_frame))) |
| return NULL; |
| } |
| return NULL; |
| } |
| |
| static CORE_ADDR |
| frame_unwind_pc (const frame_info_ptr &this_frame) |
| { |
| if (this_frame->prev_pc.status == CC_UNKNOWN) |
| { |
| struct gdbarch *prev_gdbarch; |
| CORE_ADDR pc = 0; |
| bool pc_p = false; |
| |
| /* The right way. The `pure' way. The one true way. This |
| method depends solely on the register-unwind code to |
| determine the value of registers in THIS frame, and hence |
| the value of this frame's PC (resume address). A typical |
| implementation is no more than: |
| |
| frame_unwind_register (this_frame, ISA_PC_REGNUM, buf); |
| return extract_unsigned_integer (buf, size of ISA_PC_REGNUM); |
| |
| Note: this method is very heavily dependent on a correct |
| register-unwind implementation, it pays to fix that |
| method first; this method is frame type agnostic, since |
| it only deals with register values, it works with any |
| frame. This is all in stark contrast to the old |
| FRAME_SAVED_PC which would try to directly handle all the |
| different ways that a PC could be unwound. */ |
| prev_gdbarch = frame_unwind_arch (this_frame); |
| |
| try |
| { |
| pc = gdbarch_unwind_pc (prev_gdbarch, this_frame); |
| pc_p = true; |
| } |
| catch (const gdb_exception_error &ex) |
| { |
| if (ex.error == NOT_AVAILABLE_ERROR) |
| { |
| this_frame->prev_pc.status = CC_UNAVAILABLE; |
| |
| frame_debug_printf ("this_frame=%d -> <unavailable>", |
| this_frame->level); |
| } |
| else if (ex.error == OPTIMIZED_OUT_ERROR) |
| { |
| this_frame->prev_pc.status = CC_NOT_SAVED; |
| |
| frame_debug_printf ("this_frame=%d -> <not saved>", |
| this_frame->level); |
| } |
| else |
| throw; |
| } |
| |
| if (pc_p) |
| { |
| this_frame->prev_pc.value = pc; |
| this_frame->prev_pc.status = CC_VALUE; |
| |
| frame_debug_printf ("this_frame=%d -> %s", |
| this_frame->level, |
| hex_string (this_frame->prev_pc.value)); |
| } |
| } |
| |
| if (this_frame->prev_pc.status == CC_VALUE) |
| return this_frame->prev_pc.value; |
| else if (this_frame->prev_pc.status == CC_UNAVAILABLE) |
| throw_error (NOT_AVAILABLE_ERROR, _("PC not available")); |
| else if (this_frame->prev_pc.status == CC_NOT_SAVED) |
| throw_error (OPTIMIZED_OUT_ERROR, _("PC not saved")); |
| else |
| internal_error ("unexpected prev_pc status: %d", |
| (int) this_frame->prev_pc.status); |
| } |
| |
| CORE_ADDR |
| frame_unwind_caller_pc (const frame_info_ptr &initial_this_frame) |
| { |
| frame_info_ptr this_frame = skip_artificial_frames (initial_this_frame); |
| |
| /* We must have a non-artificial frame. The caller is supposed to check |
| the result of frame_unwind_caller_id (), which returns NULL_FRAME_ID |
| in this case. */ |
| gdb_assert (this_frame != nullptr); |
| |
| return frame_unwind_pc (this_frame); |
| } |
| |
| bool |
| get_frame_func_if_available (const frame_info_ptr &this_frame, CORE_ADDR *pc) |
| { |
| frame_info *next_frame = this_frame->next; |
| |
| if (next_frame->prev_func.status == CC_UNKNOWN) |
| { |
| CORE_ADDR addr_in_block; |
| |
| /* Make certain that this, and not the adjacent, function is |
| found. */ |
| if (!get_frame_address_in_block_if_available (this_frame, &addr_in_block)) |
| { |
| next_frame->prev_func.status = CC_UNAVAILABLE; |
| |
| frame_debug_printf ("this_frame=%d -> unavailable", |
| this_frame->level); |
| } |
| else |
| { |
| next_frame->prev_func.status = CC_VALUE; |
| next_frame->prev_func.addr = get_pc_function_start (addr_in_block); |
| |
| frame_debug_printf ("this_frame=%d -> %s", |
| this_frame->level, |
| hex_string (next_frame->prev_func.addr)); |
| } |
| } |
| |
| if (next_frame->prev_func.status == CC_UNAVAILABLE) |
| { |
| *pc = -1; |
| return false; |
| } |
| else |
| { |
| gdb_assert (next_frame->prev_func.status == CC_VALUE); |
| |
| *pc = next_frame->prev_func.addr; |
| return true; |
| } |
| } |
| |
| CORE_ADDR |
| get_frame_func (const frame_info_ptr &this_frame) |
| { |
| CORE_ADDR pc; |
| |
| if (!get_frame_func_if_available (this_frame, &pc)) |
| throw_error (NOT_AVAILABLE_ERROR, _("PC not available")); |
| |
| return pc; |
| } |
| |
| std::unique_ptr<readonly_detached_regcache> |
| frame_save_as_regcache (const frame_info_ptr &this_frame) |
| { |
| auto cooked_read = [this_frame] (int regnum, gdb::array_view<gdb_byte> buf) |
| { |
| if (!deprecated_frame_register_read (this_frame, regnum, buf.data ())) |
| return REG_UNAVAILABLE; |
| else |
| return REG_VALID; |
| }; |
| |
| std::unique_ptr<readonly_detached_regcache> regcache |
| (new readonly_detached_regcache (get_frame_arch (this_frame), cooked_read)); |
| |
| return regcache; |
| } |
| |
| void |
| frame_pop (const frame_info_ptr &this_frame) |
| { |
| frame_info_ptr prev_frame; |
| |
| if (get_frame_type (this_frame) == DUMMY_FRAME) |
| { |
| /* Popping a dummy frame involves restoring more than just registers. |
| dummy_frame_pop does all the work. */ |
| dummy_frame_pop (get_frame_id (this_frame), inferior_thread ()); |
| return; |
| } |
| |
| /* Ensure that we have a frame to pop to. */ |
| prev_frame = get_prev_frame_always (this_frame); |
| |
| if (!prev_frame) |
| error (_("Cannot pop the initial frame.")); |
| |
| /* Ignore TAILCALL_FRAME type frames, they were executed already before |
| entering THISFRAME. */ |
| prev_frame = skip_tailcall_frames (prev_frame); |
| |
| if (prev_frame == NULL) |
| error (_("Cannot find the caller frame.")); |
| |
| /* Make a copy of all the register values unwound from this frame. |
| Save them in a scratch buffer so that there isn't a race between |
| trying to extract the old values from the current regcache while |
| at the same time writing new values into that same cache. */ |
| std::unique_ptr<readonly_detached_regcache> scratch |
| = frame_save_as_regcache (prev_frame); |
| |
| /* FIXME: cagney/2003-03-16: It should be possible to tell the |
| target's register cache that it is about to be hit with a burst |
| register transfer and that the sequence of register writes should |
| be batched. The pair target_prepare_to_store() and |
| target_store_registers() kind of suggest this functionality. |
| Unfortunately, they don't implement it. Their lack of a formal |
| definition can lead to targets writing back bogus values |
| (arguably a bug in the target code mind). */ |
| /* Now copy those saved registers into the current regcache. */ |
| get_thread_regcache (inferior_thread ())->restore (scratch.get ()); |
| |
| /* We've made right mess of GDB's local state, just discard |
| everything. */ |
| reinit_frame_cache (); |
| } |
| |
| void |
| frame_register_unwind (const frame_info_ptr &next_frame, int regnum, |
| int *optimizedp, int *unavailablep, |
| enum lval_type *lvalp, CORE_ADDR *addrp, |
| int *realnump, gdb_byte *bufferp) |
| { |
| struct value *value; |
| |
| /* Require all but BUFFERP to be valid. A NULL BUFFERP indicates |
| that the value proper does not need to be fetched. */ |
| gdb_assert (optimizedp != NULL); |
| gdb_assert (lvalp != NULL); |
| gdb_assert (addrp != NULL); |
| gdb_assert (realnump != NULL); |
| /* gdb_assert (bufferp != NULL); */ |
| |
| value = frame_unwind_register_value (next_frame, regnum); |
| |
| gdb_assert (value != NULL); |
| |
| *optimizedp = value->optimized_out (); |
| *unavailablep = !value->entirely_available (); |
| *lvalp = value->lval (); |
| *addrp = value->address (); |
| if (*lvalp == lval_register) |
| *realnump = value->regnum (); |
| else |
| *realnump = -1; |
| |
| if (bufferp) |
| { |
| if (!*optimizedp && !*unavailablep) |
| memcpy (bufferp, value->contents_all ().data (), |
| value->type ()->length ()); |
| else |
| memset (bufferp, 0, value->type ()->length ()); |
| } |
| |
| /* Dispose of the new value. This prevents watchpoints from |
| trying to watch the saved frame pointer. */ |
| release_value (value); |
| } |
| |
| void |
| frame_unwind_register (const frame_info_ptr &next_frame, int regnum, gdb_byte *buf) |
| { |
| int optimized; |
| int unavailable; |
| CORE_ADDR addr; |
| int realnum; |
| enum lval_type lval; |
| |
| frame_register_unwind (next_frame, regnum, &optimized, &unavailable, |
| &lval, &addr, &realnum, buf); |
| |
| if (optimized) |
| throw_error (OPTIMIZED_OUT_ERROR, |
| _("Register %d was not saved"), regnum); |
| if (unavailable) |
| throw_error (NOT_AVAILABLE_ERROR, |
| _("Register %d is not available"), regnum); |
| } |
| |
| void |
| get_frame_register (const frame_info_ptr &frame, |
| int regnum, gdb_byte *buf) |
| { |
| frame_unwind_register (frame_info_ptr (frame->next), regnum, buf); |
| } |
| |
| struct value * |
| frame_unwind_register_value (const frame_info_ptr &next_frame, int regnum) |
| { |
| FRAME_SCOPED_DEBUG_ENTER_EXIT; |
| |
| gdb_assert (next_frame != NULL); |
| gdbarch *gdbarch = frame_unwind_arch (next_frame); |
| frame_debug_printf ("frame=%d, regnum=%d(%s)", |
| next_frame->level, regnum, |
| user_reg_map_regnum_to_name (gdbarch, regnum)); |
| |
| /* Find the unwinder. */ |
| if (next_frame->unwind == NULL) |
| frame_unwind_find_by_frame (next_frame, &next_frame->prologue_cache); |
| |
| /* Ask this frame to unwind its register. */ |
| value *value |
| = next_frame->unwind->prev_register (next_frame, |
| &next_frame->prologue_cache, regnum); |
| if (value == nullptr) |
| { |
| if (gdbarch_pseudo_register_read_value_p (gdbarch)) |
| { |
| /* This is a pseudo register, we don't know how how what raw registers |
| this pseudo register is made of. Ask the gdbarch to read the |
| value, it will itself ask the next frame to unwind the values of |
| the raw registers it needs to compose the value of the pseudo |
| register. */ |
| value = gdbarch_pseudo_register_read_value |
| (gdbarch, next_frame, regnum); |
| } |
| else if (gdbarch_pseudo_register_read_p (gdbarch)) |
| { |
| value = value::allocate_register (next_frame, regnum); |
| |
| /* Passing the current regcache is known to be broken, the pseudo |
| register value will be constructed using the current raw registers, |
| rather than reading them using NEXT_FRAME. Architectures should be |
| migrated to gdbarch_pseudo_register_read_value. */ |
| register_status status = gdbarch_pseudo_register_read |
| (gdbarch, get_thread_regcache (inferior_thread ()), regnum, |
| value->contents_writeable ().data ()); |
| if (status == REG_UNAVAILABLE) |
| value->mark_bytes_unavailable (0, value->type ()->length ()); |
| } |
| else |
| error (_("Can't unwind value of register %d (%s)"), regnum, |
| user_reg_map_regnum_to_name (gdbarch, regnum)); |
| } |
| |
| if (frame_debug) |
| { |
| string_file debug_file; |
| |
| gdb_printf (&debug_file, " ->"); |
| if (value->optimized_out ()) |
| { |
| gdb_printf (&debug_file, " "); |
| val_print_not_saved (&debug_file); |
| } |
| else |
| { |
| if (value->lval () == lval_register) |
| gdb_printf (&debug_file, " register=%d", value->regnum ()); |
| else if (value->lval () == lval_memory) |
| gdb_printf (&debug_file, " address=%s", |
| paddress (gdbarch, |
| value->address ())); |
| else |
| gdb_printf (&debug_file, " computed"); |
| |
| if (value->lazy ()) |
| gdb_printf (&debug_file, " lazy"); |
| else if (value->entirely_available ()) |
| { |
| int i; |
| gdb::array_view<const gdb_byte> buf = value->contents (); |
| |
| gdb_printf (&debug_file, " bytes="); |
| gdb_printf (&debug_file, "["); |
| for (i = 0; i < register_size (gdbarch, regnum); i++) |
| gdb_printf (&debug_file, "%02x", buf[i]); |
| gdb_printf (&debug_file, "]"); |
| } |
| else if (value->entirely_unavailable ()) |
| gdb_printf (&debug_file, " unavailable"); |
| else |
| gdb_printf (&debug_file, " partly unavailable"); |
| } |
| |
| frame_debug_printf ("%s", debug_file.c_str ()); |
| } |
| |
| return value; |
| } |
| |
| struct value * |
| get_frame_register_value (const frame_info_ptr &frame, int regnum) |
| { |
| return frame_unwind_register_value (frame_info_ptr (frame->next), regnum); |
| } |
| |
| LONGEST |
| frame_unwind_register_signed (const frame_info_ptr &next_frame, int regnum) |
| { |
| struct gdbarch *gdbarch = frame_unwind_arch (next_frame); |
| enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); |
| struct value *value = frame_unwind_register_value (next_frame, regnum); |
| |
| gdb_assert (value != NULL); |
| |
| if (value->optimized_out ()) |
| { |
| throw_error (OPTIMIZED_OUT_ERROR, |
| _("Register %d was not saved"), regnum); |
| } |
| if (!value->entirely_available ()) |
| { |
| throw_error (NOT_AVAILABLE_ERROR, |
| _("Register %d is not available"), regnum); |
| } |
| |
| LONGEST r = extract_signed_integer (value->contents_all (), byte_order); |
| |
| release_value (value); |
| return r; |
| } |
| |
| LONGEST |
| get_frame_register_signed (const frame_info_ptr &frame, int regnum) |
| { |
| return frame_unwind_register_signed (frame_info_ptr (frame->next), regnum); |
| } |
| |
| ULONGEST |
| frame_unwind_register_unsigned (const frame_info_ptr &next_frame, int regnum) |
| { |
| struct gdbarch *gdbarch = frame_unwind_arch (next_frame); |
| enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); |
| int size = register_size (gdbarch, regnum); |
| struct value *value = frame_unwind_register_value (next_frame, regnum); |
| |
| gdb_assert (value != NULL); |
| |
| if (value->optimized_out ()) |
| { |
| throw_error (OPTIMIZED_OUT_ERROR, |
| _("Register %d was not saved"), regnum); |
| } |
| if (!value->entirely_available ()) |
| { |
| throw_error (NOT_AVAILABLE_ERROR, |
| _("Register %d is not available"), regnum); |
| } |
| |
| ULONGEST r = extract_unsigned_integer (value->contents_all ().data (), |
| size, byte_order); |
| |
| release_value (value); |
| return r; |
| } |
| |
| ULONGEST |
| get_frame_register_unsigned (const frame_info_ptr &frame, int regnum) |
| { |
| return frame_unwind_register_unsigned (frame_info_ptr (frame->next), regnum); |
| } |
| |
| bool |
| read_frame_register_unsigned (const frame_info_ptr &frame, int regnum, |
| ULONGEST *val) |
| { |
| struct value *regval = get_frame_register_value (frame, regnum); |
| |
| if (!regval->optimized_out () |
| && regval->entirely_available ()) |
| { |
| struct gdbarch *gdbarch = get_frame_arch (frame); |
| enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); |
| int size = register_size (gdbarch, regval->regnum ()); |
| |
| *val = extract_unsigned_integer (regval->contents ().data (), size, |
| byte_order); |
| return true; |
| } |
| |
| return false; |
| } |
| |
| void |
| put_frame_register (const frame_info_ptr &next_frame, int regnum, |
| gdb::array_view<const gdb_byte> buf) |
| { |
| gdbarch *gdbarch = frame_unwind_arch (next_frame); |
| int realnum; |
| int optim; |
| int unavail; |
| enum lval_type lval; |
| CORE_ADDR addr; |
| int size = register_size (gdbarch, regnum); |
| |
| gdb_assert (buf.size () == size); |
| |
| frame_register_unwind (next_frame, regnum, &optim, &unavail, &lval, &addr, |
| &realnum, nullptr); |
| if (optim) |
| error (_("Attempt to assign to a register that was not saved.")); |
| switch (lval) |
| { |
| case lval_memory: |
| { |
| write_memory (addr, buf.data (), size); |
| break; |
| } |
| case lval_register: |
| /* Not sure if that's always true... but we have a problem if not. */ |
| gdb_assert (size == register_size (gdbarch, realnum)); |
| |
| if (realnum < gdbarch_num_regs (gdbarch) |
| || !gdbarch_pseudo_register_write_p (gdbarch)) |
| get_thread_regcache (inferior_thread ())->cooked_write (realnum, buf); |
| else |
| gdbarch_pseudo_register_write (gdbarch, next_frame, realnum, buf); |
| break; |
| default: |
| error (_("Attempt to assign to an unmodifiable value.")); |
| } |
| } |
| |
| /* This function is deprecated. Use get_frame_register_value instead, |
| which provides more accurate information. |
| |
| Find and return the value of REGNUM for the specified stack frame. |
| The number of bytes copied is REGISTER_SIZE (REGNUM). |
| |
| Returns 0 if the register value could not be found. */ |
| |
| bool |
| deprecated_frame_register_read (const frame_info_ptr &frame, int regnum, |
| gdb_byte *myaddr) |
| { |
| int optimized; |
| int unavailable; |
| enum lval_type lval; |
| CORE_ADDR addr; |
| int realnum; |
| |
| frame_register_unwind (get_next_frame_sentinel_okay (frame), regnum, |
| &optimized, &unavailable, &lval, &addr, &realnum, |
| myaddr); |
| |
| return !optimized && !unavailable; |
| } |
| |
| bool |
| get_frame_register_bytes (const frame_info_ptr &next_frame, int regnum, |
| CORE_ADDR offset, gdb::array_view<gdb_byte> buffer, |
| int *optimizedp, int *unavailablep) |
| { |
| gdbarch *gdbarch = frame_unwind_arch (next_frame); |
| |
| /* Skip registers wholly inside of OFFSET. */ |
| while (offset >= register_size (gdbarch, regnum)) |
| { |
| offset -= register_size (gdbarch, regnum); |
| regnum++; |
| } |
| |
| /* Ensure that we will not read beyond the end of the register file. |
| This can only ever happen if the debug information is bad. */ |
| int maxsize = -offset; |
| int numregs = gdbarch_num_cooked_regs (gdbarch); |
| for (int i = regnum; i < numregs; i++) |
| { |
| int thissize = register_size (gdbarch, i); |
| |
| if (thissize == 0) |
| break; /* This register is not available on this architecture. */ |
| maxsize += thissize; |
| } |
| |
| if (buffer.size () > maxsize) |
| error (_("Bad debug information detected: " |
| "Attempt to read %zu bytes from registers."), buffer.size ()); |
| |
| /* Copy the data. */ |
| while (!buffer.empty ()) |
| { |
| int curr_len = std::min<int> (register_size (gdbarch, regnum) - offset, |
| buffer.size ()); |
| |
| if (curr_len == register_size (gdbarch, regnum)) |
| { |
| enum lval_type lval; |
| CORE_ADDR addr; |
| int realnum; |
| |
| frame_register_unwind (next_frame, regnum, optimizedp, unavailablep, |
| &lval, &addr, &realnum, buffer.data ()); |
| if (*optimizedp || *unavailablep) |
| return false; |
| } |
| else |
| { |
| value *value = frame_unwind_register_value (next_frame, regnum); |
| gdb_assert (value != NULL); |
| *optimizedp = value->optimized_out (); |
| *unavailablep = !value->entirely_available (); |
| |
| if (*optimizedp || *unavailablep) |
| { |
| release_value (value); |
| return false; |
| } |
| |
| copy (value->contents_all ().slice (offset, curr_len), |
| buffer.slice (0, curr_len)); |
| release_value (value); |
| } |
| |
| buffer = buffer.slice (curr_len); |
| offset = 0; |
| regnum++; |
| } |
| |
| *optimizedp = 0; |
| *unavailablep = 0; |
| |
| return true; |
| } |
| |
| void |
| put_frame_register_bytes (const frame_info_ptr &next_frame, int regnum, |
| CORE_ADDR offset, |
| gdb::array_view<const gdb_byte> buffer) |
| { |
| gdbarch *gdbarch = frame_unwind_arch (next_frame); |
| |
| /* Skip registers wholly inside of OFFSET. */ |
| while (offset >= register_size (gdbarch, regnum)) |
| { |
| offset -= register_size (gdbarch, regnum); |
| regnum++; |
| } |
| |
| /* Copy the data. */ |
| while (!buffer.empty ()) |
| { |
| int curr_len = std::min<int> (register_size (gdbarch, regnum) - offset, |
| buffer.size ()); |
| |
| if (curr_len == register_size (gdbarch, regnum)) |
| put_frame_register (next_frame, regnum, buffer.slice (0, curr_len)); |
| else |
| { |
| value *value = frame_unwind_register_value (next_frame, regnum); |
| gdb_assert (value != nullptr); |
| |
| copy (buffer.slice (0, curr_len), |
| value->contents_writeable ().slice (offset, curr_len)); |
| put_frame_register (next_frame, regnum, value->contents_raw ()); |
| release_value (value); |
| } |
| |
| buffer = buffer.slice (curr_len); |
| offset = 0; |
| regnum++; |
| } |
| } |
| |
| /* Create a sentinel frame. |
| |
| See frame_id_build_sentinel for the description of STACK_ADDR and |
| CODE_ADDR. */ |
| |
| static frame_info_ptr |
| create_sentinel_frame (program_space *pspace, address_space *aspace, |
| regcache *regcache, CORE_ADDR stack_addr, |
| CORE_ADDR code_addr) |
| { |
| frame_info *frame = FRAME_OBSTACK_ZALLOC (struct frame_info); |
| |
| frame->level = -1; |
| frame->pspace = pspace; |
| frame->aspace = aspace; |
| /* Explicitly initialize the sentinel frame's cache. Provide it |
| with the underlying regcache. In the future additional |
| information, such as the frame's thread will be added. */ |
| frame->prologue_cache = sentinel_frame_cache (regcache); |
| /* For the moment there is only one sentinel frame implementation. */ |
| frame->unwind = &sentinel_frame_unwind; |
| /* Link this frame back to itself. The frame is self referential |
| (the unwound PC is the same as the pc), so make it so. */ |
| frame->next = frame; |
| /* The sentinel frame has a special ID. */ |
| frame->this_id.p = frame_id_status::COMPUTED; |
| frame->this_id.value = frame_id_build_sentinel (stack_addr, code_addr); |
| |
| bool added = frame_stash_add (frame); |
| gdb_assert (added); |
| |
| frame_debug_printf (" -> %s", frame->to_string ().c_str ()); |
| |
| return frame_info_ptr (frame); |
| } |
| |
| /* Cache for frame addresses already read by gdb. Valid only while |
| inferior is stopped. Control variables for the frame cache should |
| be local to this module. */ |
| |
| static struct obstack frame_cache_obstack; |
| |
| void * |
| frame_obstack_zalloc (unsigned long size) |
| { |
| void *data = obstack_alloc (&frame_cache_obstack, size); |
| |
| memset (data, 0, size); |
| return data; |
| } |
| |
| static frame_info_ptr get_prev_frame_always_1 (const frame_info_ptr &this_frame); |
| |
| frame_info_ptr |
| get_current_frame (void) |
| { |
| frame_info_ptr current_frame; |
| |
| /* First check, and report, the lack of registers. Having GDB |
| report "No stack!" or "No memory" when the target doesn't even |
| have registers is very confusing. Besides, "printcmd.exp" |
| explicitly checks that ``print $pc'' with no registers prints "No |
| registers". */ |
| if (!target_has_registers ()) |
| error (_("No registers.")); |
| if (!target_has_stack ()) |
| error (_("No stack.")); |
| if (!target_has_memory ()) |
| error (_("No memory.")); |
| /* Traceframes are effectively a substitute for the live inferior. */ |
| if (get_traceframe_number () < 0) |
| validate_registers_access (); |
| |
| if (sentinel_frame == NULL) |
| sentinel_frame = |
| create_sentinel_frame (current_program_space, |
| current_inferior ()->aspace.get (), |
| get_thread_regcache (inferior_thread ()), |
| 0, 0).get (); |
| |
| /* Set the current frame before computing the frame id, to avoid |
| recursion inside compute_frame_id, in case the frame's |
| unwinder decides to do a symbol lookup (which depends on the |
| selected frame's block). |
| |
| This call must always succeed. In particular, nothing inside |
| get_prev_frame_always_1 should try to unwind from the |
| sentinel frame, because that could fail/throw, and we always |
| want to leave with the current frame created and linked in -- |
| we should never end up with the sentinel frame as outermost |
| frame. */ |
| current_frame = get_prev_frame_always_1 (frame_info_ptr (sentinel_frame)); |
| gdb_assert (current_frame != NULL); |
| |
| return current_frame; |
| } |
| |
| /* The "selected" stack frame is used by default for local and arg |
| access. |
| |
| The "single source of truth" for the selected frame is the |
| SELECTED_FRAME_ID / SELECTED_FRAME_LEVEL pair. |
| |
| Frame IDs can be saved/restored across reinitializing the frame |
| cache, while frame_info pointers can't (frame_info objects are |
| invalidated). If we know the corresponding frame_info object, it |
| is cached in SELECTED_FRAME. |
| |
| If SELECTED_FRAME_ID / SELECTED_FRAME_LEVEL are null_frame_id / -1, |
| and the target has stack and is stopped, the selected frame is the |
| current (innermost) target frame. SELECTED_FRAME_ID is never the ID |
| of the current (innermost) target frame. SELECTED_FRAME_LEVEL may |
| only be 0 if the selected frame is a user-created one (created and |
| selected through the "select-frame view" command), in which case |
| SELECTED_FRAME_ID is the frame id derived from the user-provided |
| addresses. |
| |
| If SELECTED_FRAME_ID / SELECTED_FRAME_LEVEL are null_frame_id / -1, |
| and the target has no stack or is executing, then there's no |
| selected frame. */ |
| static frame_id selected_frame_id = null_frame_id; |
| static int selected_frame_level = -1; |
| |
| /* See frame.h. This definition should come before any definition of a static |
| frame_info_ptr, to ensure that frame_list is destroyed after any static |
| frame_info_ptr. This is necessary because the destructor of frame_info_ptr |
| uses frame_list. */ |
| |
| intrusive_list<frame_info_ptr> frame_info_ptr::frame_list; |
| |
| /* The cached frame_info object pointing to the selected frame. |
| Looked up on demand by get_selected_frame. */ |
| static frame_info_ptr selected_frame; |
| |
| /* See frame.h. */ |
| |
| void |
| save_selected_frame (frame_id *frame_id, int *frame_level) |
| noexcept |
| { |
| *frame_id = selected_frame_id; |
| *frame_level = selected_frame_level; |
| } |
| |
| /* See frame.h. */ |
| |
| void |
| restore_selected_frame (frame_id frame_id, int frame_level) |
| noexcept |
| { |
| /* Unless it is a user-created frame, save_selected_frame never returns |
| level == 0, so we shouldn't see it here either. */ |
| gdb_assert (frame_level != 0 || frame_id.user_created_p); |
| |
| /* FRAME_ID can be null_frame_id only IFF frame_level is -1. */ |
| gdb_assert ((frame_level == -1 && !frame_id_p (frame_id)) |
| || (frame_level != -1 && frame_id_p (frame_id))); |
| |
| selected_frame_id = frame_id; |
| selected_frame_level = frame_level; |
| |
| /* Will be looked up later by get_selected_frame. */ |
| selected_frame = nullptr; |
| } |
| |
| /* Lookup the frame_info object for the selected frame FRAME_ID / |
| FRAME_LEVEL and cache the result. |
| |
| If FRAME_LEVEL > 0 and the originally selected frame isn't found, |
| warn and select the innermost (current) frame. */ |
| |
| static void |
| lookup_selected_frame (struct frame_id a_frame_id, int frame_level) |
| { |
| frame_info_ptr frame = NULL; |
| int count; |
| |
| /* This either means there was no selected frame, or the selected |
| frame was the current frame. In either case, select the current |
| frame. */ |
| if (frame_level == -1) |
| { |
| select_frame (get_current_frame ()); |
| return; |
| } |
| |
| /* This means the selected frame was a user-created one. Create a new one |
| using the user-provided addresses, which happen to be in the frame id. */ |
| if (frame_level == 0) |
| { |
| gdb_assert (a_frame_id.user_created_p); |
| select_frame (create_new_frame (a_frame_id)); |
| return; |
| } |
| |
| /* select_frame never saves 0 in SELECTED_FRAME_LEVEL, so we |
| shouldn't see it here. */ |
| gdb_assert (frame_level > 0); |
| |
| /* Restore by level first, check if the frame id is the same as |
| expected. If that fails, try restoring by frame id. If that |
| fails, nothing to do, just warn the user. */ |
| |
| count = frame_level; |
| frame = find_relative_frame (get_current_frame (), &count); |
| if (count == 0 |
| && frame != NULL |
| /* The frame ids must match - either both valid or both |
| outer_frame_id. The latter case is not failsafe, but since |
| it's highly unlikely the search by level finds the wrong |
| frame, it's 99.9(9)% of the time (for all practical purposes) |
| safe. */ |
| && get_frame_id (frame) == a_frame_id) |
| { |
| /* Cool, all is fine. */ |
| select_frame (frame); |
| return; |
| } |
| |
| frame = frame_find_by_id (a_frame_id); |
| if (frame != NULL) |
| { |
| /* Cool, refound it. */ |
| select_frame (frame); |
| return; |
| } |
| |
| /* Nothing else to do, the frame layout really changed. Select the |
| innermost stack frame. */ |
| select_frame (get_current_frame ()); |
| |
| /* Warn the user. */ |
| if (frame_level > 0 && !current_uiout->is_mi_like_p ()) |
| { |
| warning (_("Couldn't restore frame #%d in " |
| "current thread. Bottom (innermost) frame selected:"), |
| frame_level); |
| /* For MI, we should probably have a notification about current |
| frame change. But this error is not very likely, so don't |
| bother for now. */ |
| print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1); |
| } |
| } |
| |
| bool |
| has_stack_frames () |
| { |
| if (!target_has_registers () || !target_has_stack () |
| || !target_has_memory ()) |
| return false; |
| |
| /* Traceframes are effectively a substitute for the live inferior. */ |
| if (get_traceframe_number () < 0) |
| { |
| /* No current inferior, no frame. */ |
| if (inferior_ptid == null_ptid) |
| return false; |
| |
| thread_info *tp = inferior_thread (); |
| /* Don't try to read from a dead thread. */ |
| if (tp->state == THREAD_EXITED) |
| return false; |
| |
| /* ... or from a spinning thread. */ |
| if (tp->executing ()) |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /* See frame.h. */ |
| |
| frame_info_ptr |
| get_selected_frame (const char *message) |
| { |
| if (selected_frame == NULL) |
| { |
| if (message != NULL && !has_stack_frames ()) |
| error (("%s"), message); |
| |
| lookup_selected_frame (selected_frame_id, selected_frame_level); |
| } |
| /* There is always a frame. */ |
| gdb_assert (selected_frame != NULL); |
| return selected_frame; |
| } |
| |
| /* This is a variant of get_selected_frame() which can be called when |
| the inferior does not have a frame; in that case it will return |
| NULL instead of calling error(). */ |
| |
| frame_info_ptr |
| deprecated_safe_get_selected_frame (void) |
| { |
| if (!has_stack_frames ()) |
| return NULL; |
| return get_selected_frame (NULL); |
| } |
| |
| /* Invalidate the selected frame. */ |
| |
| static void |
| invalidate_selected_frame () |
| { |
| selected_frame = nullptr; |
| selected_frame_level = -1; |
| selected_frame_id = null_frame_id; |
| } |
| |
| /* See frame.h. */ |
| |
| void |
| select_frame (const frame_info_ptr &fi) |
| { |
| gdb_assert (fi != nullptr); |
| |
| selected_frame = fi; |
| selected_frame_level = frame_relative_level (fi); |
| |
| /* If the frame is a user-created one, save its level and frame id just like |
| any other non-level-0 frame. */ |
| if (selected_frame_level == 0 && !fi->this_id.value.user_created_p) |
| { |
| /* Treat the current frame especially -- we want to always |
| save/restore it without warning, even if the frame ID changes |
| (see lookup_selected_frame). E.g.: |
| |
| // The current frame is selected, the target had just stopped. |
| { |
| scoped_restore_selected_frame restore_frame; |
| some_operation_that_changes_the_stack (); |
| } |
| // scoped_restore_selected_frame's dtor runs, but the |
| // original frame_id can't be found. No matter whether it |
| // is found or not, we still end up with the now-current |
| // frame selected. Warning in lookup_selected_frame in this |
| // case seems pointless. |
| |
| Also get_frame_id may access the target's registers/memory, |
| and thus skipping get_frame_id optimizes the common case. |
| |
| Saving the selected frame this way makes get_selected_frame |
| and restore_current_frame return/re-select whatever frame is |
| the innermost (current) then. */ |
| selected_frame_level = -1; |
| selected_frame_id = null_frame_id; |
| } |
| else |
| selected_frame_id = get_frame_id (fi); |
| |
| /* NOTE: cagney/2002-05-04: FI can be NULL. This occurs when the |
| frame is being invalidated. */ |
| |
| /* FIXME: kseitz/2002-08-28: It would be nice to call |
| selected_frame_level_changed_event() right here, but due to limitations |
| in the current interfaces, we would end up flooding UIs with events |
| because select_frame() is used extensively internally. |
| |
| Once we have frame-parameterized frame (and frame-related) commands, |
| the event notification can be moved here, since this function will only |
| be called when the user's selected frame is being changed. */ |
| |
| /* Ensure that symbols for this frame are read in. Also, determine the |
| source language of this frame, and switch to it if desired. */ |
| if (fi) |
| { |
| CORE_ADDR pc; |
| |
| /* We retrieve the frame's symtab by using the frame PC. |
| However we cannot use the frame PC as-is, because it usually |
| points to the instruction following the "call", which is |
| sometimes the first instruction of another function. So we |
| rely on get_frame_address_in_block() which provides us with a |
| PC which is guaranteed to be inside the frame's code |
| block. */ |
| if (get_frame_address_in_block_if_available (fi, &pc)) |
| { |
| struct compunit_symtab *cust = find_pc_compunit_symtab (pc); |
| |
| if (cust != NULL |
| && cust->language () != current_language->la_language |
| && cust->language () != language_unknown |
| && language_mode == language_mode_auto) |
| set_language (cust->language ()); |
| } |
| } |
| } |
| |
| /* Create an arbitrary (i.e. address specified by user) or innermost frame. |
| Always returns a non-NULL value. */ |
| |
| static frame_info_ptr |
| create_new_frame (frame_id id) |
| { |
| gdb_assert (id.user_created_p); |
| gdb_assert (id.stack_status == frame_id_stack_status::FID_STACK_VALID); |
| gdb_assert (id.code_addr_p); |
| |
| frame_debug_printf ("stack_addr=%s, core_addr=%s", |
| hex_string (id.stack_addr), hex_string (id.code_addr)); |
| |
| /* Avoid creating duplicate frames, search for an existing frame with that id |
| in the stash. */ |
| frame_info_ptr frame = frame_stash_find (id); |
| if (frame != nullptr) |
| return frame; |
| |
| frame_info *fi = FRAME_OBSTACK_ZALLOC (struct frame_info); |
| |
| fi->next = create_sentinel_frame (current_program_space, |
| current_inferior ()->aspace.get (), |
| get_thread_regcache (inferior_thread ()), |
| id.stack_addr, id.code_addr).get (); |
| |
| /* Set/update this frame's cached PC value, found in the next frame. |
| Do this before looking for this frame's unwinder. A sniffer is |
| very likely to read this, and the corresponding unwinder is |
| entitled to rely that the PC doesn't magically change. */ |
| fi->next->prev_pc.value = id.code_addr; |
| fi->next->prev_pc.status = CC_VALUE; |
| |
| /* We currently assume that frame chain's can't cross spaces. */ |
| fi->pspace = fi->next->pspace; |
| fi->aspace = fi->next->aspace; |
| |
| /* Select/initialize both the unwind function and the frame's type |
| based on the PC. */ |
| frame_unwind_find_by_frame (frame_info_ptr (fi), &fi->prologue_cache); |
| |
| fi->this_id.p = frame_id_status::COMPUTED; |
| fi->this_id.value = id; |
| |
| bool added = frame_stash_add (fi); |
| gdb_assert (added); |
| |
| frame_debug_printf (" -> %s", fi->to_string ().c_str ()); |
| |
| return frame_info_ptr (fi); |
| } |
| |
| frame_info_ptr |
| create_new_frame (CORE_ADDR stack, CORE_ADDR pc) |
| { |
| frame_id id = frame_id_build (stack, pc); |
| id.user_created_p = 1; |
| |
| return create_new_frame (id); |
| } |
| |
| /* Return the frame that THIS_FRAME calls (NULL if THIS_FRAME is the |
| innermost frame). Be careful to not fall off the bottom of the |
| frame chain and onto the sentinel frame. */ |
| |
| frame_info_ptr |
| get_next_frame (const frame_info_ptr &this_frame) |
| { |
| if (this_frame->level > 0) |
| return frame_info_ptr (this_frame->next); |
| else |
| return NULL; |
| } |
| |
| /* Return the frame that THIS_FRAME calls. If THIS_FRAME is the |
| innermost (i.e. current) frame, return the sentinel frame. Thus, |
| unlike get_next_frame(), NULL will never be returned. */ |
| |
| frame_info_ptr |
| get_next_frame_sentinel_okay (const frame_info_ptr &this_frame) |
| { |
| gdb_assert (this_frame != NULL); |
| |
| /* Note that, due to the manner in which the sentinel frame is |
| constructed, this_frame->next still works even when this_frame |
| is the sentinel frame. But we disallow it here anyway because |
| calling get_next_frame_sentinel_okay() on the sentinel frame |
| is likely a coding error. */ |
| if (this_frame->this_id.p == frame_id_status::COMPUTED) |
| gdb_assert (!is_sentinel_frame_id (this_frame->this_id.value)); |
| |
| return frame_info_ptr (this_frame->next); |
| } |
| |
| /* Observer for the target_changed event. */ |
| |
| static void |
| frame_observer_target_changed (struct target_ops *target) |
| { |
| reinit_frame_cache (); |
| } |
| |
| /* Flush the entire frame cache. */ |
| |
| void |
| reinit_frame_cache (void) |
| { |
| ++frame_cache_generation; |
| |
| if (htab_elements (frame_stash) > 0) |
| annotate_frames_invalid (); |
| |
| invalidate_selected_frame (); |
| |
| /* Invalidate cache. */ |
| if (sentinel_frame != nullptr) |
| { |
| /* If frame 0's id is not computed, it is not in the frame stash, so its |
| dealloc functions will not be called when emptying the frame stash. |
| Call frame_info_del manually in that case. */ |
| frame_info *current_frame = sentinel_frame->prev; |
| if (current_frame != nullptr |
| && current_frame->this_id.p == frame_id_status::NOT_COMPUTED) |
| frame_info_del (current_frame); |
| |
| sentinel_frame = nullptr; |
| } |
| |
| frame_stash_invalidate (); |
| |
| /* Since we can't really be sure what the first object allocated was. */ |
| obstack_free (&frame_cache_obstack, 0); |
| obstack_init (&frame_cache_obstack); |
| |
| for (frame_info_ptr &iter : frame_info_ptr::frame_list) |
| iter.invalidate (); |
| |
| frame_debug_printf ("generation=%d", frame_cache_generation); |
| } |
| |
| /* Find where a register is saved (in memory or another register). |
| The result of frame_register_unwind is just where it is saved |
| relative to this particular frame. */ |
| |
| static void |
| frame_register_unwind_location (const frame_info_ptr &initial_this_frame, |
| int regnum, int *optimizedp, lval_type *lvalp, |
| CORE_ADDR *addrp, int *realnump) |
| { |
| gdb_assert (initial_this_frame == nullptr || initial_this_frame->level >= 0); |
| |
| frame_info_ptr this_frame = initial_this_frame; |
| while (this_frame != NULL) |
| { |
| int unavailable; |
| |
| frame_register_unwind (this_frame, regnum, optimizedp, &unavailable, |
| lvalp, addrp, realnump, NULL); |
| |
| if (*optimizedp) |
| break; |
| |
| if (*lvalp != lval_register) |
| break; |
| |
| regnum = *realnump; |
| this_frame = get_next_frame (this_frame); |
| } |
| } |
| |
| /* Get the previous raw frame, and check that it is not identical to |
| same other frame frame already in the chain. If it is, there is |
| most likely a stack cycle, so we discard it, and mark THIS_FRAME as |
| outermost, with UNWIND_SAME_ID stop reason. Unlike the other |
| validity tests, that compare THIS_FRAME and the next frame, we do |
| this right after creating the previous frame, to avoid ever ending |
| up with two frames with the same id in the frame chain. |
| |
| There is however, one case where this cycle detection is not desirable, |
| when asking for the previous frame of an inline frame, in this case, if |
| the previous frame is a duplicate and we return nullptr then we will be |
| unable to calculate the frame_id of the inline frame, this in turn |
| causes inline_frame_this_id() to fail. So for inline frames (and only |
| for inline frames), the previous frame will always be returned, even when it |
| has a duplicate frame_id. We're not worried about cycles in the frame |
| chain as, if the previous frame returned here has a duplicate frame_id, |
| then the frame_id of the inline frame, calculated based off the frame_id |
| of the previous frame, should also be a duplicate. */ |
| |
| static frame_info_ptr |
| get_prev_frame_maybe_check_cycle (const frame_info_ptr &this_frame) |
| { |
| frame_info_ptr prev_frame = get_prev_frame_raw (this_frame); |
| |
| /* Don't compute the frame id of the current frame yet. Unwinding |
| the sentinel frame can fail (e.g., if the thread is gone and we |
| can't thus read its registers). If we let the cycle detection |
| code below try to compute a frame ID, then an error thrown from |
| within the frame ID computation would result in the sentinel |
| frame as outermost frame, which is bogus. Instead, we'll compute |
| the current frame's ID lazily in get_frame_id. Note that there's |
| no point in doing cycle detection when there's only one frame, so |
| nothing is lost here. */ |
| if (prev_frame->level == 0) |
| return prev_frame; |
| |
| unsigned int entry_generation = get_frame_cache_generation (); |
| |
| try |
| { |
| compute_frame_id (prev_frame); |
| |
| bool cycle_detection_p = get_frame_type (this_frame) != INLINE_FRAME; |
| |
| /* This assert checks GDB's state with respect to calculating the |
| frame-id of THIS_FRAME, in the case where THIS_FRAME is an inline |
| frame. |
| |
| If THIS_FRAME is frame #0, and is an inline frame, then we put off |
| calculating the frame_id until we specifically make a call to |
| get_frame_id(). As a result we can enter this function in two |
| possible states. If GDB asked for the previous frame of frame #0 |
| then THIS_FRAME will be frame #0 (an inline frame), and the |
| frame_id will be in the NOT_COMPUTED state. However, if GDB asked |
| for the frame_id of frame #0, then, as getting the frame_id of an |
| inline frame requires us to get the frame_id of the previous |
| frame, we will still end up in here, and the frame_id status will |
| be COMPUTING. |
| |
| If, instead, THIS_FRAME is at a level greater than #0 then things |
| are simpler. For these frames we immediately compute the frame_id |
| when the frame is initially created, and so, for those frames, we |
| will always enter this function with the frame_id status of |
| COMPUTING. */ |
| gdb_assert (cycle_detection_p |
| || (this_frame->level > 0 |
| && (this_frame->this_id.p |
| == frame_id_status::COMPUTING)) |
| || (this_frame->level == 0 |
| && (this_frame->this_id.p |
| != frame_id_status::COMPUTED))); |
| |
| /* We must do the CYCLE_DETECTION_P check after attempting to add |
| PREV_FRAME into the cache; if PREV_FRAME is unique then we do want |
| it in the cache, but if it is a duplicate and CYCLE_DETECTION_P is |
| false, then we don't want to unlink it. */ |
| if (!frame_stash_add (prev_frame.get ()) && cycle_detection_p) |
| { |
| /* Another frame with the same id was already in the stash. We just |
| detected a cycle. */ |
| frame_debug_printf (" -> nullptr // this frame has same ID"); |
| |
| this_frame->stop_reason = UNWIND_SAME_ID; |
| /* Unlink. */ |
| prev_frame->next = NULL; |
| this_frame->prev = NULL; |
| prev_frame = NULL; |
| } |
| } |
| catch (const gdb_exception &ex) |
| { |
| if (get_frame_cache_generation () == entry_generation) |
| { |
| prev_frame->next = NULL; |
| this_frame->prev = NULL; |
| } |
| |
| throw; |
| } |
| |
| return prev_frame; |
| } |
| |
| /* Helper function for get_prev_frame_always, this is called inside a |
| TRY_CATCH block. Return the frame that called THIS_FRAME or NULL if |
| there is no such frame. This may throw an exception. */ |
| |
| static frame_info_ptr |
| get_prev_frame_always_1 (const frame_info_ptr &this_frame) |
| { |
| FRAME_SCOPED_DEBUG_ENTER_EXIT; |
| |
| gdb_assert (this_frame != NULL); |
| |
| if (frame_debug) |
| { |
| if (this_frame != NULL) |
| frame_debug_printf ("this_frame=%d", this_frame->level); |
| else |
| frame_debug_printf ("this_frame=nullptr"); |
| } |
| |
| struct gdbarch *gdbarch = get_frame_arch (this_frame); |
| |
| /* Only try to do the unwind once. */ |
| if (this_frame->prev_p) |
| { |
| if (this_frame->prev != nullptr) |
| frame_debug_printf (" -> %s // cached", |
| this_frame->prev->to_string ().c_str ()); |
| else |
| frame_debug_printf |
| (" -> nullptr // %s // cached", |
| frame_stop_reason_symbol_string (this_frame->stop_reason)); |
| return frame_info_ptr (this_frame->prev); |
| } |
| |
| /* If the frame unwinder hasn't been selected yet, we must do so |
| before setting prev_p; otherwise the check for misbehaved |
| sniffers will think that this frame's sniffer tried to unwind |
| further (see frame_cleanup_after_sniffer). */ |
| if (this_frame->unwind == NULL) |
| frame_unwind_find_by_frame (this_frame, &this_frame->prologue_cache); |
| |
| this_frame->prev_p = true; |
| this_frame->stop_reason = UNWIND_NO_REASON; |
| |
| /* If we are unwinding from an inline frame, all of the below tests |
| were already performed when we unwound from the next non-inline |
| frame. We must skip them, since we can not get THIS_FRAME's ID |
| until we have unwound all the way down to the previous non-inline |
| frame. */ |
| if (get_frame_type (this_frame) == INLINE_FRAME) |
| return get_prev_frame_maybe_check_cycle (this_frame); |
| |
| /* If this_frame is the current frame, then compute and stash its |
| frame id prior to fetching and computing the frame id of the |
| previous frame. Otherwise, the cycle detection code in |
| get_prev_frame_if_no_cycle() will not work correctly. When |
| get_frame_id() is called later on, an assertion error will be |
| triggered in the event of a cycle between the current frame and |
| its previous frame. |
| |
| Note we do this after the INLINE_FRAME check above. That is |
| because the inline frame's frame id computation needs to fetch |
| the frame id of its previous real stack frame. I.e., we need to |
| avoid recursion in that case. This is OK since we're sure the |
| inline frame won't create a cycle with the real stack frame. See |
| inline_frame_this_id. */ |
| if (this_frame->level == 0) |
| get_frame_id (this_frame); |
| |
| /* Check that this frame is unwindable. If it isn't, don't try to |
| unwind to the prev frame. */ |
| this_frame->stop_reason |
| = this_frame->unwind->stop_reason (this_frame, |
| &this_frame->prologue_cache); |
| |
| if (this_frame->stop_reason != UNWIND_NO_REASON) |
| { |
| frame_debug_printf |
| (" -> nullptr // %s", |
| frame_stop_reason_symbol_string (this_frame->stop_reason)); |
| return NULL; |
| } |
| |
| /* Check that this frame's ID isn't inner to (younger, below, next) |
| the next frame. This happens when a frame unwind goes backwards. |
| This check is valid only if this frame and the next frame are NORMAL. |
| See the comment at frame_id_inner for details. */ |
| if (get_frame_type (this_frame) == NORMAL_FRAME |
| && this_frame->next->unwind->type == NORMAL_FRAME |
| && frame_id_inner (get_frame_arch (frame_info_ptr (this_frame->next)), |
| get_frame_id (this_frame), |
| get_frame_id (frame_info_ptr (this_frame->next)))) |
| { |
| CORE_ADDR this_pc_in_block; |
| struct minimal_symbol *morestack_msym; |
| const char *morestack_name = NULL; |
| |
| /* gcc -fsplit-stack __morestack can continue the stack anywhere. */ |
| this_pc_in_block = get_frame_address_in_block (this_frame); |
| morestack_msym = lookup_minimal_symbol_by_pc (this_pc_in_block).minsym; |
| if (morestack_msym) |
| morestack_name = morestack_msym->linkage_name (); |
| if (!morestack_name || strcmp (morestack_name, "__morestack") != 0) |
| { |
| frame_debug_printf (" -> nullptr // this frame ID is inner"); |
| this_frame->stop_reason = UNWIND_INNER_ID; |
| return NULL; |
| } |
| } |
| |
| /* Check that this and the next frame do not unwind the PC register |
| to the same memory location. If they do, then even though they |
| have different frame IDs, the new frame will be bogus; two |
| functions can't share a register save slot for the PC. This can |
| happen when the prologue analyzer finds a stack adjustment, but |
| no PC save. |
| |
| This check does assume that the "PC register" is roughly a |
| traditional PC, even if the gdbarch_unwind_pc method adjusts |
| it (we do not rely on the value, only on the unwound PC being |
| dependent on this value). A potential improvement would be |
| to have the frame prev_pc method and the gdbarch unwind_pc |
| method set the same lval and location information as |
| frame_register_unwind. */ |
| if (this_frame->level > 0 |
| && gdbarch_pc_regnum (gdbarch) >= 0 |
| && get_frame_type (this_frame) == NORMAL_FRAME |
| && (get_frame_type (frame_info_ptr (this_frame->next)) == NORMAL_FRAME |
| || get_frame_type (frame_info_ptr (this_frame->next)) == INLINE_FRAME)) |
| { |
| int optimized, realnum, nrealnum; |
| enum lval_type lval, nlval; |
| CORE_ADDR addr, naddr; |
| |
| frame_register_unwind_location (this_frame, |
| gdbarch_pc_regnum (gdbarch), |
| &optimized, &lval, &addr, &realnum); |
| frame_register_unwind_location (get_next_frame (this_frame), |
| gdbarch_pc_regnum (gdbarch), |
| &optimized, &nlval, &naddr, &nrealnum); |
| |
| if ((lval == lval_memory && lval == nlval && addr == naddr) |
| || (lval == lval_register && lval == nlval && realnum == nrealnum)) |
| { |
| frame_debug_printf (" -> nullptr // no saved PC"); |
| this_frame->stop_reason = UNWIND_NO_SAVED_PC; |
| this_frame->prev = NULL; |
| return NULL; |
| } |
| } |
| |
| /* Ensure we can unwind the program counter of THIS_FRAME. */ |
| try |
| { |
| /* Calling frame_unwind_pc for the sentinel frame relies on the |
| current_frame being set, which at this point it might not be if we |
| are in the process of setting the current_frame after a stop (see |
| get_current_frame). |
| |
| The point of this check is to ensure that the unwinder for |
| THIS_FRAME can actually unwind the $pc, which we assume the |
| sentinel frame unwinder can always do (it's just a read from the |
| machine state), so we only call frame_unwind_pc for frames other |
| than the sentinel (level -1) frame. |
| |
| Additionally, we don't actually care about the value of the |
| unwound $pc, just that the call completed successfully. */ |
| if (this_frame->level >= 0) |
| frame_unwind_pc (this_frame); |
| } |
| catch (const gdb_exception_error &ex) |
| { |
| if (ex.error == NOT_AVAILABLE_ERROR || ex.error == OPTIMIZED_OUT_ERROR) |
| { |
| frame_debug_printf (" -> nullptr // no saved PC"); |
| this_frame->stop_reason = UNWIND_NO_SAVED_PC; |
| this_frame->prev = nullptr; |
| return nullptr; |
| } |
| |
| throw; |
| } |
| |
| return get_prev_frame_maybe_check_cycle (this_frame); |
| } |
| |
| /* Return a "struct frame_info" corresponding to the frame that called |
| THIS_FRAME. Returns NULL if there is no such frame. |
| |
| Unlike get_prev_frame, this function always tries to unwind the |
| frame. */ |
| |
| frame_info_ptr |
| get_prev_frame_always (const frame_info_ptr &this_frame) |
| { |
| frame_info_ptr prev_frame = NULL; |
| |
| try |
| { |
| prev_frame = get_prev_frame_always_1 (this_frame); |
| } |
| catch (const gdb_exception_error &ex) |
| { |
| if (ex.error == MEMORY_ERROR) |
| { |
| this_frame->stop_reason = UNWIND_MEMORY_ERROR; |
| if (ex.message != NULL) |
| { |
| char *stop_string; |
| size_t size; |
| |
| /* The error needs to live as long as the frame does. |
| Allocate using stack local STOP_STRING then assign the |
| pointer to the frame, this allows the STOP_STRING on the |
| frame to be of type 'const char *'. */ |
| size = ex.message->size () + 1; |
| stop_string = (char *) frame_obstack_zalloc (size); |
| memcpy (stop_string, ex.what (), size); |
| this_frame->stop_string = stop_string; |
| } |
| prev_frame = NULL; |
| } |
| else |
| throw; |
| } |
| |
| return prev_frame; |
| } |
| |
| /* Construct a new "struct frame_info" and link it previous to |
| this_frame. */ |
| |
| static frame_info_ptr |
| get_prev_frame_raw (const frame_info_ptr &this_frame) |
| { |
| frame_info *prev_frame; |
| |
| /* Allocate the new frame but do not wire it in to the frame chain. |
| Some (bad) code in INIT_FRAME_EXTRA_INFO tries to look along |
| frame->next to pull some fancy tricks (of course such code is, by |
| definition, recursive). Try to prevent it. |
| |
| There is no reason to worry about memory leaks, should the |
| remainder of the function fail. The allocated memory will be |
| quickly reclaimed when the frame cache is flushed, and the `we've |
| been here before' check above will stop repeated memory |
| allocation calls. */ |
| prev_frame = FRAME_OBSTACK_ZALLOC (struct frame_info); |
| prev_frame->level = this_frame->level + 1; |
| |
| /* For now, assume we don't have frame chains crossing address |
| spaces. */ |
| prev_frame->pspace = this_frame->pspace; |
| prev_frame->aspace = this_frame->aspace; |
| |
| /* Don't yet compute ->unwind (and hence ->type). It is computed |
| on-demand in get_frame_type, frame_register_unwind, and |
| get_frame_id. */ |
| |
| /* Don't yet compute the frame's ID. It is computed on-demand by |
| get_frame_id(). */ |
| |
| /* The unwound frame ID is validate at the start of this function, |
| as part of the logic to decide if that frame should be further |
| unwound, and not here while the prev frame is being created. |
| Doing this makes it possible for the user to examine a frame that |
| has an invalid frame ID. |
| |
| Some very old VAX code noted: [...] For the sake of argument, |
| suppose that the stack is somewhat trashed (which is one reason |
| that "info frame" exists). So, return 0 (indicating we don't |
| know the address of the arglist) if we don't know what frame this |
| frame calls. */ |
| |
| /* Link it in. */ |
| this_frame->prev = prev_frame; |
| prev_frame->next = this_frame.get (); |
| |
| frame_debug_printf (" -> %s", prev_frame->to_string ().c_str ()); |
| |
| return frame_info_ptr (prev_frame); |
| } |
| |
| /* Debug routine to print a NULL frame being returned. */ |
| |
| static void |
| frame_debug_got_null_frame (const frame_info_ptr &this_frame, |
| const char *reason) |
| { |
| if (frame_debug) |
| { |
| if (this_frame != NULL) |
| frame_debug_printf ("this_frame=%d -> %s", this_frame->level, reason); |
| else |
| frame_debug_printf ("this_frame=nullptr -> %s", reason); |
| } |
| } |
| |
| /* Is this (non-sentinel) frame in the "main"() function? */ |
| |
| static bool |
| inside_main_func (const frame_info_ptr &this_frame) |
| { |
| if (current_program_space->symfile_object_file == nullptr) |
| return false; |
| |
| CORE_ADDR sym_addr = 0; |
| const char *name = main_name (); |
| bound_minimal_symbol msymbol |
| = lookup_minimal_symbol (current_program_space, name, |
| current_program_space->symfile_object_file); |
| |
| if (msymbol.minsym != nullptr) |
| sym_addr = msymbol.value_address (); |
| |
| /* Favor a full symbol in Fortran, for the case where the Fortran main |
| is also called "main". */ |
| if (msymbol.minsym == nullptr |
| || get_frame_language (this_frame) == language_fortran) |
| { |
| /* In some language (for example Fortran) there will be no minimal |
| symbol with the name of the main function. In this case we should |
| search the full symbols to see if we can find a match. */ |
| struct block_symbol bs = lookup_symbol (name, nullptr, |
| SEARCH_FUNCTION_DOMAIN, nullptr); |
| |
| /* This lookup should always yield a block-valued symbol. */ |
| if (bs.symbol != nullptr && bs.symbol->aclass () == LOC_BLOCK) |
| { |
| const struct block *block = bs.symbol->value_block (); |
| gdb_assert (block != nullptr); |
| sym_addr = block->start (); |
| } |
| else if (msymbol.minsym == nullptr) |
| return false; |
| } |
| |
| /* Convert any function descriptor addresses into the actual function |
| code address. */ |
| sym_addr = (gdbarch_convert_from_func_ptr_addr |
| (get_frame_arch (this_frame), sym_addr, |
| current_inferior ()->top_target ())); |
| |
| return sym_addr == get_frame_func (this_frame); |
| } |
| |
| /* Test whether THIS_FRAME is inside the process entry point function. */ |
| |
| static bool |
| inside_entry_func (const frame_info_ptr &this_frame) |
| { |
| CORE_ADDR entry_point; |
| |
| if (!entry_point_address_query (current_program_space, &entry_point)) |
| return false; |
| |
| return get_frame_func (this_frame) == entry_point; |
| } |
| |
| /* Return a structure containing various interesting information about |
| the frame that called THIS_FRAME. Returns NULL if there is either |
| no such frame or the frame fails any of a set of target-independent |
| condition that should terminate the frame chain (e.g., as unwinding |
| past main()). |
| |
| This function should not contain target-dependent tests, such as |
| checking whether the program-counter is zero. */ |
| |
| frame_info_ptr |
| get_prev_frame (const frame_info_ptr &this_frame) |
| { |
| FRAME_SCOPED_DEBUG_ENTER_EXIT; |
| |
| CORE_ADDR frame_pc; |
| int frame_pc_p; |
| |
| /* There is always a frame. If this assertion fails, suspect that |
| something should be calling get_selected_frame() or |
| get_current_frame(). */ |
| gdb_assert (this_frame != NULL); |
| |
| frame_pc_p = get_frame_pc_if_available (this_frame, &frame_pc); |
| |
| /* tausq/2004-12-07: Dummy frames are skipped because it doesn't make much |
| sense to stop unwinding at a dummy frame. One place where a dummy |
| frame may have an address "inside_main_func" is on HPUX. On HPUX, the |
| pcsqh register (space register for the instruction at the head of the |
| instruction queue) cannot be written directly; the only way to set it |
| is to branch to code that is in the target space. In order to implement |
| frame dummies on HPUX, the called function is made to jump back to where |
| the inferior was when the user function was called. If gdb was inside |
| the main function when we created the dummy frame, the dummy frame will |
| point inside the main function. */ |
| if (this_frame->level >= 0 |
| && get_frame_type (this_frame) == NORMAL_FRAME |
| && !user_set_backtrace_options.backtrace_past_main |
| && frame_pc_p |
| && inside_main_func (this_frame)) |
| /* Don't unwind past main(). Note, this is done _before_ the |
| frame has been marked as previously unwound. That way if the |
| user later decides to enable unwinds past main(), that will |
| automatically happen. */ |
| { |
| frame_debug_got_null_frame (this_frame, "inside main func"); |
| return NULL; |
| } |
| |
| /* If the user's backtrace limit has been exceeded, stop. We must |
| add two to the current level; one of those accounts for backtrace_limit |
| being 1-based and the level being 0-based, and the other accounts for |
| the level of the new frame instead of the level of the current |
| frame. */ |
| if (this_frame->level + 2 > user_set_backtrace_options.backtrace_limit) |
| { |
| frame_debug_got_null_frame (this_frame, "backtrace limit exceeded"); |
| return NULL; |
| } |
| |
| /* If we're already inside the entry function for the main objfile, |
| then it isn't valid. Don't apply this test to a dummy frame - |
| dummy frame PCs typically land in the entry func. Don't apply |
| this test to the sentinel frame. Sentinel frames should always |
| be allowed to unwind. */ |
| /* NOTE: cagney/2003-07-07: Fixed a bug in inside_main_func() - |
| wasn't checking for "main" in the minimal symbols. With that |
| fixed asm-source tests now stop in "main" instead of halting the |
| backtrace in weird and wonderful ways somewhere inside the entry |
| file. Suspect that tests for inside the entry file/func were |
| added to work around that (now fixed) case. */ |
| /* NOTE: cagney/2003-07-15: danielj (if I'm reading it right) |
| suggested having the inside_entry_func test use the |
| inside_main_func() msymbol trick (along with entry_point_address() |
| I guess) to determine the address range of the start function. |
| That should provide a far better stopper than the current |
| heuristics. */ |
| /* NOTE: tausq/2004-10-09: this is needed if, for example, the compiler |
| applied tail-call optimizations to main so that a function called |
| from main returns directly to the caller of main. Since we don't |
| stop at main, we should at least stop at the entry point of the |
| application. */ |
| if (this_frame->level >= 0 |
| && get_frame_type (this_frame) == NORMAL_FRAME |
| && !user_set_backtrace_options.backtrace_past_entry |
| && frame_pc_p |
| && inside_entry_func (this_frame)) |
| { |
| frame_debug_got_null_frame (this_frame, "inside entry func"); |
| return NULL; |
| } |
| |
| /* Assume that the only way to get a zero PC is through something |
| like a SIGSEGV or a dummy frame, and hence that NORMAL frames |
| will never unwind a zero PC. */ |
| if (this_frame->level > 0 |
| && (get_frame_type (this_frame) == NORMAL_FRAME |
| || get_frame_type (this_frame) == INLINE_FRAME) |
| && get_frame_type (get_next_frame (this_frame)) == NORMAL_FRAME |
| && frame_pc_p && frame_pc == 0) |
| { |
| frame_debug_got_null_frame (this_frame, "zero PC"); |
| return NULL; |
| } |
| |
| return get_prev_frame_always (this_frame); |
| } |
| |
| CORE_ADDR |
| get_frame_pc (const frame_info_ptr &frame) |
| { |
| gdb_assert (frame->next != NULL); |
| return frame_unwind_pc (frame_info_ptr (frame->next)); |
| } |
| |
| bool |
| get_frame_pc_if_available (const frame_info_ptr &frame, CORE_ADDR *pc) |
| { |
| |
| gdb_assert (frame->next != NULL); |
| |
| try |
| { |
| *pc = frame_unwind_pc (frame_info_ptr (frame->next)); |
| } |
| catch (const gdb_exception_error &ex) |
| { |
| if (ex.error == NOT_AVAILABLE_ERROR) |
| return false; |
| else |
| throw; |
| } |
| |
| return true; |
| } |
| |
| /* Return an address that falls within THIS_FRAME's code block. */ |
| |
| CORE_ADDR |
| get_frame_address_in_block (const frame_info_ptr &this_frame) |
| { |
| /* A draft address. */ |
| CORE_ADDR pc = get_frame_pc (this_frame); |
| |
| frame_info_ptr next_frame (this_frame->next); |
| |
| /* Calling get_frame_pc returns the resume address for THIS_FRAME. |
| Normally the resume address is inside the body of the function |
| associated with THIS_FRAME, but there is a special case: when |
| calling a function which the compiler knows will never return |
| (for instance abort), the call may be the very last instruction |
| in the calling function. The resume address will point after the |
| call and may be at the beginning of a different function |
| entirely. |
| |
| If THIS_FRAME is a signal frame or dummy frame, then we should |
| not adjust the unwound PC. For a dummy frame, GDB pushed the |
| resume address manually onto the stack. For a signal frame, the |
| OS may have pushed the resume address manually and invoked the |
| handler (e.g. GNU/Linux), or invoked the trampoline which called |
| the signal handler - but in either case the signal handler is |
| expected to return to the trampoline. So in both of these |
| cases we know that the resume address is executable and |
| related. So we only need to adjust the PC if THIS_FRAME |
| is a normal function. |
| |
| If the program has been interrupted while THIS_FRAME is current, |
| then clearly the resume address is inside the associated |
| function. There are three kinds of interruption: debugger stop |
| (next frame will be SENTINEL_FRAME), operating system |
| signal or exception (next frame will be SIGTRAMP_FRAME), |
| or debugger-induced function call (next frame will be |
| DUMMY_FRAME). So we only need to adjust the PC if |
| NEXT_FRAME is a normal function. |
| |
| We check the type of NEXT_FRAME first, since it is already |
| known; frame type is determined by the unwinder, and since |
| we have THIS_FRAME we've already selected an unwinder for |
| NEXT_FRAME. |
| |
| If the next frame is inlined, we need to keep going until we find |
| the real function - for instance, if a signal handler is invoked |
| while in an inlined function, then the code address of the |
| "calling" normal function should not be adjusted either. */ |
| |
| while (get_frame_type (next_frame) == INLINE_FRAME) |
| next_frame = frame_info_ptr (next_frame->next); |
| |
| if ((get_frame_type (next_frame) == NORMAL_FRAME |
| || get_frame_type (next_frame) == TAILCALL_FRAME) |
| && (get_frame_type (this_frame) == NORMAL_FRAME |
| || get_frame_type (this_frame) == TAILCALL_FRAME |
| || get_frame_type (this_frame) == INLINE_FRAME)) |
| return pc - 1; |
| |
| return pc; |
| } |
| |
| bool |
| get_frame_address_in_block_if_available (const frame_info_ptr &this_frame, |
| CORE_ADDR *pc) |
| { |
| |
| try |
| { |
| *pc = get_frame_address_in_block (this_frame); |
| } |
| catch (const gdb_exception_error &ex) |
| { |
| if (ex.error == NOT_AVAILABLE_ERROR) |
| return false; |
| throw; |
| } |
| |
| return true; |
| } |
| |
| symtab_and_line |
| find_frame_sal (const frame_info_ptr &frame) |
| { |
| frame_info_ptr next_frame; |
| int notcurrent; |
| CORE_ADDR pc; |
| |
| if (frame_inlined_callees (frame) > 0) |
| { |
| const symbol *sym; |
| |
| /* If the current frame has some inlined callees, and we have a next |
| frame, then that frame must be an inlined frame. In this case |
| this frame's sal is the "call site" of the next frame's inlined |
| function, which can not be inferred from get_frame_pc. */ |
| next_frame = get_next_frame (frame); |
| if (next_frame) |
| sym = get_frame_function (next_frame); |
| else |
| sym = inline_skipped_symbol (inferior_thread ()); |
| |
| /* If frame is inline, it certainly has symbols. */ |
| gdb_assert (sym); |
| |
| symtab_and_line sal; |
| if (sym->line () != 0) |
| { |
| sal.symtab = sym->symtab (); |
| sal.line = sym->line (); |
| } |
| else |
| /* If the symbol does not have a location, we don't know where |
| the call site is. Do not pretend to. This is jarring, but |
| we can't do much better. */ |
| sal.pc = get_frame_pc (frame); |
| |
| sal.pspace = get_frame_program_space (frame); |
| return sal; |
| } |
| |
| /* If FRAME is not the innermost frame, that normally means that |
| FRAME->pc points at the return instruction (which is *after* the |
| call instruction), and we want to get the line containing the |
| call (because the call is where the user thinks the program is). |
| However, if the next frame is either a SIGTRAMP_FRAME or a |
| DUMMY_FRAME, then the next frame will contain a saved interrupt |
| PC and such a PC indicates the current (rather than next) |
| instruction/line, consequently, for such cases, want to get the |
| line containing fi->pc. */ |
| if (!get_frame_pc_if_available (frame, &pc)) |
| return {}; |
| |
| notcurrent = (pc != get_frame_address_in_block (frame)); |
| return find_pc_line (pc, notcurrent); |
| } |
| |
| /* Per "frame.h", return the ``address'' of the frame. Code should |
| really be using get_frame_id(). */ |
| CORE_ADDR |
| get_frame_base (const frame_info_ptr &fi) |
| { |
| return get_frame_id (fi).stack_addr; |
| } |
| |
| /* High-level offsets into the frame. Used by the debug info. */ |
| |
| CORE_ADDR |
| get_frame_base_address (const frame_info_ptr &fi) |
| { |
| if (get_frame_type (fi) != NORMAL_FRAME) |
| return 0; |
| if (fi->base == NULL) |
| fi->base = frame_base_find_by_frame (fi); |
| /* Sneaky: If the low-level unwind and high-level base code share a |
| common unwinder, let them share the prologue cache. */ |
| if (fi->base->unwind == fi->unwind) |
| return fi->base->this_base (fi, &fi->prologue_cache); |
| return fi->base->this_base (fi, &fi->base_cache); |
| } |
| |
| CORE_ADDR |
| get_frame_locals_address (const frame_info_ptr &fi) |
| { |
| if (get_frame_type (fi) != NORMAL_FRAME) |
| return 0; |
| /* If there isn't a frame address method, find it. */ |
| if (fi->base == NULL) |
| fi->base = frame_base_find_by_frame (fi); |
| /* Sneaky: If the low-level unwind and high-level base code share a |
| common unwinder, let them share the prologue cache. */ |
| if (fi->base->unwind == fi->unwind) |
| return fi->base->this_locals (fi, &fi->prologue_cache); |
| return fi->base->this_locals (fi, &fi->base_cache); |
| } |
| |
| CORE_ADDR |
| get_frame_args_address (const frame_info_ptr &fi) |
| { |
| if (get_frame_type (fi) != NORMAL_FRAME) |
| return 0; |
| /* If there isn't a frame address method, find it. */ |
| if (fi->base == NULL) |
| fi->base = frame_base_find_by_frame (fi); |
| /* Sneaky: If the low-level unwind and high-level base code share a |
| common unwinder, let them share the prologue cache. */ |
| if (fi->base->unwind == fi->unwind) |
| return fi->base->this_args (fi, &fi->prologue_cache); |
| return fi->base->this_args (fi, &fi->base_cache); |
| } |
| |
| /* Return true if the frame unwinder for frame FI is UNWINDER; false |
| otherwise. */ |
| |
| bool |
| frame_unwinder_is (const frame_info_ptr &fi, const frame_unwind *unwinder) |
| { |
| if (fi->unwind == nullptr) |
| frame_unwind_find_by_frame (fi, &fi->prologue_cache); |
| |
| return fi->unwind == unwinder; |
| } |
| |
| /* Level of the selected frame: 0 for innermost, 1 for its caller, ... |
| or -1 for a NULL frame. */ |
| |
| int |
| frame_relative_level (const frame_info_ptr &fi) |
| { |
| if (fi == NULL) |
| return -1; |
| else |
| return fi->level; |
| } |
| |
| enum frame_type |
| get_frame_type (const frame_info_ptr &frame) |
| { |
| if (frame->unwind == NULL) |
| /* Initialize the frame's unwinder because that's what |
| provides the frame's type. */ |
| frame_unwind_find_by_frame (frame, &frame->prologue_cache); |
| return frame->unwind->type; |
| } |
| |
| struct program_space * |
| get_frame_program_space (const frame_info_ptr &frame) |
| { |
| return frame->pspace; |
| } |
| |
| struct program_space * |
| frame_unwind_program_space (const frame_info_ptr &this_frame) |
| { |
| gdb_assert (this_frame); |
| |
| /* This is really a placeholder to keep the API consistent --- we |
| assume for now that we don't have frame chains crossing |
| spaces. */ |
| return this_frame->pspace; |
| } |
| |
| const address_space * |
| get_frame_address_space (const frame_info_ptr &frame) |
| { |
| return frame->aspace; |
| } |
| |
| /* Memory access methods. */ |
| |
| void |
| get_frame_memory (const frame_info_ptr &this_frame, CORE_ADDR addr, |
| gdb::array_view<gdb_byte> buffer) |
| { |
| read_memory (addr, buffer.data (), buffer.size ()); |
| } |
| |
| LONGEST |
| get_frame_memory_signed (const frame_info_ptr &this_frame, CORE_ADDR addr, |
| int len) |
| { |
| struct gdbarch *gdbarch = get_frame_arch (this_frame); |
| enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); |
| |
| return read_memory_integer (addr, len, byte_order); |
| } |
| |
| ULONGEST |
| get_frame_memory_unsigned (const frame_info_ptr &this_frame, CORE_ADDR addr, |
| int len) |
| { |
| struct gdbarch *gdbarch = get_frame_arch (this_frame); |
| enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); |
| |
| return read_memory_unsigned_integer (addr, len, byte_order); |
| } |
| |
| bool |
| safe_frame_unwind_memory (const frame_info_ptr &this_frame, |
| CORE_ADDR addr, gdb::array_view<gdb_byte> buffer) |
| { |
| /* NOTE: target_read_memory returns zero on success! */ |
| return target_read_memory (addr, buffer.data (), buffer.size ()) == 0; |
| } |
| |
| /* Architecture methods. */ |
| |
| struct gdbarch * |
| get_frame_arch (const frame_info_ptr &this_frame) |
| { |
| return frame_unwind_arch (frame_info_ptr (this_frame->next)); |
| } |
| |
| struct gdbarch * |
| frame_unwind_arch (const frame_info_ptr &next_frame) |
| { |
| if (!next_frame->prev_arch.p) |
| { |
| struct gdbarch *arch; |
| |
| if (next_frame->unwind == NULL) |
| frame_unwind_find_by_frame (next_frame, &next_frame->prologue_cache); |
| |
| if (next_frame->unwind->prev_arch != NULL) |
| arch = next_frame->unwind->prev_arch (next_frame, |
| &next_frame->prologue_cache); |
| else |
| arch = get_frame_arch (next_frame); |
| |
| next_frame->prev_arch.arch = arch; |
| next_frame->prev_arch.p = true; |
| frame_debug_printf ("next_frame=%d -> %s", |
| next_frame->level, |
| gdbarch_bfd_arch_info (arch)->printable_name); |
| } |
| |
| return next_frame->prev_arch.arch; |
| } |
| |
| struct gdbarch * |
| frame_unwind_caller_arch (const frame_info_ptr &initial_next_frame) |
| { |
| frame_info_ptr next_frame = skip_artificial_frames (initial_next_frame); |
| |
| /* We must have a non-artificial frame. The caller is supposed to check |
| the result of frame_unwind_caller_id (), which returns NULL_FRAME_ID |
| in this case. */ |
| gdb_assert (next_frame != nullptr); |
| |
| return frame_unwind_arch (next_frame); |
| } |
| |
| /* Gets the language of FRAME. */ |
| |
| enum language |
| get_frame_language (const frame_info_ptr &frame) |
| { |
| CORE_ADDR pc = 0; |
| bool pc_p = false; |
| |
| gdb_assert (frame!= NULL); |
| |
| /* We determine the current frame language by looking up its |
| associated symtab. To retrieve this symtab, we use the frame |
| PC. However we cannot use the frame PC as is, because it |
| usually points to the instruction following the "call", which |
| is sometimes the first instruction of another function. So |
| we rely on get_frame_address_in_block(), it provides us with |
| a PC that is guaranteed to be inside the frame's code |
| block. */ |
| |
| try |
| { |
| pc = get_frame_address_in_block (frame); |
| pc_p = true; |
| } |
| catch (const gdb_exception_error &ex) |
| { |
| if (ex.error != NOT_AVAILABLE_ERROR) |
| throw; |
| } |
| |
| if (pc_p) |
| { |
| struct compunit_symtab *cust = find_pc_compunit_symtab (pc); |
| |
| if (cust != NULL) |
| return cust->language (); |
| } |
| |
| return language_unknown; |
| } |
| |
| /* Stack pointer methods. */ |
| |
| CORE_ADDR |
| get_frame_sp (const frame_info_ptr &this_frame) |
| { |
| struct gdbarch *gdbarch = get_frame_arch (this_frame); |
| |
| /* NOTE drow/2008-06-28: gdbarch_unwind_sp could be converted to |
| operate on THIS_FRAME now. */ |
| return gdbarch_unwind_sp (gdbarch, frame_info_ptr (this_frame->next)); |
| } |
| |
| /* See frame.h. */ |
| |
| frame_info_ptr |
| frame_follow_static_link (const frame_info_ptr &initial_frame) |
| { |
| const block *frame_block = get_frame_block (initial_frame, nullptr); |
| if (frame_block == nullptr) |
| return {}; |
| |
| frame_block = frame_block->function_block (); |
| |
| const struct dynamic_prop *static_link = frame_block->static_link (); |
| if (static_link == nullptr) |
| return {}; |
| |
| CORE_ADDR upper_frame_base; |
| |
| if (!dwarf2_evaluate_property (static_link, initial_frame, NULL, &upper_frame_base)) |
| return {}; |
| |
| /* Now climb up the stack frame until we reach the frame we are interested |
| in. */ |
| frame_info_ptr frame = initial_frame; |
| for (; frame != nullptr; frame = get_prev_frame (frame)) |
| { |
| struct symbol *framefunc = get_frame_function (frame); |
| |
| /* Stacks can be quite deep: give the user a chance to stop this. */ |
| QUIT; |
| |
| /* If we don't know how to compute FRAME's base address, don't give up: |
| maybe the frame we are looking for is upper in the stack frame. */ |
| if (framefunc != nullptr) |
| { |
| if (const symbol_block_ops *block_ops = framefunc->block_ops (); |
| (block_ops != nullptr |
| && block_ops->get_frame_base != nullptr |
| && (block_ops->get_frame_base (framefunc, frame) |
| == upper_frame_base))) |
| break; |
| } |
| } |
| |
| return frame; |
| } |
| |
| /* Return the reason why we can't unwind past FRAME. */ |
| |
| enum unwind_stop_reason |
| get_frame_unwind_stop_reason (const frame_info_ptr &frame) |
| { |
| /* Fill-in STOP_REASON. */ |
| get_prev_frame_always (frame); |
| gdb_assert (frame->prev_p); |
| |
| return frame->stop_reason; |
| } |
| |
| /* Return a string explaining REASON. */ |
| |
| const char * |
| unwind_stop_reason_to_string (enum unwind_stop_reason reason) |
| { |
| switch (reason) |
| { |
| #define SET(name, description) \ |
| case name: return _(description); |
| #include "unwind_stop_reasons.def" |
| #undef SET |
| |
| default: |
| internal_error ("Invalid frame stop reason"); |
| } |
| } |
| |
| const char * |
| frame_stop_reason_string (const frame_info_ptr &fi) |
| { |
| gdb_assert (fi->prev_p); |
| gdb_assert (fi->prev == NULL); |
| |
| /* Return the specific string if we have one. */ |
| if (fi->stop_string != NULL) |
| return fi->stop_string; |
| |
| /* Return the generic string if we have nothing better. */ |
| return unwind_stop_reason_to_string (fi->stop_reason); |
| } |
| |
| /* Return the enum symbol name of REASON as a string, to use in debug |
| output. */ |
| |
| static const char * |
| frame_stop_reason_symbol_string (enum unwind_stop_reason reason) |
| { |
| switch (reason) |
| { |
| #define SET(name, description) \ |
| case name: return #name; |
| #include "unwind_stop_reasons.def" |
| #undef SET |
| |
| default: |
| internal_error ("Invalid frame stop reason"); |
| } |
| } |
| |
| /* Clean up after a failed (wrong unwinder) attempt to unwind past |
| FRAME. */ |
| |
| void |
| frame_cleanup_after_sniffer (const frame_info_ptr &frame) |
| { |
| /* The sniffer should not allocate a prologue cache if it did not |
| match this frame. */ |
| gdb_assert (frame->prologue_cache == NULL); |
| |
| /* No sniffer should extend the frame chain; sniff based on what is |
| already certain. */ |
| gdb_assert (!frame->prev_p); |
| |
| /* The sniffer should not check the frame's ID; that's circular. */ |
| gdb_assert (frame->this_id.p != frame_id_status::COMPUTED); |
| |
| /* Clear cached fields dependent on the unwinder. |
| |
| The previous PC is independent of the unwinder, but the previous |
| function is not (see get_frame_address_in_block). */ |
| frame->prev_func.status = CC_UNKNOWN; |
| frame->prev_func.addr = 0; |
| |
| /* Discard the unwinder last, so that we can easily find it if an assertion |
| in this function triggers. */ |
| frame->unwind = NULL; |
| } |
| |
| /* Set FRAME's unwinder temporarily, so that we can call a sniffer. |
| If sniffing fails, the caller should be sure to call |
| frame_cleanup_after_sniffer. */ |
| |
| void |
| frame_prepare_for_sniffer (const frame_info_ptr &frame, |
| const struct frame_unwind *unwind) |
| { |
| gdb_assert (frame->unwind == NULL); |
| frame->unwind = unwind; |
| } |
| |
| static struct cmd_list_element *set_backtrace_cmdlist; |
| static struct cmd_list_element *show_backtrace_cmdlist; |
| |
| /* Definition of the "set backtrace" settings that are exposed as |
| "backtrace" command options. */ |
| |
| using boolean_option_def |
| = gdb::option::boolean_option_def<set_backtrace_options>; |
| |
| const gdb::option::option_def set_backtrace_option_defs[] = { |
| |
| boolean_option_def { |
| "past-main", |
| [] (set_backtrace_options *opt) { return &opt->backtrace_past_main; }, |
| show_backtrace_past_main, /* show_cmd_cb */ |
| N_("Set whether backtraces should continue past \"main\"."), |
| N_("Show whether backtraces should continue past \"main\"."), |
| N_("Normally the caller of \"main\" is not of interest, so GDB will terminate\n\ |
| the backtrace at \"main\". Set this if you need to see the rest\n\ |
| of the stack trace."), |
| }, |
| |
| boolean_option_def { |
| "past-entry", |
| [] (set_backtrace_options *opt) { return &opt->backtrace_past_entry; }, |
| show_backtrace_past_entry, /* show_cmd_cb */ |
| N_("Set whether backtraces should continue past the entry point of a program."), |
| N_("Show whether backtraces should continue past the entry point of a program."), |
| N_("Normally there are no callers beyond the entry point of a program, so GDB\n\ |
| will terminate the backtrace there. Set this if you need to see\n\ |
| the rest of the stack trace."), |
| }, |
| }; |
| |
| /* Implement the 'maintenance print frame-id' command. */ |
| |
| static void |
| maintenance_print_frame_id (const char *args, int from_tty) |
| { |
| frame_info_ptr frame; |
| |
| /* Use the currently selected frame, or select a frame based on the level |
| number passed by the user. */ |
| if (args == nullptr) |
| frame = get_selected_frame ("No frame selected"); |
| else |
| { |
| int level = value_as_long (parse_and_eval (args)); |
| frame = find_relative_frame (get_current_frame (), &level); |
| } |
| |
| /* Print the frame-id. */ |
| gdb_assert (frame != nullptr); |
| gdb_printf ("frame-id for frame #%d: %s\n", |
| frame_relative_level (frame), |
| get_frame_id (frame).to_string ().c_str ()); |
| } |
| |
| /* See frame-info-ptr.h. */ |
| |
| frame_info_ptr::frame_info_ptr (struct frame_info *ptr) |
| : m_ptr (ptr) |
| { |
| frame_list.push_back (*this); |
| |
| if (m_ptr == nullptr) |
| return; |
| |
| m_cached_level = ptr->level; |
| |
| if (m_cached_level != 0 || m_ptr->this_id.value.user_created_p) |
| m_cached_id = m_ptr->this_id.value; |
| } |
| |
| /* See frame-info-ptr.h. */ |
| |
| frame_info * |
| frame_info_ptr::reinflate () const |
| { |
| /* Ensure we have a valid frame level (sentinel frame or above). */ |
| gdb_assert (m_cached_level >= -1); |
| |
| if (m_ptr != nullptr) |
| { |
| /* The frame_info wasn't invalidated, no need to reinflate. */ |
| return m_ptr; |
| } |
| |
| if (m_cached_id.user_created_p) |
| m_ptr = create_new_frame (m_cached_id).get (); |
| else |
| { |
| /* Frame #0 needs special handling, see comment in select_frame. */ |
| if (m_cached_level == 0) |
| m_ptr = get_current_frame ().get (); |
| else |
| { |
| /* If we reach here without a valid frame id, it means we are trying |
| to reinflate a frame whose id was not know at construction time. |
| We're probably trying to reinflate a frame while computing its id |
| which is not possible, and would indicate a problem with GDB. */ |
| gdb_assert (frame_id_p (m_cached_id)); |
| m_ptr = frame_find_by_id (m_cached_id).get (); |
| } |
| } |
| |
| gdb_assert (m_ptr != nullptr); |
| return m_ptr; |
| } |
| |
| void _initialize_frame (); |
| void |
| _initialize_frame () |
| { |
| obstack_init (&frame_cache_obstack); |
| |
| frame_stash_create (); |
| |
| gdb::observers::target_changed.attach (frame_observer_target_changed, |
| "frame"); |
| |
| add_setshow_prefix_cmd ("backtrace", class_maintenance, |
| _("\ |
| Set backtrace specific variables.\n\ |
| Configure backtrace variables such as the backtrace limit"), |
| _("\ |
| Show backtrace specific variables.\n\ |
| Show backtrace variables such as the backtrace limit."), |
| &set_backtrace_cmdlist, &show_backtrace_cmdlist, |
| &setlist, &showlist); |
| |
| add_setshow_uinteger_cmd ("limit", class_obscure, |
| &user_set_backtrace_options.backtrace_limit, _("\ |
| Set an upper bound on the number of backtrace levels."), _("\ |
| Show the upper bound on the number of backtrace levels."), _("\ |
| No more than the specified number of frames can be displayed or examined.\n\ |
| Literal \"unlimited\" or zero means no limit."), |
| NULL, |
| show_backtrace_limit, |
| &set_backtrace_cmdlist, |
| &show_backtrace_cmdlist); |
| |
| gdb::option::add_setshow_cmds_for_options |
| (class_stack, &user_set_backtrace_options, |
| set_backtrace_option_defs, &set_backtrace_cmdlist, &show_backtrace_cmdlist); |
| |
| /* Debug this files internals. */ |
| add_setshow_boolean_cmd ("frame", class_maintenance, &frame_debug, _("\ |
| Set frame debugging."), _("\ |
| Show frame debugging."), _("\ |
| When non-zero, frame specific internal debugging is enabled."), |
| NULL, |
| show_frame_debug, |
| &setdebuglist, &showdebuglist); |
| |
| add_cmd ("frame-id", class_maintenance, maintenance_print_frame_id, |
| _("Print the current frame-id."), |
| &maintenanceprintlist); |
| } |