X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fframe.c;h=d8b5f819f1d4162f3302cfd13e5d2cd73dc9c18f;hb=24e31cf3aa66e20877358040ceb35b87dde66d12;hp=f100da356ab6a1aa4fe87fae98fc5e1f4f7511cf;hpb=481695ed5f6e0a8a9c9c50bfac1cdd2b3151e6c9;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/frame.c b/gdb/frame.c index f100da356a..d8b5f819f1 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -1,6 +1,6 @@ /* Cache and manage frames for GDB, the GNU debugger. - Copyright (C) 1986-2017 Free Software Foundation, Inc. + Copyright (C) 1986-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -34,7 +34,7 @@ #include "frame-base.h" #include "command.h" #include "gdbcmd.h" -#include "observer.h" +#include "observable.h" #include "objfiles.h" #include "gdbthread.h" #include "block.h" @@ -99,7 +99,7 @@ struct frame_info struct program_space *pspace; /* The frame's address space. */ - struct address_space *aspace; + const address_space *aspace; /* The frame's low-level unwinder and corresponding cache. The low-level unwinder is responsible for unwinding register values @@ -269,6 +269,22 @@ frame_stash_invalidate (void) htab_empty (frame_stash); } +/* See frame.h */ +scoped_restore_selected_frame::scoped_restore_selected_frame () +{ + m_fid = get_frame_id (get_selected_frame (NULL)); +} + +/* See frame.h */ +scoped_restore_selected_frame::~scoped_restore_selected_frame () +{ + frame_info *frame = frame_find_by_id (m_fid); + if (frame == NULL) + warning (_("Unable to restore previously selected frame.")); + else + select_frame (frame); +} + /* Flag to control debugging. */ unsigned int frame_debug; @@ -856,76 +872,71 @@ frame_unwind_pc (struct frame_info *this_frame) { if (this_frame->prev_pc.status == CC_UNKNOWN) { - if (gdbarch_unwind_pc_p (frame_unwind_arch (this_frame))) + struct gdbarch *prev_gdbarch; + CORE_ADDR pc = 0; + int pc_p = 0; + + /* 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 = 1; + } + CATCH (ex, RETURN_MASK_ERROR) { - struct gdbarch *prev_gdbarch; - CORE_ADDR pc = 0; - int pc_p = 0; - - /* 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 + if (ex.error == NOT_AVAILABLE_ERROR) { - pc = gdbarch_unwind_pc (prev_gdbarch, this_frame); - pc_p = 1; + this_frame->prev_pc.status = CC_UNAVAILABLE; + + if (frame_debug) + fprintf_unfiltered (gdb_stdlog, + "{ frame_unwind_pc (this_frame=%d)" + " -> }\n", + this_frame->level); } - CATCH (ex, RETURN_MASK_ERROR) + else if (ex.error == OPTIMIZED_OUT_ERROR) { - if (ex.error == NOT_AVAILABLE_ERROR) - { - this_frame->prev_pc.status = CC_UNAVAILABLE; - - if (frame_debug) - fprintf_unfiltered (gdb_stdlog, - "{ frame_unwind_pc (this_frame=%d)" - " -> }\n", - this_frame->level); - } - else if (ex.error == OPTIMIZED_OUT_ERROR) - { - this_frame->prev_pc.status = CC_NOT_SAVED; - - if (frame_debug) - fprintf_unfiltered (gdb_stdlog, - "{ frame_unwind_pc (this_frame=%d)" - " -> }\n", - this_frame->level); - } - else - throw_exception (ex); - } - END_CATCH + this_frame->prev_pc.status = CC_NOT_SAVED; - if (pc_p) - { - this_frame->prev_pc.value = pc; - this_frame->prev_pc.status = CC_VALUE; if (frame_debug) fprintf_unfiltered (gdb_stdlog, - "{ frame_unwind_pc (this_frame=%d) " - "-> %s }\n", - this_frame->level, - hex_string (this_frame->prev_pc.value)); + "{ frame_unwind_pc (this_frame=%d)" + " -> }\n", + this_frame->level); } + else + throw_exception (ex); + } + END_CATCH + + if (pc_p) + { + this_frame->prev_pc.value = pc; + this_frame->prev_pc.status = CC_VALUE; + if (frame_debug) + fprintf_unfiltered (gdb_stdlog, + "{ frame_unwind_pc (this_frame=%d) " + "-> %s }\n", + this_frame->level, + hex_string (this_frame->prev_pc.value)); } - else - internal_error (__FILE__, __LINE__, _("No unwind_pc method")); } if (this_frame->prev_pc.status == CC_VALUE) @@ -1008,25 +1019,20 @@ get_frame_func (struct frame_info *this_frame) return pc; } -static enum register_status -do_frame_register_read (void *src, int regnum, gdb_byte *buf) -{ - if (!deprecated_frame_register_read ((struct frame_info *) src, regnum, buf)) - return REG_UNAVAILABLE; - else - return REG_VALID; -} - -struct regcache * +std::unique_ptr frame_save_as_regcache (struct frame_info *this_frame) { - struct address_space *aspace = get_frame_address_space (this_frame); - struct regcache *regcache = regcache_xmalloc (get_frame_arch (this_frame), - aspace); - struct cleanup *cleanups = make_cleanup_regcache_xfree (regcache); + auto cooked_read = [this_frame] (int regnum, gdb_byte *buf) + { + if (!deprecated_frame_register_read (this_frame, regnum, buf)) + return REG_UNAVAILABLE; + else + return REG_VALID; + }; + + std::unique_ptr regcache + (new readonly_detached_regcache (get_frame_arch (this_frame), cooked_read)); - regcache_save (regcache, do_frame_register_read, this_frame); - discard_cleanups (cleanups); return regcache; } @@ -1034,14 +1040,12 @@ void frame_pop (struct frame_info *this_frame) { struct frame_info *prev_frame; - struct regcache *scratch; - struct cleanup *cleanups; 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_ptid); + dummy_frame_pop (get_frame_id (this_frame), inferior_thread ()); return; } @@ -1062,8 +1066,8 @@ frame_pop (struct frame_info *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. */ - scratch = frame_save_as_regcache (prev_frame); - cleanups = make_cleanup_regcache_xfree (scratch); + std::unique_ptr 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 @@ -1073,10 +1077,8 @@ frame_pop (struct frame_info *this_frame) 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. - Here, regcache_cpy() calls regcache_restore(). */ - regcache_cpy (get_current_regcache (), scratch); - do_cleanups (cleanups); + /* Now copy those saved registers into the current regcache. */ + get_current_regcache ()->restore (scratch.get ()); /* We've made right mess of GDB's local state, just discard everything. */ @@ -1084,7 +1086,7 @@ frame_pop (struct frame_info *this_frame) } void -frame_register_unwind (struct frame_info *frame, int regnum, +frame_register_unwind (frame_info *next_frame, int regnum, int *optimizedp, int *unavailablep, enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, gdb_byte *bufferp) @@ -1099,7 +1101,7 @@ frame_register_unwind (struct frame_info *frame, int regnum, gdb_assert (realnump != NULL); /* gdb_assert (bufferp != NULL); */ - value = frame_unwind_register_value (frame, regnum); + value = frame_unwind_register_value (next_frame, regnum); gdb_assert (value != NULL); @@ -1124,7 +1126,6 @@ frame_register_unwind (struct frame_info *frame, int regnum, /* Dispose of the new value. This prevents watchpoints from trying to watch the saved frame pointer. */ release_value (value); - value_free (value); } void @@ -1148,7 +1149,7 @@ frame_register (struct frame_info *frame, int regnum, } void -frame_unwind_register (struct frame_info *frame, int regnum, gdb_byte *buf) +frame_unwind_register (frame_info *next_frame, int regnum, gdb_byte *buf) { int optimized; int unavailable; @@ -1156,7 +1157,7 @@ frame_unwind_register (struct frame_info *frame, int regnum, gdb_byte *buf) int realnum; enum lval_type lval; - frame_register_unwind (frame, regnum, &optimized, &unavailable, + frame_register_unwind (next_frame, regnum, &optimized, &unavailable, &lval, &addr, &realnum, buf); if (optimized) @@ -1175,29 +1176,31 @@ get_frame_register (struct frame_info *frame, } struct value * -frame_unwind_register_value (struct frame_info *frame, int regnum) +frame_unwind_register_value (frame_info *next_frame, int regnum) { struct gdbarch *gdbarch; struct value *value; - gdb_assert (frame != NULL); - gdbarch = frame_unwind_arch (frame); + gdb_assert (next_frame != NULL); + gdbarch = frame_unwind_arch (next_frame); if (frame_debug) { fprintf_unfiltered (gdb_stdlog, "{ frame_unwind_register_value " "(frame=%d,regnum=%d(%s),...) ", - frame->level, regnum, + next_frame->level, regnum, user_reg_map_regnum_to_name (gdbarch, regnum)); } /* Find the unwinder. */ - if (frame->unwind == NULL) - frame_unwind_find_by_frame (frame, &frame->prologue_cache); + if (next_frame->unwind == NULL) + frame_unwind_find_by_frame (next_frame, &next_frame->prologue_cache); /* Ask this frame to unwind its register. */ - value = frame->unwind->prev_register (frame, &frame->prologue_cache, regnum); + value = next_frame->unwind->prev_register (next_frame, + &next_frame->prologue_cache, + regnum); if (frame_debug) { @@ -1247,12 +1250,12 @@ get_frame_register_value (struct frame_info *frame, int regnum) } LONGEST -frame_unwind_register_signed (struct frame_info *frame, int regnum) +frame_unwind_register_signed (frame_info *next_frame, int regnum) { - struct gdbarch *gdbarch = frame_unwind_arch (frame); + 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 (frame, regnum); + struct value *value = frame_unwind_register_value (next_frame, regnum); gdb_assert (value != NULL); @@ -1271,7 +1274,6 @@ frame_unwind_register_signed (struct frame_info *frame, int regnum) byte_order); release_value (value); - value_free (value); return r; } @@ -1282,12 +1284,12 @@ get_frame_register_signed (struct frame_info *frame, int regnum) } ULONGEST -frame_unwind_register_unsigned (struct frame_info *frame, int regnum) +frame_unwind_register_unsigned (frame_info *next_frame, int regnum) { - struct gdbarch *gdbarch = frame_unwind_arch (frame); + 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 (frame, regnum); + struct value *value = frame_unwind_register_value (next_frame, regnum); gdb_assert (value != NULL); @@ -1306,7 +1308,6 @@ frame_unwind_register_unsigned (struct frame_info *frame, int regnum) byte_order); release_value (value); - value_free (value); return r; } @@ -1359,7 +1360,7 @@ put_frame_register (struct frame_info *frame, int regnum, break; } case lval_register: - regcache_cooked_write (get_current_regcache (), realnum, buf); + get_current_regcache ()->cooked_write (realnum, buf); break; default: error (_("Attempt to assign to an unmodifiable value.")); @@ -1410,7 +1411,7 @@ get_frame_register_bytes (struct frame_info *frame, int 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. */ maxsize = -offset; - numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); + numregs = gdbarch_num_cooked_regs (gdbarch); for (i = regnum; i < numregs; i++) { int thissize = register_size (gdbarch, i); @@ -1453,12 +1454,10 @@ get_frame_register_bytes (struct frame_info *frame, int regnum, if (*optimizedp || *unavailablep) { release_value (value); - value_free (value); return 0; } memcpy (myaddr, value_contents_all (value) + offset, curr_len); release_value (value); - value_free (value); } myaddr += curr_len; @@ -1507,7 +1506,6 @@ put_frame_register_bytes (struct frame_info *frame, int regnum, curr_len); put_frame_register (frame, regnum, value_contents_raw (value)); release_value (value); - value_free (value); } myaddr += curr_len; @@ -1526,7 +1524,7 @@ create_sentinel_frame (struct program_space *pspace, struct regcache *regcache) frame->level = -1; frame->pspace = pspace; - frame->aspace = get_regcache_aspace (regcache); + frame->aspace = regcache->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. */ @@ -1621,15 +1619,16 @@ has_stack_frames (void) if (get_traceframe_number () < 0) { /* No current inferior, no frame. */ - if (ptid_equal (inferior_ptid, null_ptid)) + if (inferior_ptid == null_ptid) return 0; + thread_info *tp = inferior_thread (); /* Don't try to read from a dead thread. */ - if (is_exited (inferior_ptid)) + if (tp->state == THREAD_EXITED) return 0; /* ... or from a spinning thread. */ - if (is_executing (inferior_ptid)) + if (tp->executing) return 0; } @@ -1721,23 +1720,6 @@ select_frame (struct frame_info *fi) } } -#if GDB_SELF_TEST -struct frame_info * -create_test_frame (struct regcache *regcache) -{ - struct frame_info *this_frame = XCNEW (struct frame_info); - - sentinel_frame = create_sentinel_frame (NULL, regcache); - sentinel_frame->prev = this_frame; - sentinel_frame->prev_p = 1;; - this_frame->prev_arch.p = 1; - this_frame->prev_arch.arch = get_regcache_arch (regcache); - this_frame->next = sentinel_frame; - - return this_frame; -} -#endif - /* Create an arbitrary (i.e. address specified by user) or innermost frame. Always returns a non-NULL value. */ @@ -1885,22 +1867,6 @@ frame_register_unwind_location (struct frame_info *this_frame, int regnum, } } -/* Called during frame unwinding to remove a previous frame pointer from a - frame passed in ARG. */ - -static void -remove_prev_frame (void *arg) -{ - struct frame_info *this_frame, *prev_frame; - - this_frame = (struct frame_info *) arg; - prev_frame = this_frame->prev; - gdb_assert (prev_frame != NULL); - - prev_frame->next = NULL; - this_frame->prev = NULL; -} - /* 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 @@ -1913,7 +1879,6 @@ static struct frame_info * get_prev_frame_if_no_cycle (struct frame_info *this_frame) { struct frame_info *prev_frame; - struct cleanup *prev_frame_cleanup; prev_frame = get_prev_frame_raw (this_frame); @@ -1929,29 +1894,35 @@ get_prev_frame_if_no_cycle (struct frame_info *this_frame) if (prev_frame->level == 0) return prev_frame; - /* The cleanup will remove the previous frame that get_prev_frame_raw - linked onto THIS_FRAME. */ - prev_frame_cleanup = make_cleanup (remove_prev_frame, this_frame); - - compute_frame_id (prev_frame); - if (!frame_stash_add (prev_frame)) + TRY { - /* Another frame with the same id was already in the stash. We just - detected a cycle. */ - if (frame_debug) + compute_frame_id (prev_frame); + if (!frame_stash_add (prev_frame)) { - fprintf_unfiltered (gdb_stdlog, "-> "); - fprint_frame (gdb_stdlog, NULL); - fprintf_unfiltered (gdb_stdlog, " // this frame has same ID }\n"); + /* Another frame with the same id was already in the stash. We just + detected a cycle. */ + if (frame_debug) + { + fprintf_unfiltered (gdb_stdlog, "-> "); + fprint_frame (gdb_stdlog, NULL); + fprintf_unfiltered (gdb_stdlog, " // this frame has same ID }\n"); + } + this_frame->stop_reason = UNWIND_SAME_ID; + /* Unlink. */ + prev_frame->next = NULL; + this_frame->prev = NULL; + prev_frame = NULL; } - this_frame->stop_reason = UNWIND_SAME_ID; - /* Unlink. */ + } + CATCH (ex, RETURN_MASK_ALL) + { prev_frame->next = NULL; this_frame->prev = NULL; - prev_frame = NULL; + + throw_exception (ex); } + END_CATCH - discard_cleanups (prev_frame_cleanup); return prev_frame; } @@ -2247,7 +2218,7 @@ inside_main_func (struct frame_info *this_frame) returned. */ maddr = gdbarch_convert_from_func_ptr_addr (get_frame_arch (this_frame), BMSYMBOL_VALUE_ADDRESS (msymbol), - ¤t_target); + current_top_target ()); return maddr == get_frame_func (this_frame); } @@ -2524,7 +2495,7 @@ find_frame_sal (frame_info *frame) if (next_frame) sym = get_frame_function (next_frame); else - sym = inline_skipped_symbol (inferior_ptid); + sym = inline_skipped_symbol (inferior_thread ()); /* If frame is inline, it certainly has symbols. */ gdb_assert (sym); @@ -2665,7 +2636,7 @@ frame_unwind_program_space (struct frame_info *this_frame) return this_frame->pspace; } -struct address_space * +const address_space * get_frame_address_space (struct frame_info *frame) { return frame->aspace; @@ -2806,18 +2777,9 @@ get_frame_sp (struct frame_info *this_frame) { struct gdbarch *gdbarch = get_frame_arch (this_frame); - /* Normality - an architecture that provides a way of obtaining any - frame inner-most address. */ - if (gdbarch_unwind_sp_p (gdbarch)) - /* NOTE drow/2008-06-28: gdbarch_unwind_sp could be converted to - operate on THIS_FRAME now. */ - return gdbarch_unwind_sp (gdbarch, this_frame->next); - /* Now things are really are grim. Hope that the value returned by - the gdbarch_sp_regnum register is meaningful. */ - if (gdbarch_sp_regnum (gdbarch) >= 0) - return get_frame_register_unsigned (this_frame, - gdbarch_sp_regnum (gdbarch)); - internal_error (__FILE__, __LINE__, _("Missing unwind SP method")); + /* NOTE drow/2008-06-28: gdbarch_unwind_sp could be converted to + operate on THIS_FRAME now. */ + return gdbarch_unwind_sp (gdbarch, this_frame->next); } /* Return the reason why we can't unwind past FRAME. */ @@ -2886,11 +2848,9 @@ frame_stop_reason_symbol_string (enum unwind_stop_reason reason) /* Clean up after a failed (wrong unwinder) attempt to unwind past FRAME. */ -static void -frame_cleanup_after_sniffer (void *arg) +void +frame_cleanup_after_sniffer (struct frame_info *frame) { - struct frame_info *frame = (struct frame_info *) arg; - /* The sniffer should not allocate a prologue cache if it did not match this frame. */ gdb_assert (frame->prologue_cache == NULL); @@ -2915,30 +2875,29 @@ frame_cleanup_after_sniffer (void *arg) } /* Set FRAME's unwinder temporarily, so that we can call a sniffer. - Return a cleanup which should be called if unwinding fails, and - discarded if it succeeds. */ + If sniffing fails, the caller should be sure to call + frame_cleanup_after_sniffer. */ -struct cleanup * +void frame_prepare_for_sniffer (struct frame_info *frame, const struct frame_unwind *unwind) { gdb_assert (frame->unwind == NULL); frame->unwind = unwind; - return make_cleanup (frame_cleanup_after_sniffer, frame); } static struct cmd_list_element *set_backtrace_cmdlist; static struct cmd_list_element *show_backtrace_cmdlist; static void -set_backtrace_cmd (char *args, int from_tty) +set_backtrace_cmd (const char *args, int from_tty) { help_list (set_backtrace_cmdlist, "set backtrace ", all_commands, gdb_stdout); } static void -show_backtrace_cmd (char *args, int from_tty) +show_backtrace_cmd (const char *args, int from_tty) { cmd_show_list (show_backtrace_cmdlist, from_tty, ""); } @@ -2950,7 +2909,7 @@ _initialize_frame (void) frame_stash_create (); - observer_attach_target_changed (frame_observer_target_changed); + gdb::observers::target_changed.attach (frame_observer_target_changed); add_prefix_cmd ("backtrace", class_maintenance, set_backtrace_cmd, _("\ Set backtrace specific variables.\n\