/* Cache and manage frames for GDB, the GNU debugger.
- Copyright (C) 1986-2015 Free Software Foundation, Inc.
+ Copyright (C) 1986-2017 Free Software Foundation, Inc.
This file is part of GDB.
#include "hashtab.h"
#include "valprint.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. */
+
+static struct frame_info *sentinel_frame;
+
static struct frame_info *get_prev_frame_raw (struct frame_info *this_frame);
static const char *frame_stop_reason_symbol_string (enum unwind_stop_reason reason);
/* 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; current_frame
+ 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
static hashval_t
frame_addr_hash (const void *ap)
{
- const struct frame_info *frame = ap;
+ const struct frame_info *frame = (const struct frame_info *) ap;
const struct frame_id f_id = frame->this_id.value;
hashval_t hash = 0;
static int
frame_addr_hash_eq (const void *a, const void *b)
{
- const struct frame_info *f_entry = a;
- const struct frame_info *f_element = b;
+ const struct frame_info *f_entry = (const struct frame_info *) a;
+ const struct frame_info *f_element = (const struct frame_info *) b;
return frame_id_eq (f_entry->this_id.value,
f_element->this_id.value);
struct frame_info *frame;
dummy.this_id.value = id;
- frame = htab_find (frame_stash, &dummy);
+ frame = (struct frame_info *) htab_find (frame_stash, &dummy);
return frame;
}
fprintf_unfiltered (file, "!stack");
else if (id.stack_status == FID_STACK_UNAVAILABLE)
fprintf_unfiltered (file, "stack=<unavailable>");
+ else if (id.stack_status == FID_STACK_SENTINEL)
+ fprintf_unfiltered (file, "stack=<sentinel>");
else
fprintf_unfiltered (file, "stack=%s", hex_string (id.stack_addr));
fprintf_unfiltered (file, ",");
/* 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 the original frame if no immediate previous frames exist. */
+ Return FRAME if FRAME is a non-artificial frame.
+ Return NULL if FRAME is the start of an artificial-only chain. */
static struct frame_info *
skip_artificial_frames (struct frame_info *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). This is safe, because as these frames
- are made up by GDB, there must be a real frame in the chain
- below. */
+ sets a backtrace limit).
+
+ Note that for record targets we may get a frame chain that consists
+ of artificial frames only. */
while (get_frame_type (frame) == INLINE_FRAME
|| get_frame_type (frame) == TAILCALL_FRAME)
- frame = get_prev_frame_always (frame);
+ {
+ frame = get_prev_frame_always (frame);
+ if (frame == NULL)
+ break;
+ }
+
+ return frame;
+}
+
+struct frame_info *
+skip_unwritable_frames (struct frame_info *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. */
+
+struct frame_info *
+skip_tailcall_frames (struct frame_info *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;
}
if (fi == NULL)
return null_frame_id;
- gdb_assert (fi->this_id.p);
+ if (!fi->this_id.p)
+ {
+ int stashed;
+
+ /* 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. */
+ stashed = frame_stash_add (fi);
+ gdb_assert (stashed);
+ }
+
return fi->this_id.value;
}
requests the frame ID of "main()"s caller. */
next_frame = skip_artificial_frames (next_frame);
+ if (next_frame == NULL)
+ return null_frame_id;
+
this_frame = get_prev_frame_always (next_frame);
if (this_frame)
return get_frame_id (skip_artificial_frames (this_frame));
return null_frame_id;
}
-const struct frame_id null_frame_id; /* All zeros. */
+const struct frame_id null_frame_id = { 0 }; /* All zeros. */
+const struct frame_id sentinel_frame_id = { 0, 0, 0, FID_STACK_SENTINEL, 0, 1, 0 };
const struct frame_id outer_frame_id = { 0, 0, 0, FID_STACK_INVALID, 0, 1, 0 };
struct frame_id
if (!frame_id_p (id))
return NULL;
+ /* Check for the sentinel frame. */
+ if (frame_id_eq (id, sentinel_frame_id))
+ return 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)
CORE_ADDR
frame_unwind_caller_pc (struct frame_info *this_frame)
{
- return frame_unwind_pc (skip_artificial_frames (this_frame));
+ this_frame = skip_artificial_frames (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 != NULL);
+
+ return frame_unwind_pc (this_frame);
}
int
static enum register_status
do_frame_register_read (void *src, int regnum, gdb_byte *buf)
{
- if (!deprecated_frame_register_read (src, regnum, buf))
+ if (!deprecated_frame_register_read ((struct frame_info *) src, regnum, buf))
return REG_UNAVAILABLE;
else
return REG_VALID;
/* Ignore TAILCALL_FRAME type frames, they were executed already before
entering THISFRAME. */
- while (get_frame_type (prev_frame) == TAILCALL_FRAME)
- prev_frame = get_prev_frame (prev_frame);
+ 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
*unavailablep = !value_entirely_available (value);
*lvalp = VALUE_LVAL (value);
*addrp = value_address (value);
- *realnump = VALUE_REGNUM (value);
+ if (*lvalp == lval_register)
+ *realnump = VALUE_REGNUM (value);
+ else
+ *realnump = -1;
if (bufferp)
{
}
else
{
- gdb_byte buf[MAX_REGISTER_SIZE];
- enum lval_type lval;
- CORE_ADDR addr;
- int realnum;
+ struct value *value = frame_unwind_register_value (frame->next,
+ regnum);
+ gdb_assert (value != NULL);
+ *optimizedp = value_optimized_out (value);
+ *unavailablep = !value_entirely_available (value);
- frame_register (frame, regnum, optimizedp, unavailablep,
- &lval, &addr, &realnum, buf);
if (*optimizedp || *unavailablep)
- return 0;
- memcpy (myaddr, buf + offset, curr_len);
+ {
+ 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;
}
else
{
- gdb_byte buf[MAX_REGISTER_SIZE];
-
- deprecated_frame_register_read (frame, regnum, buf);
- memcpy (buf + offset, myaddr, curr_len);
- put_frame_register (frame, regnum, buf);
+ struct value *value = frame_unwind_register_value (frame->next,
+ regnum);
+ gdb_assert (value != NULL);
+
+ memcpy ((char *) value_contents_writeable (value) + offset, myaddr,
+ curr_len);
+ put_frame_register (frame, regnum, value_contents_raw (value));
+ release_value (value);
+ value_free (value);
}
myaddr += curr_len;
/* 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;
- /* Make the sentinel frame's ID valid, but invalid. That way all
- comparisons with it should fail. */
+ /* The sentinel frame has a special ID. */
frame->this_id.p = 1;
- frame->this_id.value = null_frame_id;
+ frame->this_id.value = sentinel_frame_id;
if (frame_debug)
{
fprintf_unfiltered (gdb_stdlog, "{ create_sentinel_frame (...) -> ");
return frame;
}
-/* Info about the innermost stack frame (contents of FP register). */
-
-static struct frame_info *current_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. */
return data;
}
-/* Return the innermost (currently executing) stack frame. This is
- split into two functions. The function unwind_to_current_frame()
- is wrapped in catch exceptions so that, even when the unwind of the
- sentinel frame fails, the function still returns a stack frame. */
-
-static int
-unwind_to_current_frame (struct ui_out *ui_out, void *args)
-{
- struct frame_info *frame = get_prev_frame (args);
-
- /* A sentinel frame can fail to unwind, e.g., because its PC value
- lands in somewhere like start. */
- if (frame == NULL)
- return 1;
- current_frame = frame;
- return 0;
-}
+static struct frame_info *get_prev_frame_always_1 (struct frame_info *this_frame);
struct frame_info *
get_current_frame (void)
{
+ struct frame_info *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"
error (_("No memory."));
/* Traceframes are effectively a substitute for the live inferior. */
if (get_traceframe_number () < 0)
- {
- if (ptid_equal (inferior_ptid, null_ptid))
- error (_("No selected thread."));
- if (is_exited (inferior_ptid))
- error (_("Invalid selected thread."));
- if (is_executing (inferior_ptid))
- error (_("Target is executing."));
- }
+ validate_registers_access ();
+
+ if (sentinel_frame == NULL)
+ sentinel_frame =
+ create_sentinel_frame (current_program_space, get_current_regcache ());
+
+ /* 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 (sentinel_frame);
+ gdb_assert (current_frame != NULL);
- if (current_frame == NULL)
- {
- struct frame_info *sentinel_frame =
- create_sentinel_frame (current_program_space, get_current_regcache ());
- if (catch_exceptions (current_uiout, unwind_to_current_frame,
- sentinel_frame, RETURN_MASK_ERROR) != 0)
- {
- /* Oops! Fake a current frame? Is this useful? It has a PC
- of zero, for instance. */
- current_frame = sentinel_frame;
- }
- }
return current_frame;
}
selected_frame = fi;
/* NOTE: cagney/2002-05-04: FI can be NULL. This occurs when the
frame is being invalidated. */
- if (deprecated_selected_frame_level_changed_hook)
- deprecated_selected_frame_level_changed_hook (frame_relative_level (fi));
/* FIXME: kseitz/2002-08-28: It would be nice to call
selected_frame_level_changed_event() right here, but due to limitations
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. */
+
+struct frame_info *
+get_next_frame_sentinel_okay (struct frame_info *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. */
+ gdb_assert (this_frame != sentinel_frame);
+
+ return this_frame->next;
+}
+
/* Observer for the target_changed event. */
static void
struct frame_info *fi;
/* Tear down all frame caches. */
- for (fi = current_frame; fi != NULL; fi = fi->prev)
+ for (fi = sentinel_frame; fi != NULL; fi = fi->prev)
{
if (fi->prologue_cache && fi->unwind->dealloc_cache)
fi->unwind->dealloc_cache (fi, fi->prologue_cache);
obstack_free (&frame_cache_obstack, 0);
obstack_init (&frame_cache_obstack);
- if (current_frame != NULL)
+ if (sentinel_frame != NULL)
annotate_frames_invalid ();
- current_frame = NULL; /* Invalidate cache */
+ sentinel_frame = NULL; /* Invalidate cache */
select_frame (NULL);
frame_stash_invalidate ();
if (frame_debug)
struct cleanup *prev_frame_cleanup;
prev_frame = get_prev_frame_raw (this_frame);
- if (prev_frame == NULL)
- return NULL;
+
+ /* 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;
/* The cleanup will remove the previous frame that get_prev_frame_raw
linked onto THIS_FRAME. */
pointer to the frame, this allows the STOP_STRING on the
frame to be of type 'const char *'. */
size = strlen (ex.message) + 1;
- stop_string = frame_obstack_zalloc (size);
+ stop_string = (char *) frame_obstack_zalloc (size);
memcpy (stop_string, ex.message, size);
this_frame->stop_string = stop_string;
}
something should be calling get_selected_frame() or
get_current_frame(). */
gdb_assert (this_frame != NULL);
+
+ /* 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. */
+ if (this_frame->level == 0)
+ get_frame_id (this_frame);
+
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
return get_prev_frame_always (this_frame);
}
+struct frame_id
+get_prev_frame_id_by_id (struct frame_id id)
+{
+ struct frame_id prev_id;
+ struct frame_info *frame;
+
+ frame = frame_find_by_id (id);
+
+ if (frame != NULL)
+ prev_id = get_frame_id (get_prev_frame (frame));
+ else
+ prev_id = null_frame_id;
+
+ return prev_id;
+}
+
CORE_ADDR
get_frame_pc (struct frame_info *frame)
{
struct gdbarch *
frame_unwind_caller_arch (struct frame_info *next_frame)
{
- return frame_unwind_arch (skip_artificial_frames (next_frame));
+ next_frame = skip_artificial_frames (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 != NULL);
+
+ return frame_unwind_arch (next_frame);
+}
+
+/* Gets the language of FRAME. */
+
+enum language
+get_frame_language (struct frame_info *frame)
+{
+ CORE_ADDR pc = 0;
+ int pc_p = 0;
+
+ 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 = 1;
+ }
+ CATCH (ex, RETURN_MASK_ERROR)
+ {
+ if (ex.error != NOT_AVAILABLE_ERROR)
+ throw_exception (ex);
+ }
+ END_CATCH
+
+ if (pc_p)
+ {
+ struct compunit_symtab *cust = find_pc_compunit_symtab (pc);
+
+ if (cust != NULL)
+ return compunit_language (cust);
+ }
+
+ return language_unknown;
}
/* Stack pointer methods. */
static void
frame_cleanup_after_sniffer (void *arg)
{
- struct frame_info *frame = arg;
+ struct frame_info *frame = (struct frame_info *) arg;
/* The sniffer should not allocate a prologue cache if it did not
match this frame. */