/* Definitions for dealing with stack frames, for GDB, the GNU debugger.
- Copyright (C) 1986-2017 Free Software Foundation, Inc.
+ Copyright (C) 1986-2021 Free Software Foundation, Inc.
This file is part of GDB.
#define FRAME_H 1
/* The following is the intended naming schema for frame functions.
- It isn't 100% consistent, but it is aproaching that. Frame naming
+ It isn't 100% consistent, but it is approaching that. Frame naming
schema:
Prefixes:
- get_frame_WHAT...(): Get WHAT from the THIS frame (functionaly
+ get_frame_WHAT...(): Get WHAT from the THIS frame (functionally
equivalent to THIS->next->unwind->what)
frame_unwind_WHAT...(): Unwind THIS frame's WHAT from the NEXT
strongly hinting at its unsafeness)
safe_....(): Safer version of various functions, doesn't throw an
- error (leave this for later?). Returns non-zero / non-NULL if the
- request succeeds, zero / NULL otherwize.
+ error (leave this for later?). Returns true / non-NULL if the request
+ succeeds, false / NULL otherwise.
Suffixes:
*/
#include "language.h"
+#include "cli/cli-option.h"
struct symtab_and_line;
struct frame_unwind;
struct gdbarch;
struct ui_file;
struct ui_out;
+struct frame_print_options;
/* Status of a given frame's stack. */
enum frame_id_stack_status
{
- /* Stack address is invalid. E.g., this frame is the outermost
- (i.e., _start), and the stack hasn't been setup yet. */
+ /* Stack address is invalid. */
FID_STACK_INVALID = 0,
/* Stack address is valid, and is found in the stack_addr field. */
/* Sentinel frame. */
FID_STACK_SENTINEL = 2,
+ /* Outer frame. Since a frame's stack address is typically defined as the
+ value the stack pointer had prior to the activation of the frame, an outer
+ frame doesn't have a stack address. The frame ids of frames inlined in the
+ outer frame are also of this type. */
+ FID_STACK_OUTER = 3,
+
/* Stack address is unavailable. I.e., there's a valid stack, but
we don't know where it is (because memory or registers we'd
compute it from were not collected). */
/* The frame's special address. This shall be constant through out the
lifetime of the frame. This is used for architectures that may have
- frames that do not change the stack but are still distinct and have
- some form of distinct identifier (e.g. the ia64 which uses a 2nd
+ frames that do not change the stack but are still distinct and have
+ some form of distinct identifier (e.g. the ia64 which uses a 2nd
stack for registers). This field is treated as unordered - i.e. will
not be used in frame ordering comparisons.
Caller of inlined function will have it zero, each more inner called frame
will have it increasingly one, two etc. Similarly for TAILCALL_FRAME. */
int artificial_depth;
+
+ /* Return a string representation of this frame id. */
+ std::string to_string () const;
+};
+
+/* Save and restore the currently selected frame. */
+
+class scoped_restore_selected_frame
+{
+public:
+ /* Save the currently selected frame. */
+ scoped_restore_selected_frame ();
+
+ /* Restore the currently selected frame. */
+ ~scoped_restore_selected_frame ();
+
+ DISABLE_COPY_AND_ASSIGN (scoped_restore_selected_frame);
+
+private:
+
+ /* The ID and level of the previously selected frame. */
+ struct frame_id m_fid;
+ int m_level;
+
+ /* Save/restore the language as well, because selecting a frame
+ changes the current language to the frame's language if "set
+ language auto". */
+ enum language m_lang;
};
/* Methods for constructing and comparing Frame IDs. */
as the special identifier address are set to indicate wild cards. */
extern struct frame_id frame_id_build_wild (CORE_ADDR stack_addr);
-/* Returns non-zero when L is a valid frame (a valid frame has a
- non-zero .base). The outermost frame is valid even without an
- ID. */
-extern int frame_id_p (struct frame_id l);
+/* Returns true when L is a valid frame. */
+extern bool frame_id_p (frame_id l);
-/* Returns non-zero when L is a valid frame representing a frame made up by GDB
+/* Returns true when L is a valid frame representing a frame made up by GDB
without stack data representation in inferior, such as INLINE_FRAME or
TAILCALL_FRAME. */
-extern int frame_id_artificial_p (struct frame_id l);
-
-/* Returns non-zero when L and R identify the same frame, or, if
- either L or R have a zero .func, then the same frame base. */
-extern int frame_id_eq (struct frame_id l, struct frame_id r);
-
-/* Write the internal representation of a frame ID on the specified
- stream. */
-extern void fprint_frame_id (struct ui_file *file, struct frame_id id);
+extern bool frame_id_artificial_p (frame_id l);
+/* Returns true when L and R identify the same frame. */
+extern bool frame_id_eq (frame_id l, frame_id r);
/* Frame types. Some are real, some are signal trampolines, and some
are completely artificial (dummy). */
/* Does the current target interface have enough state to be able to
query the current inferior for frame info, and is the inferior in a
state where that is possible? */
-extern int has_stack_frames (void);
+extern bool has_stack_frames ();
/* Invalidates the frame cache (this function should have been called
invalidate_cached_frames).
modifies the target invalidating the frame cache). */
extern void reinit_frame_cache (void);
-/* On demand, create the selected frame and then return it. If the
- selected frame can not be created, this function prints then throws
- an error. When MESSAGE is non-NULL, use it for the error message,
- otherwize use a generic error message. */
+/* Return the selected frame. Always returns non-NULL. If there
+ isn't an inferior sufficient for creating a frame, an error is
+ thrown. When MESSAGE is non-NULL, use it for the error message,
+ otherwise use a generic error message. */
/* FIXME: cagney/2002-11-28: At present, when there is no selected
frame, this function always returns the current (inner most) frame.
It should instead, when a thread has previously had its frame
selected (but not resumed) and the frame cache invalidated, find
and then return that thread's previously selected frame. */
-extern struct frame_info *get_selected_frame (const char *message);
-
-/* If there is a selected frame, return it. Otherwise, return NULL. */
-extern struct frame_info *get_selected_frame_if_set (void);
+extern struct frame_info *get_selected_frame (const char *message = nullptr);
-/* Select a specific frame. NULL, apparently implies re-select the
- inner most frame. */
+/* Select a specific frame. NULL implies re-select the inner most
+ frame. */
extern void select_frame (struct frame_info *);
+/* Save the frame ID and frame level of the selected frame in FRAME_ID
+ and FRAME_LEVEL, to be restored later with restore_selected_frame.
+
+ This is preferred over getting the same info out of
+ get_selected_frame directly because this function does not create
+ the selected-frame's frame_info object if it hasn't been created
+ yet, and thus is more efficient and doesn't throw. */
+extern void save_selected_frame (frame_id *frame_id, int *frame_level)
+ noexcept;
+
+/* Restore selected frame as saved with save_selected_frame.
+
+ Does not try to find the corresponding frame_info object. Instead
+ the next call to get_selected_frame will look it up and cache the
+ result.
+
+ This function does not throw. It is designed to be safe to called
+ from the destructors of RAII types. */
+extern void restore_selected_frame (frame_id frame_id, int frame_level)
+ noexcept;
+
+/* 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. */
+extern void lookup_selected_frame (frame_id frame_id, int frame_level);
+
/* Given a FRAME, return the next (more inner, younger) or previous
(more outer, older) frame. */
extern struct frame_info *get_prev_frame (struct frame_info *);
/* Same as get_frame_pc, but return a boolean indication of whether
the PC is actually available, instead of throwing an error. */
-extern int get_frame_pc_if_available (struct frame_info *frame,
- CORE_ADDR *pc);
+extern bool get_frame_pc_if_available (frame_info *frame, CORE_ADDR *pc);
/* An address (not necessarily aligned to an instruction boundary)
that falls within THIS frame's code block.
PC is unavailable, it will not be), instead of possibly throwing an
error trying to read an unavailable PC. */
-extern int
- get_frame_address_in_block_if_available (struct frame_info *this_frame,
- CORE_ADDR *pc);
+extern bool get_frame_address_in_block_if_available (frame_info *this_frame,
+ CORE_ADDR *pc);
/* The frame's inner-most bound. AKA the stack-pointer. Confusingly
known as top-of-stack. */
will not be), instead of possibly throwing an error trying to read
an unavailable PC. */
-extern int get_frame_func_if_available (struct frame_info *fi, CORE_ADDR *);
+extern bool get_frame_func_if_available (frame_info *fi, CORE_ADDR *);
/* Closely related to the resume address, various symbol table
attributes that are determined by the PC. Note that for a normal
(up, older) frame is returned. If VALUEP is NULL, don't
fetch/compute the value. Instead just return the location of the
value. */
-extern void frame_register_unwind (struct frame_info *frame, int regnum,
+extern void frame_register_unwind (frame_info *frame, int regnum,
int *optimizedp, int *unavailablep,
enum lval_type *lvalp,
CORE_ADDR *addrp, int *realnump,
fetch fails. The value methods never return NULL, but usually
do return a lazy value. */
-extern void frame_unwind_register (struct frame_info *frame,
+extern void frame_unwind_register (frame_info *next_frame,
int regnum, gdb_byte *buf);
extern void get_frame_register (struct frame_info *frame,
int regnum, gdb_byte *buf);
-struct value *frame_unwind_register_value (struct frame_info *frame,
+struct value *frame_unwind_register_value (frame_info *next_frame,
int regnum);
struct value *get_frame_register_value (struct frame_info *frame,
int regnum);
-extern LONGEST frame_unwind_register_signed (struct frame_info *frame,
+extern LONGEST frame_unwind_register_signed (frame_info *next_frame,
int regnum);
extern LONGEST get_frame_register_signed (struct frame_info *frame,
int regnum);
-extern ULONGEST frame_unwind_register_unsigned (struct frame_info *frame,
- int regnum);
+extern ULONGEST frame_unwind_register_unsigned (frame_info *frame,
+ int regnum);
extern ULONGEST get_frame_register_unsigned (struct frame_info *frame,
int regnum);
get_frame_register_value, that do not throw if the result is
optimized out or unavailable. */
-extern int read_frame_register_unsigned (struct frame_info *frame,
- int regnum, ULONGEST *val);
+extern bool read_frame_register_unsigned (frame_info *frame,
+ int regnum, ULONGEST *val);
/* Get the value of the register that belongs to this FRAME. This
function is a wrapper to the call sequence ``frame_register_unwind
in frame FRAME, starting at OFFSET, into BUF. If the register
contents are optimized out or unavailable, set *OPTIMIZEDP,
*UNAVAILABLEP accordingly. */
-extern int get_frame_register_bytes (struct frame_info *frame, int regnum,
- CORE_ADDR offset, int len,
- gdb_byte *myaddr,
- int *optimizedp, int *unavailablep);
+extern bool get_frame_register_bytes (frame_info *frame, int regnum,
+ CORE_ADDR offset,
+ gdb::array_view<gdb_byte> buffer,
+ int *optimizedp, int *unavailablep);
-/* Write LEN bytes to one or multiple registers starting with REGNUM
- in frame FRAME, starting at OFFSET, into BUF. */
+/* Write bytes from BUFFER to one or multiple registers starting with REGNUM
+ in frame FRAME, starting at OFFSET. */
extern void put_frame_register_bytes (struct frame_info *frame, int regnum,
- CORE_ADDR offset, int len,
- const gdb_byte *myaddr);
+ CORE_ADDR offset,
+ gdb::array_view<const gdb_byte> buffer);
/* Unwind the PC. Strictly speaking return the resume address of the
calling frame. For GDB, `pc' is the resume address and not a
adaptor frames this should be ok. */
extern void get_frame_memory (struct frame_info *this_frame, CORE_ADDR addr,
- gdb_byte *buf, int len);
+ gdb::array_view<gdb_byte> buffer);
extern LONGEST get_frame_memory_signed (struct frame_info *this_frame,
CORE_ADDR memaddr, int len);
extern ULONGEST get_frame_memory_unsigned (struct frame_info *this_frame,
CORE_ADDR memaddr, int len);
-/* Same as above, but return non-zero when the entire memory read
- succeeds, zero otherwize. */
-extern int safe_frame_unwind_memory (struct frame_info *this_frame,
- CORE_ADDR addr, gdb_byte *buf, int len);
+/* Same as above, but return true zero when the entire memory read
+ succeeds, false otherwise. */
+extern bool safe_frame_unwind_memory (frame_info *this_frame, CORE_ADDR addr,
+ gdb::array_view<gdb_byte> buffer);
/* Return this frame's architecture. */
extern struct gdbarch *get_frame_arch (struct frame_info *this_frame);
/* Return the previous frame's architecture. */
-extern struct gdbarch *frame_unwind_arch (struct frame_info *frame);
+extern struct gdbarch *frame_unwind_arch (frame_info *next_frame);
/* Return the previous frame's architecture, skipping inline functions. */
extern struct gdbarch *frame_unwind_caller_arch (struct frame_info *frame);
-/* Values for the source flag to be used in print_frame_info_base(). */
+/* Values for the source flag to be used in print_frame_info ().
+ For all the cases below, the address is never printed if
+ 'set print address' is off. When 'set print address' is on,
+ the address is printed if the program counter is not at the
+ beginning of the source line of the frame
+ and PRINT_WHAT is != LOC_AND_ADDRESS. */
enum print_what
- {
- /* Print only the source line, like in stepi. */
- SRC_LINE = -1,
- /* Print only the location, i.e. level, address (sometimes)
- function, args, file, line, line num. */
+ {
+ /* Print only the address, source line, like in stepi. */
+ SRC_LINE = -1,
+ /* Print only the location, i.e. level, address,
+ function, args (as controlled by 'set print frame-arguments'),
+ file, line, line num. */
LOCATION,
/* Print both of the above. */
- SRC_AND_LOC,
- /* Print location only, but always include the address. */
- LOC_AND_ADDRESS
+ SRC_AND_LOC,
+ /* Print location only, print the address even if the program counter
+ is at the beginning of the source line. */
+ LOC_AND_ADDRESS,
+ /* Print only level and function,
+ i.e. location only, without address, file, line, line num. */
+ SHORT_LOCATION
};
/* Allocate zero initialized memory from the frame cache obstack.
#define FRAME_OBSTACK_CALLOC(NUMBER,TYPE) \
((TYPE *) frame_obstack_zalloc ((NUMBER) * sizeof (TYPE)))
+class readonly_detached_regcache;
/* Create a regcache, and copy the frame's registers into it. */
-std::unique_ptr<struct regcache> frame_save_as_regcache
+std::unique_ptr<readonly_detached_regcache> frame_save_as_regcache
(struct frame_info *this_frame);
extern const struct block *get_frame_block (struct frame_info *,
enum print_what print_what,
int set_current_sal);
-extern void print_frame_info (struct frame_info *, int print_level,
+extern void print_frame_info (const frame_print_options &fp_opts,
+ struct frame_info *, int print_level,
enum print_what print_what, int args,
int set_current_sal);
extern struct frame_info *block_innermost_frame (const struct block *);
-extern int deprecated_frame_register_read (struct frame_info *frame, int regnum,
- gdb_byte *buf);
+extern bool deprecated_frame_register_read (frame_info *frame, int regnum,
+ gdb_byte *buf);
/* From stack.c. */
+/* The possible choices of "set print frame-arguments". */
+extern const char print_frame_arguments_all[];
+extern const char print_frame_arguments_scalars[];
+extern const char print_frame_arguments_none[];
+
+/* The possible choices of "set print frame-info". */
+extern const char print_frame_info_auto[];
+extern const char print_frame_info_source_line[];
+extern const char print_frame_info_location[];
+extern const char print_frame_info_source_and_location[];
+extern const char print_frame_info_location_and_address[];
+extern const char print_frame_info_short_location[];
+
+/* The possible choices of "set print entry-values". */
extern const char print_entry_values_no[];
extern const char print_entry_values_only[];
extern const char print_entry_values_preferred[];
extern const char print_entry_values_both[];
extern const char print_entry_values_compact[];
extern const char print_entry_values_default[];
-extern const char *print_entry_values;
+
+/* Data for the frame-printing "set print" settings exposed as command
+ options. */
+
+struct frame_print_options
+{
+ const char *print_frame_arguments = print_frame_arguments_scalars;
+ const char *print_frame_info = print_frame_info_auto;
+ const char *print_entry_values = print_entry_values_default;
+
+ /* If true, don't invoke pretty-printers for frame
+ arguments. */
+ bool print_raw_frame_arguments;
+};
+
+/* The values behind the global "set print ..." settings. */
+extern frame_print_options user_frame_print_options;
/* Inferior function parameter value read in from a frame. */
struct frame_arg
{
/* Symbol for this parameter used for example for its name. */
- struct symbol *sym;
+ struct symbol *sym = nullptr;
/* Value of the parameter. It is NULL if ERROR is not NULL; if both VAL and
ERROR are NULL this parameter's value should not be printed. */
- struct value *val;
+ struct value *val = nullptr;
/* String containing the error message, it is more usually NULL indicating no
error occured reading this parameter. */
- char *error;
+ gdb::unique_xmalloc_ptr<char> error;
/* One of the print_entry_values_* entries as appropriate specifically for
this frame_arg. It will be different from print_entry_values. With
value - print_entry_values_compact is not permitted fi ui_out_is_mi_like_p
(in such case print_entry_values_no and print_entry_values_only is used
for each parameter kind specifically. */
- const char *entry_kind;
+ const char *entry_kind = nullptr;
};
-extern void read_frame_arg (struct symbol *sym, struct frame_info *frame,
+extern void read_frame_arg (const frame_print_options &fp_opts,
+ symbol *sym, frame_info *frame,
struct frame_arg *argp,
struct frame_arg *entryargp);
extern void read_frame_local (struct symbol *sym, struct frame_info *frame,
struct frame_arg *argp);
-extern void info_args_command (char *, int);
+extern void info_args_command (const char *, int);
-extern void info_locals_command (char *, int);
+extern void info_locals_command (const char *, int);
-extern void return_command (char *, int);
+extern void return_command (const char *, int);
/* Set FRAME's unwinder temporarily, so that we can call a sniffer.
If sniffing fails, the caller should be sure to call
/* Return true if the frame unwinder for frame FI is UNWINDER; false
otherwise. */
-extern int frame_unwinder_is (struct frame_info *fi,
- const struct frame_unwind *unwinder);
+extern bool frame_unwinder_is (frame_info *fi, const frame_unwind *unwinder);
/* Return the language of FRAME. */
extern struct frame_info *skip_unwritable_frames (struct frame_info *frame);
+/* Data for the "set backtrace" settings. */
+
+struct set_backtrace_options
+{
+ /* Flag to indicate whether backtraces should continue past
+ main. */
+ bool backtrace_past_main = false;
+
+ /* Flag to indicate whether backtraces should continue past
+ entry. */
+ bool backtrace_past_entry = false;
+
+ /* Upper bound on the number of backtrace levels. Note this is not
+ exposed as a command option, because "backtrace" and "frame
+ apply" already have other means to set a frame count limit. */
+ unsigned int backtrace_limit = UINT_MAX;
+};
+
+/* The corresponding option definitions. */
+extern const gdb::option::option_def set_backtrace_option_defs[2];
+
+/* The values behind the global "set backtrace ..." settings. */
+extern set_backtrace_options user_set_backtrace_options;
+
+/* Get the number of calls to reinit_frame_cache. */
+
+unsigned int get_frame_cache_generation ();
+
+/* Mark that the PC value is masked for the previous frame. */
+
+extern void set_frame_previous_pc_masked (struct frame_info *frame);
+
+/* Get whether the PC value is masked for the given frame. */
+
+extern bool get_frame_pc_masked (const struct frame_info *frame);
+
+
#endif /* !defined (FRAME_H) */