gdb: Add switch to disable DWARF stack unwinders

Add a maintenance command to disable the DWARF stack unwinders.
Normal users would not need this feature, but it is useful to allow
extended testing of fallback stack unwinding strategies, for example,
prologue scanners.

This is a partial implementation of the idea discussed in pr gdb/8434,
which talks about a generic ability to disable any frame unwinder.

Being able to arbitrarily disable any frame unwinder would be a more
complex patch, and I was unsure how useful such a feature would really
be, however, I can see (and have) a real need to disable DWARF
unwinders.  That's why this patch only targets that specific set of
unwinders.

If in the future we find ourselves adding more switches to disable
different unwinders, then we should probably move to a more generic
solution, and remove this patch.

gdb/ChangeLog:

	* dwarf2-frame-tailcall.c (tailcall_frame_sniffer): Exit early if
	DWARF unwinders are disabled.
	* dwarf2-frame.c: Add dwarf2read.h include.
	(dwarf2_frame_sniffer): Exit early if DWARF unwinders are
	disabled.
	(dwarf2_frame_unwinders_enabled_p): Define.
	(show_dwarf_unwinders_enabled_p): New function.
	(_initialize_dwarf2_frame): Register switch to control DWARF
	unwinder use.
	* dwarf2-frame.h (dwarf2_frame_unwinders_enabled_p): Declare.
	* dwarf2read.c (set_dwarf_cmdlist): Remove static keyword.
	(show_dwarf_cmdlist): Remove static keyword.
	* dwarf2read.h (set_dwarf_cmdlist): Declare.
	(show_dwarf_cmdlist): Declare.
	* NEWS: Document new feature.

gdb/doc/ChangeLog:

	* gdb.texinfo (Maintenance Commands): Add description of
	maintenance command to control dwarf unwinders.

gdb/testsuite/ChangeLog:

	* gdb.base/maint.exp: Add check that dwarf unwinders control flag
	is visible.
This commit is contained in:
Andrew Burgess
2018-07-13 12:01:16 +01:00
parent 33cb30a1f9
commit 3c3bb0580b
11 changed files with 106 additions and 2 deletions

View File

@@ -35,6 +35,7 @@
#include "complaints.h"
#include "dwarf2-frame.h"
#include "dwarf2read.h"
#include "ax.h"
#include "dwarf2loc.h"
#include "dwarf2-frame-tailcall.h"
@@ -169,6 +170,9 @@ static CORE_ADDR read_encoded_value (struct comp_unit *unit, gdb_byte encoding,
CORE_ADDR func_base);
/* See dwarf2-frame.h. */
int dwarf2_frame_unwinders_enabled_p = 1;
/* Store the length the expression for the CFA in the `cfa_reg' field,
which is unused in that case. */
#define cfa_exp_len cfa_reg
@@ -1326,6 +1330,9 @@ static int
dwarf2_frame_sniffer (const struct frame_unwind *self,
struct frame_info *this_frame, void **this_cache)
{
if (!dwarf2_frame_unwinders_enabled_p)
return 0;
/* Grab an address that is guarenteed to reside somewhere within the
function. get_frame_pc(), with a no-return next function, can
end up returning something past the end of this function's body.
@@ -2394,12 +2401,36 @@ dwarf2_build_frame_info (struct objfile *objfile)
set_objfile_data (objfile, dwarf2_frame_objfile_data, fde_table2);
}
/* Handle 'maintenance show dwarf unwinders'. */
static void
show_dwarf_unwinders_enabled_p (struct ui_file *file, int from_tty,
struct cmd_list_element *c,
const char *value)
{
fprintf_filtered (file,
_("The DWARF stack unwinders are currently %s.\n"),
value);
}
void
_initialize_dwarf2_frame (void)
{
dwarf2_frame_data = gdbarch_data_register_pre_init (dwarf2_frame_init);
dwarf2_frame_objfile_data = register_objfile_data ();
add_setshow_boolean_cmd ("unwinders", class_obscure,
&dwarf2_frame_unwinders_enabled_p , _("\
Set whether the DWARF stack frame unwinders are used."), _("\
Show whether the DWARF stack frame unwinders are used."), _("\
When enabled the DWARF stack frame unwinders can be used for architectures\n\
that support the DWARF unwinders. Enabling the DWARF unwinders for an\n\
architecture that doesn't support them will have no effect."),
NULL,
show_dwarf_unwinders_enabled_p,
&set_dwarf_cmdlist,
&show_dwarf_cmdlist);
#if GDB_SELF_TEST
selftests::register_test_foreach_arch ("execute_cfa_program",
selftests::execute_cfa_program_test);