Compare commits

...

3 Commits

Author SHA1 Message Date
Guinevere Larsen
840e48cd7c gdb: add "unwinder class" to frame unwinders
A future patch will add a way to disable certain unwinders based on
different characteristics. This patch aims done to make it more
convenient to disable related unwinders in bulk, such as architecture
specific ones, by indentifying all unwinders by which part of the code
adds it. The classes, and explanations, are as follows:

* GDB: An internal unwinder, added by GDB core, such as the unwinder
  for dummy frames;
* EXTENSION: Unwinders added by extension languages;
* DEBUGINFO: Unwinders installed by the debug info reader;
* ARCH: Unwinders installed by the architecture specific code.
2024-02-16 18:30:24 +01:00
Fedora GDB patches
fb054b5e08 gdb/testsuite: Test for a backtrace through object without debuginfo
Fedora has been carrying this test since back in the Project Archer
days. A change back then caused GDB to stop being able to backtrace when
only some of the object files had debug information. Even though the
changed code never seems to have made its way into the main GDB project,
I think it makes sense to bring the test along to ensure something like
this doesn't pass unnoticed.
2024-02-14 15:38:26 +01:00
Guinevere Larsen
e961aad01f gdb: make gdbarch store a vector of frame unwinders
Before this commit, all frame unwinders would be stored in the obstack
of a gdbarch and accessed by using the registry system. This made for
unwieldy code, and unnecessarily complex logic in the frame_unwinder
implementation, along with making frame_unwind structs be unable to have
non-trivial constructors.

Seeing as a future patch of this series wants to refactor the
frame_unwind struct to use inheritance, obstack storage would no longer
be viable. In preparation for that change, this commit adds an
std::vector to gdbarch to store the unwinders in.

There should be no user-visible changes.
2024-02-14 15:38:26 +01:00
86 changed files with 358 additions and 70 deletions

View File

@@ -1208,6 +1208,7 @@ static frame_unwind aarch64_prologue_unwind =
{
"aarch64 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
aarch64_prologue_frame_unwind_stop_reason,
aarch64_prologue_this_id,
aarch64_prologue_prev_register,
@@ -1303,6 +1304,7 @@ static frame_unwind aarch64_stub_unwind =
{
"aarch64 stub",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
aarch64_stub_frame_unwind_stop_reason,
aarch64_stub_this_id,
aarch64_prologue_prev_register,

View File

@@ -335,6 +335,7 @@ static const struct frame_unwind alpha_mdebug_frame_unwind =
{
"alpha mdebug",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
alpha_mdebug_frame_this_id,
alpha_mdebug_frame_prev_register,

View File

@@ -1011,6 +1011,7 @@ static const struct frame_unwind alpha_sigtramp_frame_unwind =
{
"alpha sigtramp",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
alpha_sigtramp_frame_this_id,
alpha_sigtramp_frame_prev_register,
@@ -1430,6 +1431,7 @@ static const struct frame_unwind alpha_heuristic_frame_unwind =
{
"alpha prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
alpha_heuristic_frame_this_id,
alpha_heuristic_frame_prev_register,

View File

@@ -409,6 +409,7 @@ static const struct frame_unwind amd64obsd_trapframe_unwind =
which really is not what we want here. */
"amd64 openbsd trap",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
amd64obsd_trapframe_this_id,
amd64obsd_trapframe_prev_register,

View File

@@ -2662,6 +2662,7 @@ static const struct frame_unwind amd64_frame_unwind =
{
"amd64 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
amd64_frame_unwind_stop_reason,
amd64_frame_this_id,
amd64_frame_prev_register,
@@ -2808,6 +2809,7 @@ static const struct frame_unwind amd64_sigtramp_frame_unwind =
{
"amd64 sigtramp",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
amd64_sigtramp_frame_unwind_stop_reason,
amd64_sigtramp_frame_this_id,
amd64_sigtramp_frame_prev_register,
@@ -3000,6 +3002,7 @@ static const struct frame_unwind amd64_epilogue_override_frame_unwind =
{
"amd64 epilogue override",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
amd64_epilogue_frame_unwind_stop_reason,
amd64_epilogue_frame_this_id,
amd64_frame_prev_register,
@@ -3011,6 +3014,7 @@ static const struct frame_unwind amd64_epilogue_frame_unwind =
{
"amd64 epilogue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
amd64_epilogue_frame_unwind_stop_reason,
amd64_epilogue_frame_this_id,
amd64_frame_prev_register,

View File

@@ -1185,6 +1185,7 @@ static const struct frame_unwind amd64_windows_frame_unwind =
{
"amd64 windows",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
&amd64_windows_frame_this_id,
&amd64_windows_frame_prev_register,

View File

@@ -895,6 +895,7 @@ amdgpu_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
static const frame_unwind amdgpu_frame_unwind = {
"amdgpu",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
amdgpu_frame_this_id,
amdgpu_frame_prev_register,

View File

@@ -1903,6 +1903,7 @@ arc_sigtramp_frame_sniffer (const struct frame_unwind *self,
static const struct frame_unwind arc_frame_unwind = {
"arc prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
arc_frame_this_id,
arc_frame_prev_register,
@@ -1919,6 +1920,7 @@ static const struct frame_unwind arc_frame_unwind = {
static const struct frame_unwind arc_sigtramp_frame_unwind = {
"arc sigtramp",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
arc_sigtramp_frame_this_id,
arc_sigtramp_frame_prev_register,

View File

@@ -1218,6 +1218,14 @@ obstack *gdbarch_obstack (gdbarch *arch)
/* See gdbarch.h. */
std::vector<const frame_unwind*>&
gdbarch_get_unwinder_list (struct gdbarch *arch)
{
return arch->unwinders;
}
/* See gdbarch.h. */
char *
gdbarch_obstack_strdup (struct gdbarch *arch, const char *string)
{

View File

@@ -2472,6 +2472,7 @@ arm_prologue_prev_register (frame_info_ptr this_frame,
static frame_unwind arm_prologue_unwind = {
"arm prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
arm_prologue_unwind_stop_reason,
arm_prologue_this_id,
arm_prologue_prev_register,
@@ -3191,6 +3192,7 @@ arm_exidx_unwind_sniffer (const struct frame_unwind *self,
struct frame_unwind arm_exidx_unwind = {
"arm exidx",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
arm_prologue_this_id,
arm_prologue_prev_register,
@@ -3301,6 +3303,7 @@ static const struct frame_unwind arm_epilogue_frame_unwind =
{
"arm epilogue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
arm_epilogue_frame_this_id,
arm_epilogue_frame_prev_register,
@@ -3430,6 +3433,7 @@ arm_stub_unwind_sniffer (const struct frame_unwind *self,
struct frame_unwind arm_stub_unwind = {
"arm stub",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
arm_stub_this_id,
arm_prologue_prev_register,
@@ -3956,6 +3960,7 @@ struct frame_unwind arm_m_exception_unwind =
{
"arm m exception lockup sec_fnc",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
arm_m_exception_frame_unwind_stop_reason,
arm_m_exception_this_id,
arm_m_exception_prev_register,

View File

@@ -1158,6 +1158,7 @@ avr_frame_prev_register (frame_info_ptr this_frame,
static const struct frame_unwind avr_frame_unwind = {
"avr prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
avr_frame_this_id,
avr_frame_prev_register,

View File

@@ -376,6 +376,7 @@ static const struct frame_unwind bfin_frame_unwind =
{
"bfin prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
bfin_frame_this_id,
bfin_frame_prev_register,

View File

@@ -186,6 +186,7 @@ static const struct frame_unwind bpf_frame_unwind =
{
"bpf prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
bpf_frame_unwind_stop_reason,
bpf_frame_this_id,
bpf_frame_prev_register,

View File

@@ -439,6 +439,7 @@ static const struct frame_unwind cris_sigtramp_frame_unwind =
{
"cris sigtramp",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
cris_sigtramp_frame_this_id,
cris_sigtramp_frame_prev_register,
@@ -904,6 +905,7 @@ static const struct frame_unwind cris_frame_unwind =
{
"cris prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
cris_frame_this_id,
cris_frame_prev_register,

View File

@@ -2162,6 +2162,7 @@ csky_frame_prev_register (frame_info_ptr this_frame,
static const struct frame_unwind csky_unwind_cache = {
"cski prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
csky_frame_this_id,
csky_frame_prev_register,
@@ -2296,6 +2297,7 @@ csky_stub_prev_register (frame_info_ptr this_frame,
static frame_unwind csky_stub_unwind = {
"csky stub",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
csky_stub_this_id,
csky_stub_prev_register,

View File

@@ -380,6 +380,7 @@ const struct frame_unwind dummy_frame_unwind =
{
"dummy",
DUMMY_FRAME,
FRAME_UNWIND_GDB,
default_frame_unwind_stop_reason,
dummy_frame_this_id,
dummy_frame_prev_register,

View File

@@ -473,6 +473,7 @@ const struct frame_unwind dwarf2_tailcall_frame_unwind =
{
"dwarf2 tailcall",
TAILCALL_FRAME,
FRAME_UNWIND_DEBUGINFO,
default_frame_unwind_stop_reason,
tailcall_frame_this_id,
tailcall_frame_prev_register,

View File

@@ -1344,6 +1344,7 @@ static const struct frame_unwind dwarf2_frame_unwind =
{
"dwarf2",
NORMAL_FRAME,
FRAME_UNWIND_DEBUGINFO,
dwarf2_frame_unwind_stop_reason,
dwarf2_frame_this_id,
dwarf2_frame_prev_register,
@@ -1356,6 +1357,7 @@ static const struct frame_unwind dwarf2_signal_frame_unwind =
{
"dwarf2 signal",
SIGTRAMP_FRAME,
FRAME_UNWIND_DEBUGINFO,
dwarf2_frame_unwind_stop_reason,
dwarf2_frame_this_id,
dwarf2_frame_prev_register,

View File

@@ -31,49 +31,16 @@
#include "cli/cli-cmds.h"
#include "inferior.h"
struct frame_unwind_table_entry
/* If an unwinder should be prepended to the list, this is the
index in which it should be inserted. */
static int osabi_start = -1;
/* Start the table out with a few default sniffers. OSABI code
can't override this. */
static void
initialize_frame_unwind_table (std::vector<const frame_unwind*>& table)
{
const struct frame_unwind *unwinder;
struct frame_unwind_table_entry *next;
};
struct frame_unwind_table
{
struct frame_unwind_table_entry *list = nullptr;
/* The head of the OSABI part of the search list. */
struct frame_unwind_table_entry **osabi_head = nullptr;
};
static const registry<gdbarch>::key<struct frame_unwind_table>
frame_unwind_data;
/* A helper function to add an unwinder to a list. LINK says where to
install the new unwinder. The new link is returned. */
static struct frame_unwind_table_entry **
add_unwinder (struct obstack *obstack, const struct frame_unwind *unwinder,
struct frame_unwind_table_entry **link)
{
*link = OBSTACK_ZALLOC (obstack, struct frame_unwind_table_entry);
(*link)->unwinder = unwinder;
return &(*link)->next;
}
static struct frame_unwind_table *
get_frame_unwind_table (struct gdbarch *gdbarch)
{
struct frame_unwind_table *table = frame_unwind_data.get (gdbarch);
if (table != nullptr)
return table;
table = new frame_unwind_table;
/* Start the table out with a few default sniffers. OSABI code
can't override this. */
struct frame_unwind_table_entry **link = &table->list;
struct obstack *obstack = gdbarch_obstack (gdbarch);
link = add_unwinder (obstack, &dummy_frame_unwind, link);
table.push_back (&dummy_frame_unwind);
/* The DWARF tailcall sniffer must come before the inline sniffer.
Otherwise, we can end up in a situation where a DWARF frame finds
tailcall information, but then the inline sniffer claims a frame
@@ -81,41 +48,71 @@ get_frame_unwind_table (struct gdbarch *gdbarch)
safe to do always because the tailcall sniffer can only ever be
activated if the newer frame was created using the DWARF
unwinder, and it also found tailcall information. */
link = add_unwinder (obstack, &dwarf2_tailcall_frame_unwind, link);
link = add_unwinder (obstack, &inline_frame_unwind, link);
table.push_back (&dwarf2_tailcall_frame_unwind);
table.push_back (&inline_frame_unwind);
/* The insertion point for OSABI sniffers. */
table->osabi_head = link;
frame_unwind_data.set (gdbarch, table);
osabi_start = table.size ();
}
/* This function call retrieves the list of frame unwinders available in
GDBARCH. If this list is empty, it is initialized before being
returned. */
static std::vector<const frame_unwind*>&
get_frame_unwind_table (struct gdbarch *gdbarch)
{
std::vector<const frame_unwind*>& table = gdbarch_get_unwinder_list (gdbarch);
if (table.size () == 0)
initialize_frame_unwind_table (table);
return table;
}
static const char *
frame_unwinder_class_str (frame_unwind_class uclass)
{
switch (uclass)
{
case FRAME_UNWIND_GDB:
return "FRAME_UNWIND_GDB";
case FRAME_UNWIND_EXTENSION:
return "FRAME_UNWIND_EXTENSION";
case FRAME_UNWIND_DEBUGINFO:
return "FRAME_UNWIND_DEBUGINFOD";
case FRAME_UNWIND_ARCH:
return "FRAME_UNWIND_ARCH";
default:
return "<unknown class>";
};
}
void
frame_unwind_prepend_unwinder (struct gdbarch *gdbarch,
const struct frame_unwind *unwinder)
{
struct frame_unwind_table *table = get_frame_unwind_table (gdbarch);
struct frame_unwind_table_entry *entry;
std::vector<const frame_unwind*>& table = get_frame_unwind_table (gdbarch);
/* Insert the new entry at the start of the list. */
entry = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry);
entry->unwinder = unwinder;
entry->next = (*table->osabi_head);
(*table->osabi_head) = entry;
gdb_assert (osabi_start >= 0);
table.push_back (unwinder);
/* Bubble the new entry up to where new unwinders are allowed to be
inserterd. */
for (int i = table.size() - 1; i > osabi_start; i--)
std::swap(table[i], table[i-1]);
}
void
frame_unwind_append_unwinder (struct gdbarch *gdbarch,
const struct frame_unwind *unwinder)
{
struct frame_unwind_table *table = get_frame_unwind_table (gdbarch);
struct frame_unwind_table_entry **ip;
std::vector<const frame_unwind*>& table = get_frame_unwind_table (gdbarch);
/* Find the end of the list and insert the new entry there. */
for (ip = table->osabi_head; (*ip) != NULL; ip = &(*ip)->next);
(*ip) = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry);
(*ip)->unwinder = unwinder;
table.push_back (unwinder);
}
/* Call SNIFFER from UNWINDER. If it succeeded set UNWINDER for
@@ -188,9 +185,6 @@ frame_unwind_find_by_frame (frame_info_ptr this_frame, void **this_cache)
FRAME_SCOPED_DEBUG_ENTER_EXIT;
frame_debug_printf ("this_frame=%d", frame_relative_level (this_frame));
struct gdbarch *gdbarch = get_frame_arch (this_frame);
struct frame_unwind_table *table = get_frame_unwind_table (gdbarch);
struct frame_unwind_table_entry *entry;
const struct frame_unwind *unwinder_from_target;
unwinder_from_target = target_get_unwinder ();
@@ -205,8 +199,10 @@ frame_unwind_find_by_frame (frame_info_ptr this_frame, void **this_cache)
unwinder_from_target))
return;
for (entry = table->list; entry != NULL; entry = entry->next)
if (frame_unwind_try_unwinder (this_frame, this_cache, entry->unwinder))
struct gdbarch *gdbarch = get_frame_arch (this_frame);
std::vector<const frame_unwind*> table = get_frame_unwind_table (gdbarch);
for (auto unwinder: table)
if (frame_unwind_try_unwinder (this_frame, this_cache, unwinder))
return;
internal_error (_("frame_unwind_find_by_frame failed"));
@@ -347,23 +343,25 @@ static void
maintenance_info_frame_unwinders (const char *args, int from_tty)
{
gdbarch *gdbarch = current_inferior ()->arch ();
struct frame_unwind_table *table = get_frame_unwind_table (gdbarch);
std::vector<const frame_unwind*> table = get_frame_unwind_table (gdbarch);
ui_out *uiout = current_uiout;
ui_out_emit_table table_emitter (uiout, 2, -1, "FrameUnwinders");
ui_out_emit_table table_emitter (uiout, 3, -1, "FrameUnwinders");
uiout->table_header (27, ui_left, "name", "Name");
uiout->table_header (25, ui_left, "type", "Type");
uiout->table_header (25, ui_left, "class", "Class");
uiout->table_body ();
for (struct frame_unwind_table_entry *entry = table->list; entry != NULL;
entry = entry->next)
for (const struct frame_unwind* unwinder: table)
{
const char *name = entry->unwinder->name;
const char *type = frame_type_str (entry->unwinder->type);
const char *name = unwinder->name;
const char *type = frame_type_str (unwinder->type);
const char *uclass = frame_unwinder_class_str (unwinder->unwinder_class);
ui_out_emit_list tuple_emitter (uiout, nullptr);
uiout->field_string ("name", name);
uiout->field_string ("type", type);
uiout->field_string ("class", uclass);
uiout->text ("\n");
}
}

View File

@@ -156,12 +156,23 @@ typedef void (frame_dealloc_cache_ftype) (frame_info *self,
typedef struct gdbarch *(frame_prev_arch_ftype) (frame_info_ptr this_frame,
void **this_prologue_cache);
enum frame_unwind_class {
FRAME_UNWIND_GDB,
FRAME_UNWIND_EXTENSION,
FRAME_UNWIND_DEBUGINFO,
FRAME_UNWIND_ARCH,
};
struct frame_unwind
{
const char *name;
/* The frame's type. Should this instead be a collection of
predicates that test the frame for various attributes? */
enum frame_type type;
/* What kind of unwinder is this. It generally follows from where
the unwinder was added or where it looks for information to do the
unwinding. */
enum frame_unwind_class unwinder_class;
/* Should an attribute indicating the frame's address-in-block go
here? */
frame_unwind_stop_reason_ftype *stop_reason;

View File

@@ -336,6 +336,7 @@ static const struct frame_unwind frv_linux_sigtramp_frame_unwind =
{
"frv linux sigtramp",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
frv_linux_sigtramp_frame_this_id,
frv_linux_sigtramp_frame_prev_register,

View File

@@ -1408,6 +1408,7 @@ frv_frame_prev_register (frame_info_ptr this_frame,
static const struct frame_unwind frv_frame_unwind = {
"frv prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
frv_frame_this_id,
frv_frame_prev_register,

View File

@@ -528,6 +528,7 @@ static const struct frame_unwind ft32_frame_unwind =
{
"ft32 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
ft32_frame_this_id,
ft32_frame_prev_register,

View File

@@ -27,6 +27,7 @@
/* Maintain the struct gdbarch object. */
#include <vector>
struct gdbarch
{
/* Has this architecture been fully initialized? */
@@ -36,6 +37,8 @@ struct gdbarch
auto_obstack obstack;
/* Registry. */
registry<gdbarch> registry_fields;
/* list of frame unwinders. */
std::vector<const frame_unwind *> unwinders;
/* basic architectural information. */
const struct bfd_arch_info * bfd_arch_info;

View File

@@ -30,6 +30,7 @@
#include "displaced-stepping.h"
#include "gdbsupport/gdb-checked-static-cast.h"
#include "registry.h"
#include "frame-unwind.h"
struct floatformat;
struct ui_file;
@@ -310,6 +311,10 @@ extern obstack *gdbarch_obstack (gdbarch *arch);
#define GDBARCH_OBSTACK_ZALLOC(GDBARCH, TYPE) obstack_zalloc<TYPE> (gdbarch_obstack ((GDBARCH)))
/* Return the vector of unwinders stored in a gdbarch object. */
std::vector<const frame_unwind*>& gdbarch_get_unwinder_list (struct gdbarch *arch);
/* Duplicate STRING, returning an equivalent string that's allocated on the
obstack associated with GDBARCH. The string is freed when the corresponding
architecture is also freed. */

View File

@@ -125,6 +125,7 @@ with open("gdbarch.c", "w") as f:
print(file=f)
print("/* Maintain the struct gdbarch object. */", file=f)
print(file=f)
print("#include <vector>",file=f)
#
# The struct definition body.
#
@@ -137,6 +138,8 @@ with open("gdbarch.c", "w") as f:
print(" auto_obstack obstack;", file=f)
print(" /* Registry. */", file=f)
print(" registry<gdbarch> registry_fields;", file=f)
print(" /* list of frame unwinders. */", file=f)
print(" std::vector<const frame_unwind *> unwinders;", file=f)
print(file=f)
print(" /* basic architectural information. */", file=f)
for c in filter(info, components):

View File

@@ -503,6 +503,7 @@ h8300_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
static const struct frame_unwind h8300_frame_unwind = {
"h8300 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
h8300_frame_this_id,
h8300_frame_prev_register,

View File

@@ -311,6 +311,7 @@ hppa_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
static const struct frame_unwind hppa_linux_sigtramp_frame_unwind = {
"hppa linux sigtramp",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
hppa_linux_sigtramp_frame_this_id,
hppa_linux_sigtramp_frame_prev_register,

View File

@@ -2287,6 +2287,7 @@ static const struct frame_unwind hppa_frame_unwind =
{
"hppa unwind table",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
hppa_frame_this_id,
hppa_frame_prev_register,
@@ -2400,6 +2401,7 @@ static const struct frame_unwind hppa_fallback_frame_unwind =
{
"hppa prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
hppa_fallback_frame_this_id,
hppa_fallback_frame_prev_register,
@@ -2481,6 +2483,7 @@ hppa_stub_unwind_sniffer (const struct frame_unwind *self,
static const struct frame_unwind hppa_stub_frame_unwind = {
"hppa stub",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
hppa_stub_frame_this_id,
hppa_stub_frame_prev_register,

View File

@@ -396,6 +396,7 @@ static const struct frame_unwind i386obsd_trapframe_unwind = {
frame, but SIGTRAMP_FRAME would print <signal handler called>,
which really is not what we want here. */
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
i386obsd_trapframe_this_id,
i386obsd_trapframe_prev_register,

View File

@@ -2200,6 +2200,7 @@ static const struct frame_unwind i386_frame_unwind =
{
"i386 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
i386_frame_unwind_stop_reason,
i386_frame_this_id,
i386_frame_prev_register,
@@ -2355,6 +2356,7 @@ static const struct frame_unwind i386_epilogue_override_frame_unwind =
{
"i386 epilogue override",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
i386_epilogue_frame_unwind_stop_reason,
i386_epilogue_frame_this_id,
i386_epilogue_frame_prev_register,
@@ -2366,6 +2368,7 @@ static const struct frame_unwind i386_epilogue_frame_unwind =
{
"i386 epilogue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
i386_epilogue_frame_unwind_stop_reason,
i386_epilogue_frame_this_id,
i386_epilogue_frame_prev_register,
@@ -2448,6 +2451,7 @@ static const struct frame_unwind i386_stack_tramp_frame_unwind =
{
"i386 stack tramp",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
i386_epilogue_frame_unwind_stop_reason,
i386_epilogue_frame_this_id,
i386_epilogue_frame_prev_register,
@@ -2597,6 +2601,7 @@ static const struct frame_unwind i386_sigtramp_frame_unwind =
{
"i386 sigtramp",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
i386_sigtramp_frame_unwind_stop_reason,
i386_sigtramp_frame_this_id,
i386_sigtramp_frame_prev_register,

View File

@@ -2166,6 +2166,7 @@ static const struct frame_unwind ia64_frame_unwind =
{
"ia64 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
&ia64_frame_this_id,
&ia64_frame_prev_register,
@@ -2355,6 +2356,7 @@ static const struct frame_unwind ia64_sigtramp_frame_unwind =
{
"ia64 sigtramp",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
ia64_sigtramp_frame_this_id,
ia64_sigtramp_frame_prev_register,
@@ -3015,6 +3017,7 @@ static const struct frame_unwind ia64_libunwind_frame_unwind =
{
"ia64 libunwind",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
ia64_libunwind_frame_this_id,
ia64_libunwind_frame_prev_register,
@@ -3104,6 +3107,7 @@ static const struct frame_unwind ia64_libunwind_sigtramp_frame_unwind =
{
"ia64 libunwind sigtramp",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
ia64_libunwind_sigtramp_frame_this_id,
ia64_libunwind_sigtramp_frame_prev_register,

View File

@@ -268,6 +268,7 @@ inline_frame_sniffer (const struct frame_unwind *self,
const struct frame_unwind inline_frame_unwind = {
"inline",
INLINE_FRAME,
FRAME_UNWIND_GDB,
default_frame_unwind_stop_reason,
inline_frame_this_id,
inline_frame_prev_register,

View File

@@ -427,6 +427,7 @@ iq2000_frame_this_id (frame_info_ptr this_frame, void **this_cache,
static const struct frame_unwind iq2000_frame_unwind = {
"iq2000 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
iq2000_frame_this_id,
iq2000_frame_prev_register,

View File

@@ -1108,6 +1108,7 @@ static const struct frame_unwind jit_frame_unwind =
{
"jit",
NORMAL_FRAME,
FRAME_UNWIND_EXTENSION,
default_frame_unwind_stop_reason,
jit_frame_this_id,
jit_frame_prev_register,

View File

@@ -450,6 +450,7 @@ lm32_frame_prev_register (frame_info_ptr this_frame,
static const struct frame_unwind lm32_frame_unwind = {
"lm32 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
lm32_frame_this_id,
lm32_frame_prev_register,

View File

@@ -453,6 +453,7 @@ loongarch_frame_prev_register (frame_info_ptr this_frame,
static const struct frame_unwind loongarch_frame_unwind = {
"loongarch prologue",
/*.type =*/NORMAL_FRAME,
/*.unwinder_class=*/FRAME_UNWIND_ARCH,
/*.stop_reason =*/default_frame_unwind_stop_reason,
/*.this_id =*/loongarch_frame_this_id,
/*.prev_register =*/loongarch_frame_prev_register,

View File

@@ -1958,6 +1958,7 @@ m32c_prev_register (frame_info_ptr this_frame,
static const struct frame_unwind m32c_unwind = {
"m32c prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
m32c_this_id,
m32c_prev_register,

View File

@@ -304,6 +304,7 @@ m32r_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
static const struct frame_unwind m32r_linux_sigtramp_frame_unwind = {
"m32r linux sigtramp",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
m32r_linux_sigtramp_frame_this_id,
m32r_linux_sigtramp_frame_prev_register,

View File

@@ -834,6 +834,7 @@ m32r_frame_prev_register (frame_info_ptr this_frame,
static const struct frame_unwind m32r_frame_unwind = {
"m32r prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
m32r_frame_this_id,
m32r_frame_prev_register,

View File

@@ -939,6 +939,7 @@ m68hc11_frame_prev_register (frame_info_ptr this_frame,
static const struct frame_unwind m68hc11_frame_unwind = {
"m68hc11 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
m68hc11_frame_this_id,
m68hc11_frame_prev_register,

View File

@@ -318,6 +318,7 @@ static const struct frame_unwind m68k_linux_sigtramp_frame_unwind =
{
"m68k linux sigtramp",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
m68k_linux_sigtramp_frame_this_id,
m68k_linux_sigtramp_frame_prev_register,

View File

@@ -1011,6 +1011,7 @@ static const struct frame_unwind m68k_frame_unwind =
{
"m68k prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
m68k_frame_this_id,
m68k_frame_prev_register,

View File

@@ -2064,6 +2064,7 @@ mep_frame_prev_register (frame_info_ptr this_frame,
static const struct frame_unwind mep_frame_unwind = {
"mep prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
mep_frame_this_id,
mep_frame_prev_register,

View File

@@ -482,6 +482,7 @@ static const struct frame_unwind microblaze_frame_unwind =
{
"microblaze prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
microblaze_frame_this_id,
microblaze_frame_prev_register,

View File

@@ -165,6 +165,7 @@ static const struct frame_unwind mips_sde_frame_unwind =
{
"mips sde sigtramp",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
mips_sde_frame_this_id,
mips_sde_frame_prev_register,

View File

@@ -2933,6 +2933,7 @@ static const struct frame_unwind mips_insn16_frame_unwind =
{
"mips insn16 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
mips_insn16_frame_this_id,
mips_insn16_frame_prev_register,
@@ -3369,6 +3370,7 @@ static const struct frame_unwind mips_micro_frame_unwind =
{
"mips micro prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
mips_micro_frame_this_id,
mips_micro_frame_prev_register,
@@ -3748,6 +3750,7 @@ static const struct frame_unwind mips_insn32_frame_unwind =
{
"mips insn32 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
mips_insn32_frame_this_id,
mips_insn32_frame_prev_register,
@@ -3865,6 +3868,7 @@ static const struct frame_unwind mips_stub_frame_unwind =
{
"mips stub",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
mips_stub_frame_this_id,
mips_stub_frame_prev_register,

View File

@@ -1130,6 +1130,7 @@ mn10300_frame_prev_register (frame_info_ptr this_frame,
static const struct frame_unwind mn10300_frame_unwind = {
"mn10300 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
mn10300_frame_this_id,
mn10300_frame_prev_register,

View File

@@ -588,6 +588,7 @@ moxie_frame_prev_register (frame_info_ptr this_frame,
static const struct frame_unwind moxie_frame_unwind = {
"moxie prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
moxie_frame_this_id,
moxie_frame_prev_register,

View File

@@ -545,6 +545,7 @@ msp430_prev_register (frame_info_ptr this_frame,
static const struct frame_unwind msp430_unwind = {
"msp430 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
msp430_this_id,
msp430_prev_register,

View File

@@ -992,6 +992,7 @@ static const struct frame_unwind nds32_frame_unwind =
{
"nds32 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
nds32_frame_this_id,
nds32_frame_prev_register,
@@ -1376,6 +1377,7 @@ static const struct frame_unwind nds32_epilogue_frame_unwind =
{
"nds32 epilogue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
nds32_epilogue_frame_this_id,
nds32_epilogue_frame_prev_register,

View File

@@ -1981,6 +1981,7 @@ static const struct frame_unwind nios2_frame_unwind =
{
"nios2 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
nios2_frame_this_id,
nios2_frame_prev_register,
@@ -2082,6 +2083,7 @@ static const struct frame_unwind nios2_stub_frame_unwind =
{
"nios2 stub",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
nios2_stub_frame_this_id,
nios2_stub_frame_prev_register,

View File

@@ -1128,6 +1128,7 @@ or1k_frame_prev_register (frame_info_ptr this_frame,
static const struct frame_unwind or1k_frame_unwind = {
"or1k prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
or1k_frame_this_id,
or1k_frame_prev_register,

View File

@@ -265,6 +265,7 @@ ppcfbsd_sigtramp_frame_prev_register (frame_info_ptr this_frame,
static const struct frame_unwind ppcfbsd_sigtramp_frame_unwind = {
"ppc freebsd sigtramp",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
ppcfbsd_sigtramp_frame_this_id,
ppcfbsd_sigtramp_frame_prev_register,

View File

@@ -234,6 +234,7 @@ ppcobsd_sigtramp_frame_prev_register (frame_info_ptr this_frame,
static const struct frame_unwind ppcobsd_sigtramp_frame_unwind = {
"ppc openbsd sigtramp",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
ppcobsd_sigtramp_frame_this_id,
ppcobsd_sigtramp_frame_prev_register,

View File

@@ -965,6 +965,7 @@ pyuw_on_new_gdbarch (gdbarch *newarch)
unwinder->name = "python";
unwinder->type = NORMAL_FRAME;
unwinder->unwinder_class = FRAME_UNWIND_EXTENSION;
unwinder->stop_reason = default_frame_unwind_stop_reason;
unwinder->this_id = pyuw_this_id;
unwinder->prev_register = pyuw_prev_register;

View File

@@ -1898,6 +1898,7 @@ const struct frame_unwind record_btrace_frame_unwind =
{
"record-btrace",
NORMAL_FRAME,
FRAME_UNWIND_GDB,
record_btrace_frame_unwind_stop_reason,
record_btrace_frame_this_id,
record_btrace_frame_prev_register,
@@ -1910,6 +1911,7 @@ const struct frame_unwind record_btrace_tailcall_frame_unwind =
{
"record-btrace tailcall",
TAILCALL_FRAME,
FRAME_UNWIND_GDB,
record_btrace_frame_unwind_stop_reason,
record_btrace_frame_this_id,
record_btrace_frame_prev_register,

View File

@@ -3905,6 +3905,7 @@ static const struct frame_unwind riscv_frame_unwind =
{
/*.name =*/ "riscv prologue",
/*.type =*/ NORMAL_FRAME,
/*.unwinder_class=*/FRAME_UNWIND_ARCH,
/*.stop_reason =*/ default_frame_unwind_stop_reason,
/*.this_id =*/ riscv_frame_this_id,
/*.prev_register =*/ riscv_frame_prev_register,

View File

@@ -1187,6 +1187,7 @@ static const struct frame_unwind rl78_unwind =
{
"rl78 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
rl78_this_id,
rl78_prev_register,

View File

@@ -331,6 +331,7 @@ aix_sighandle_frame_sniffer (const struct frame_unwind *self,
static const struct frame_unwind aix_sighandle_frame_unwind = {
"rs6000 aix sighandle",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
aix_sighandle_frame_this_id,
aix_sighandle_frame_prev_register,

View File

@@ -3842,6 +3842,7 @@ static const struct frame_unwind rs6000_frame_unwind =
{
"rs6000 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
rs6000_frame_this_id,
rs6000_frame_prev_register,
@@ -3983,6 +3984,7 @@ static const struct frame_unwind rs6000_epilogue_frame_unwind =
{
"rs6000 epilogue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
rs6000_epilogue_frame_this_id, rs6000_epilogue_frame_prev_register,
NULL,

View File

@@ -634,6 +634,7 @@ rx_exception_sniffer (const struct frame_unwind *self,
static const struct frame_unwind rx_frame_unwind = {
"rx prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
rx_frame_this_id,
rx_frame_prev_register,
@@ -648,6 +649,7 @@ static const struct frame_unwind rx_exception_unwind = {
"rx exception",
/* SIGTRAMP_FRAME could be used here, but backtraces are less informative. */
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
rx_frame_this_id,
rx_frame_prev_register,

View File

@@ -445,6 +445,7 @@ s12z_frame_prev_register (frame_info_ptr this_frame,
static const struct frame_unwind s12z_frame_unwind = {
"s12z prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
s12z_frame_this_id,
s12z_frame_prev_register,

View File

@@ -545,6 +545,7 @@ s390_sigtramp_frame_sniffer (const struct frame_unwind *self,
static const struct frame_unwind s390_sigtramp_frame_unwind = {
"s390 linux sigtramp",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
s390_sigtramp_frame_this_id,
s390_sigtramp_frame_prev_register,

View File

@@ -2649,6 +2649,7 @@ s390_frame_prev_register (frame_info_ptr this_frame,
static const struct frame_unwind s390_frame_unwind = {
"s390 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
s390_frame_this_id,
s390_frame_prev_register,
@@ -2743,6 +2744,7 @@ s390_stub_frame_sniffer (const struct frame_unwind *self,
static const struct frame_unwind s390_stub_frame_unwind = {
"s390 stub",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
s390_stub_frame_this_id,
s390_stub_frame_prev_register,

View File

@@ -83,6 +83,7 @@ const struct frame_unwind sentinel_frame_unwind =
{
"sentinel",
SENTINEL_FRAME,
FRAME_UNWIND_GDB,
default_frame_unwind_stop_reason,
sentinel_frame_this_id,
sentinel_frame_prev_register,

View File

@@ -1932,6 +1932,7 @@ sh_frame_this_id (frame_info_ptr this_frame, void **this_cache,
static const struct frame_unwind sh_frame_unwind = {
"sh prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
sh_frame_this_id,
sh_frame_prev_register,
@@ -1999,6 +2000,7 @@ static const struct frame_unwind sh_stub_unwind =
{
"sh stub",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
sh_stub_this_id,
sh_frame_prev_register,

View File

@@ -253,6 +253,7 @@ static const struct frame_unwind sparc32nbsd_sigcontext_frame_unwind =
{
"sparc32 netbsd sigcontext",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
sparc32nbsd_sigcontext_frame_this_id,
sparc32nbsd_sigcontext_frame_prev_register,

View File

@@ -138,6 +138,7 @@ static const struct frame_unwind sparc32obsd_sigtramp_frame_unwind =
{
"sparc32 openbsd sigtramp",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
sparc32obsd_sigtramp_frame_this_id,
sparc32obsd_sigtramp_frame_prev_register,

View File

@@ -184,6 +184,7 @@ static const struct frame_unwind sparc32_sol2_sigtramp_frame_unwind =
{
"sparc32 solaris sigtramp",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
sparc32_sol2_sigtramp_frame_this_id,
sparc32_sol2_sigtramp_frame_prev_register,

View File

@@ -1350,6 +1350,7 @@ static const struct frame_unwind sparc32_frame_unwind =
{
"sparc32 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
sparc32_frame_this_id,
sparc32_frame_prev_register,

View File

@@ -201,6 +201,7 @@ static const struct frame_unwind sparc64fbsd_sigtramp_frame_unwind =
{
"sparc64 freebsd sigtramp",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
sparc64fbsd_sigtramp_frame_this_id,
sparc64fbsd_sigtramp_frame_prev_register,

View File

@@ -227,6 +227,7 @@ static const struct frame_unwind sparc64nbsd_sigcontext_frame_unwind =
{
"sparc64 netbsd sigcontext",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
sparc64nbsd_sigcontext_frame_this_id,
sparc64nbsd_sigcontext_frame_prev_register,

View File

@@ -224,6 +224,7 @@ static const struct frame_unwind sparc64obsd_frame_unwind =
{
"sparc64 openbsd sigtramp",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
sparc64obsd_frame_this_id,
sparc64obsd_frame_prev_register,

View File

@@ -187,6 +187,7 @@ static const struct frame_unwind sparc64_sol2_sigtramp_frame_unwind =
{
"sparc64 solaris sigtramp",
SIGTRAMP_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
sparc64_sol2_sigtramp_frame_this_id,
sparc64_sol2_sigtramp_frame_prev_register,

View File

@@ -1138,6 +1138,7 @@ static const struct frame_unwind sparc64_frame_unwind =
{
"sparc64 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
sparc64_frame_this_id,
sparc64_frame_prev_register,

View File

@@ -0,0 +1,28 @@
/* This testcase is part of GDB, the GNU debugger.
Copyright 2005-2023 Free Software Foundation, Inc.
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/>. */
typedef int (*callback_t) (void);
int
caller (callback_t callback)
{
/* Ensure some frame content to push away the return address. */
volatile const long one = 1;
/* Modify the return value to prevent any tail-call optimization. */
return (*callback) () - one;
}

View File

@@ -0,0 +1,32 @@
/* This testcase is part of GDB, the GNU debugger.
Copyright 2005-2023 Free Software Foundation, Inc.
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/>. */
typedef int (*callback_t) (void);
extern int caller (callback_t callback);
int
callback (void)
{
return 1;
}
int
main (void)
{
return caller (callback);
}

View File

@@ -0,0 +1,91 @@
# Copyright 2010-2023 Free Software Foundation, Inc.
# 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/>.
# Test that GDB can generate accurate backtraces even if some of the stack
# trace goes through a function with no debug information.
standard_testfile -caller.c -main.c
set objmainfile ${testfile}-main.o
set objcallerfile ${testfile}-caller.o
# recompile the inferior with or without CFI information, then run the
# inferior until the point where the important test starts
# returns TRUE on an ERROR.
proc prepare_test {has_cfi} {
global srcdir subdir srcfile srcfile2 objmainfile objcallerfile binfile
if {$has_cfi} {
set extension "cfi"
if {[gdb_compile "${srcdir}/${subdir}/${srcfile}" ${objcallerfile} \
object [list {additional_flags=-fomit-frame-pointer \
-funwind-tables -fasynchronous-unwind-tables}]] != "" } {
untested "couldn't compile without cfi"
return true
}
} else {
set extension "no-cfi"
if {[gdb_compile "${srcdir}/${subdir}/${srcfile}" ${objcallerfile} \
object [list {additional_flags=-fomit-frame-pointer \
-fno-unwind-tables \
-fno-asynchronous-unwind-tables}]] != "" } {
untested "couldn't compile with cfi"
return true
}
}
if {[gdb_compile "${objmainfile} ${objcallerfile}" \
"${binfile}-${extension}" binfile {}] != ""} {
untested "couldn't link object files"
return true
}
clean_restart "$binfile-${extension}"
if ![runto callback] then {
fail "has_cfi=$has_cfi: Can't run to callback"
return true
}
return false
}
if {[gdb_compile "${srcdir}/${subdir}/${srcfile2}" ${objmainfile} \
object {debug}] != "" } {
untested "couldn't compile main file"
return
}
if { [prepare_test false] } {
untested ${testfile}.exp
} else {
gdb_test_multiple "bt" "verify unwinding breaks without CFI" {
-re -wrap " in \[?\]\[?\] .*" {
# It may backtrace through some random frames even to main().
pass $gdb_test_name
}
-re -wrap " in main .*" {
fail $gdb_test_name
}
}
}
if { [prepare_test true] } {
untested ${testfile}.exp
} else {
# #0 callback () at ...
# #1 0x00000000004004e9 in caller ()
# #2 0x00000000004004cd in main () at ...
gdb_test "bt" \
"#0 +callback \[^\r\n\]+\r\n#1 \[^\r\n\]+ in caller \[^\r\n\]+\r\n#2 \[^\r\n\]+ in main \[^\r\n\]+" \
"verify unwinding works for CFI without DIEs"
}

View File

@@ -456,6 +456,7 @@ static const struct frame_unwind tic6x_frame_unwind =
{
"tic6x prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
tic6x_frame_this_id,
tic6x_frame_prev_register,

View File

@@ -903,6 +903,7 @@ tilegx_frame_base_address (frame_info_ptr this_frame, void **this_cache)
static const struct frame_unwind tilegx_frame_unwind = {
"tilegx prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
tilegx_frame_this_id,
tilegx_frame_prev_register,

View File

@@ -166,6 +166,7 @@ tramp_frame_prepend_unwinder (struct gdbarch *gdbarch,
data->tramp_frame = tramp_frame;
unwinder->type = tramp_frame->frame_type;
unwinder->unwind_data = data;
unwinder->unwinder_class = FRAME_UNWIND_GDB;
unwinder->sniffer = tramp_frame_sniffer;
unwinder->stop_reason = default_frame_unwind_stop_reason;
unwinder->this_id = tramp_frame_this_id;

View File

@@ -1323,6 +1323,7 @@ v850_frame_this_id (frame_info_ptr this_frame, void **this_cache,
static const struct frame_unwind v850_frame_unwind = {
"v850 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
v850_frame_this_id,
v850_frame_prev_register,

View File

@@ -390,6 +390,7 @@ static const struct frame_unwind vax_frame_unwind =
{
"vax prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
vax_frame_this_id,
vax_frame_prev_register,

View File

@@ -731,6 +731,7 @@ xstormy16_frame_base_address (frame_info_ptr this_frame, void **this_cache)
static const struct frame_unwind xstormy16_frame_unwind = {
"xstormy16 prologue",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
xstormy16_frame_this_id,
xstormy16_frame_prev_register,

View File

@@ -1068,6 +1068,7 @@ z80_frame_unwind =
{
"z80",
NORMAL_FRAME,
FRAME_UNWIND_ARCH,
default_frame_unwind_stop_reason,
z80_frame_this_id,
z80_frame_prev_register,