From patchwork Fri Jul 13 13:46:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 28367 Received: (qmail 1834 invoked by alias); 13 Jul 2018 13:46:37 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 1824 invoked by uid 89); 13 Jul 2018 13:46:36 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=Maintenance, HX-Gm-Message-State:AOUpUlG, reside, sk:gdb_tes X-HELO: mail-wm0-f48.google.com Received: from mail-wm0-f48.google.com (HELO mail-wm0-f48.google.com) (74.125.82.48) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 13 Jul 2018 13:46:34 +0000 Received: by mail-wm0-f48.google.com with SMTP id s14-v6so9505065wmc.1 for ; Fri, 13 Jul 2018 06:46:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=from:to:cc:subject:date:message-id; bh=i4UxGNKDNRu7J4OuGTT0z4/wD1Yc/iUzbyVd+MktVTo=; b=K4xJiS7gFauftAnHLR+6rv5Gkr92VPs+Gk18GXVz/SHMZVL0yUjDvBE0c8HxDHKl17 x0mYjYSRmGcXE0pmJ2AA8PC5M4KGju4n/vYed3xMxeelsl2mnKhpt1FaJAnBLj3vDe8V 6r9ukRGgwWThAwzvRlHhVh+4GRlfX1dZVsdMYeXue4iGGcF5VM02qc0aPli1fmGhjrqP 7ZMXpznLYDBPE1z8XuX+wzj/t9zSey+Cx/EgKRuB/Sx3FKLGF3FjckMv6S7HejNOBnk0 KHG6ReqR3hJaJZeA9YxDDc8gl35t3WNDTXQV8d+CmX+ye3gMsuva4sQ2U2XIxeLhAzNo 5SbQ== Return-Path: Received: from localhost (host86-164-199-62.range86-164.btcentralplus.com. [86.164.199.62]) by smtp.gmail.com with ESMTPSA id u4-v6sm18673976wrt.31.2018.07.13.06.46.31 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 13 Jul 2018 06:46:31 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess Subject: [PATCH] gdb: Add switch to disable DWARF stack unwinders Date: Fri, 13 Jul 2018 14:46:29 +0100 Message-Id: <20180713134629.27011-1-andrew.burgess@embecosm.com> X-IsSubscribed: yes 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. gdb/ChangeLog: * dwarf2-frame-tailcall.c (tailcall_frame_sniffer): Exit early if dwarf unwinders are disabled. * dwarf2-frame.c (dwarf2_frame_sniffer): Likewise. (dwarf2_frame_unwinders_enabled_p): Define. (dwarf2_append_unwinders): Enable dwarf unwinders when they are first registered. * dwarf2-frame.h (dwarf2_frame_unwinders_enabled_p): Declare. * dwarf2read.c: Add dwarf2-frame.h include. (show_dwarf_unwinders_enabled_p): New function. (_initialize_dwarf2_read): Register switch to control unwinder use. * 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. --- gdb/ChangeLog | 15 +++++++++++++++ gdb/NEWS | 6 ++++++ gdb/doc/ChangeLog | 5 +++++ gdb/doc/gdb.texinfo | 24 ++++++++++++++++++++++++ gdb/dwarf2-frame-tailcall.c | 3 +++ gdb/dwarf2-frame.c | 9 +++++++++ gdb/dwarf2-frame.h | 6 ++++++ gdb/dwarf2read.c | 26 ++++++++++++++++++++++++++ gdb/testsuite/ChangeLog | 5 +++++ gdb/testsuite/gdb.base/maint.exp | 4 ++++ 10 files changed, 103 insertions(+) diff --git a/gdb/NEWS b/gdb/NEWS index acb9c34fb22..8b66cd8a9ad 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -7,6 +7,12 @@ can be passed using the '[ADDRESS]:PORT' notation, or the regular 'ADDRESS:PORT' method. +* New commands + +maint set dwarf unwinders (on|off) +maint show dwarf unwinders + Control whether DWARF unwinders can be used. + *** Changes in GDB 8.2 * The 'set disassembler-options' command now supports specifying options diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 2e9d76227c3..eb148cedef0 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -35802,6 +35802,30 @@ memory will be used. Setting it to zero disables caching, which will slow down @value{GDBN} startup, but reduce memory consumption. +@kindex maint set dwarf unwinders +@kindex maint show dwarf unwinders +@item maint set dwarf unwinders +@itemx maint show dwarf unwinders +Control use of the DWARF frame unwinders. + +@cindex DWARF frame unwinders +Many targets that support DWARF debugging use @value{GDBN}'s DWARF +frame unwinders to build the backtrace. Many of these targets will +also have a second mechanism for building the backtrace for use in +cases where DWARF information is not available, this second mechanism +is often an analysis of a functions prologue. + +In order to extend testing coverage of the second level stack +unwinding mechanisms it is helpful to be able to disable the DWARF +stack unwinders, this can be done with this switch. + +In normal use of @value{GDBN} disabling the DWARF unwinders is not +advisable, there are cases that are better handled through DWARF than +prologue analysis, and the debug experience is likely to be better +with the DWARF frame unwinders enabled. + +If DWARF frame unwinders are not supported for a particular target +architecture, then enabling this flag does not cause them to be used. @kindex maint set profile @kindex maint show profile @cindex profiling GDB diff --git a/gdb/dwarf2-frame-tailcall.c b/gdb/dwarf2-frame-tailcall.c index 1d3e1f445bb..f565a2eecc8 100644 --- a/gdb/dwarf2-frame-tailcall.c +++ b/gdb/dwarf2-frame-tailcall.c @@ -318,6 +318,9 @@ tailcall_frame_sniffer (const struct frame_unwind *self, int next_levels; struct tailcall_cache *cache; + if (!dwarf2_frame_unwinders_enabled_p) + return 0; + /* Inner tail call element does not make sense for a sentinel frame. */ next_frame = get_next_frame (this_frame); if (next_frame == NULL) diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index 91e16cf024e..fdd41b360e6 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -169,6 +169,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 = 0; + /* 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 +1329,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. @@ -1389,6 +1395,9 @@ dwarf2_append_unwinders (struct gdbarch *gdbarch) frame_unwind_append_unwinder (gdbarch, &dwarf2_frame_unwind); frame_unwind_append_unwinder (gdbarch, &dwarf2_signal_frame_unwind); + + /* Mark dwarf frame unwinders as enabled. */ + dwarf2_frame_unwinders_enabled_p = 1; } diff --git a/gdb/dwarf2-frame.h b/gdb/dwarf2-frame.h index 471281a2c3f..56c90be8ceb 100644 --- a/gdb/dwarf2-frame.h +++ b/gdb/dwarf2-frame.h @@ -210,6 +210,12 @@ struct dwarf2_frame_state bool armcc_cfa_offsets_reversed = false; }; +/* When this is true the dwarf frame unwinders can be used if they are + registered with the gdbarch. Not all architectures can or do use the + dwarf unwinders. Setting this to true on a target that does not + otherwise support the dwarf unwinders has no effect. */ +extern int dwarf2_frame_unwinders_enabled_p; + /* Set the architecture-specific register state initialization function for GDBARCH to INIT_REG. */ diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 372f45ee175..b49d4d9fbbc 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -90,6 +90,7 @@ #include #include "rust-lang.h" #include "common/pathstuff.h" +#include "dwarf2-frame.h" /* When == 1, print basic high level tracing messages. When > 1, be more verbose. @@ -1423,6 +1424,19 @@ show_dwarf_max_cache_age (struct ui_file *file, int from_tty, "DWARF compilation units is %s.\n"), value); } + +/* 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); +} + /* local function prototypes */ @@ -25363,6 +25377,18 @@ conversational style, when possible."), &set_dwarf_cmdlist, &show_dwarf_cmdlist); + 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); + add_setshow_zuinteger_cmd ("dwarf-read", no_class, &dwarf_read_debug, _("\ Set debugging of the DWARF reader."), _("\ Show debugging of the DWARF reader."), _("\ diff --git a/gdb/testsuite/gdb.base/maint.exp b/gdb/testsuite/gdb.base/maint.exp index 92086eec862..6125b6ec6f2 100644 --- a/gdb/testsuite/gdb.base/maint.exp +++ b/gdb/testsuite/gdb.base/maint.exp @@ -526,6 +526,10 @@ gdb_test_no_output "maint info line-table xxx.c" \ set timeout $oldtimeout +# Just check that the DWARF unwinders control flag is visible. +gdb_test "maint show dwarf unwinders" \ + "The DWARF stack unwinders are currently (on\|off)\." + #============test help on maint commands test_prefix_command_help {"maint info" "maintenance info"} {