From patchwork Fri May 24 15:40:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Ijaz, Abdul B" X-Patchwork-Id: 90826 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 82FA8385E45E for ; Fri, 24 May 2024 15:42:23 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.19]) by sourceware.org (Postfix) with ESMTPS id 66B0B3865C10 for ; Fri, 24 May 2024 15:41:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 66B0B3865C10 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=intel.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 66B0B3865C10 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=198.175.65.19 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716565297; cv=none; b=MOM5CeFpeSZnpJiOY1b4UXNPii/OczinY9NtArCx946wXGc14Uy0d6RY2clCF5R3A+4Ogq6ht5thAQCpu/zAPjFDea/yh7sXwkpp9qWsOUO76FjmonromRXhfxAK8Hf0Sl5p2Fb8h3D6DJ1VO2HvvCavKoMLUU0Eg2rVPtBtQrg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716565297; c=relaxed/simple; bh=aktX5xlPW0gb8RHdei+bPHuYHZ0GszHJH54KDjbONs8=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=AzEDDiBB2XHgjOcgzv/NLOjsc0w3nQiokv7/KpOMndh/fyivxn7y2Vu7yTv2bPOalN/UqUb9OdC5MnilLkGQCVGbMxzjmwHymE4mWlrY6xx8YrIDo2LiyiKNrfeE4sgs2gefm3SnyRTYJfuA9V6sqgqG6akVfLwqw/4ui3B2Csw= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1716565291; x=1748101291; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=aktX5xlPW0gb8RHdei+bPHuYHZ0GszHJH54KDjbONs8=; b=QvT/3UE0aoy0tTfT6YdLhrM88o3KGMW4AzVfCGf3QMrWR2hGN4KiTUGW lMZuNgJBUcM4DqDCOCAMtWBYjo+RPDdMnx50JBGuhTH1pw2ncJFJKPT+q hiIKjTglWgcYs+jsRxUjYeVEh2UzJze5hVKo9ySb7cCpruvDSrT69cj27 UcUV0AgaDkc9mel0AAiuKxBq+qcv93mtMGC/8EqL6qY9Wziw8ZagEW7Oh hNdGGVRz6PzE59Az9/g3g+N+xGvs6Rf9Yb9airXwNr5koAYMYhXJf7aTW pS+/4HQlaZCBR2HC4CWqiwGkFZGD6raTmw8yxUSQDxu0w6QubYITdGAbW A==; X-CSE-ConnectionGUID: 2e9BM7srSICkSxnmL/yylA== X-CSE-MsgGUID: L5Ati9xdQbee7e5bmVFbcA== X-IronPort-AV: E=McAfee;i="6600,9927,11082"; a="12795788" X-IronPort-AV: E=Sophos;i="6.08,185,1712646000"; d="scan'208";a="12795788" Received: from orviesa006.jf.intel.com ([10.64.159.146]) by orvoesa111.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 May 2024 08:41:30 -0700 X-CSE-ConnectionGUID: xJTEgPQ1Q2yBSCODcxuU6g== X-CSE-MsgGUID: h796Hk18TNC4o26Veh9Alg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,185,1712646000"; d="scan'208";a="34558136" Received: from abijaz-mobl2.ger.corp.intel.com (HELO localhost) ([10.94.253.168]) by orviesa006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 May 2024 08:41:29 -0700 From: Abdul Basit Ijaz To: gdb-patches@sourceware.org Cc: abdul.b.ijaz@intel.com, JiniSusan.George@amd.com, tom@tromey.com, eliz@gnu.org Subject: [PATCH v8 04/10] gdb: Skip trampoline frames for the backtrace command. Date: Fri, 24 May 2024 17:40:26 +0200 Message-Id: <20240524154032.12652-5-abdul.b.ijaz@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240524154032.12652-1-abdul.b.ijaz@intel.com> References: <20240524154032.12652-1-abdul.b.ijaz@intel.com> MIME-Version: 1.0 X-Spam-Status: No, score=-10.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: "Ijaz, Abdul B" This change filters trampoline functions when the option 'skip-trampoline-functions' is set to 'on' for the backtrace command. Before the change, GDB prints the frames indicated by the compiler with DIE "DW_AT_trampoline" in the backtrace, but for better user experience, all such frames can be hidden from the user. The test 'gdb.fortran/mixed-lang-stack' test used to fail for the IFX compiler because of extra trampoline frames in the backtrace. After the commit, those trampoline frames are filtered and test is updated accordingly. Extra trampoline frames: bt -frame-arguments all ''' \#8 0x0000000000405535 in mixed_func_1b_.t86p.t87p.t88p.t89p.t90p.t91p.t3v () \#10 0x0000000000405439 in mixed_func_1a_.void () at mixed-lang-stack.f90:33 ''' (gdb) FAIL: gdb.fortran/mixed-lang-stack.exp: lang=auto: bt -frame-arguments all In this example the IFX compiler emits "DW_AT_trampoline" tag for the 'first' and 'second' trampoline functions like following: function second (x, y) result(z) integer, intent(in) :: x, y integer :: z z = x * y ! breakpt-backtrace end function second function first (num1, num2) result(total) integer, intent(in) :: num1, num2 integer :: total total = second (num1 + 4, num2 * 3) ! first-breakpt total = total + 30 end function first Related Dwarf: 0x0000013f: DW_TAG_subprogram DW_AT_low_pc (0x0000000000404350) DW_AT_high_pc (0x000000000040435f) DW_AT_frame_base (DW_OP_reg6 RBP) DW_AT_linkage_name ("second_.t74p.t75p") DW_AT_name ("second_.t74p.t75p") DW_AT_trampoline ("second_") 0x0000015a: DW_TAG_subprogram DW_AT_low_pc (0x00000000004044a0) DW_AT_high_pc (0x00000000004044af) DW_AT_frame_base (DW_OP_reg6 RBP) DW_AT_linkage_name ("first_.t104p.t105p") DW_AT_name ("first_.t104p.t105p") DW_AT_trampoline ("first_") Before this change, the backtrace command output looks like: ''' (gdb) backtrace 3 \#0 second (x=20, y=9) at test.f90:4 \#1 0x0000000000405209 in second_.t74p.t75p () at test.f90:12 \#2 0x00000000004051e3 in first (num1=16, num2=3) at test.f90:10 (gdb) backtrace -3 \#2 0x00000000004051e3 in first (num1=16, num2=3) at test.f90:10 \#3 0x0000000000405309 in first_.t95p.t96p () at test.f90:21 \#4 0x0000000000405234 in func_trampoline () at test.f90:17 ''' After the change: ''' (gdb) backtrace 3 \#0 second (x=20, y=9) at test.f90:4 \#2 0x00000000004051e3 in first (num1=16, num2=3) at test.f90:10 \#4 0x0000000000405234 in func_trampoline () at test.f90:17 (gdb) backtrace -3 \#2 0x00000000004051e3 in first (num1=16, num2=3) at test.f90:10 \#4 0x0000000000405234 in func_trampoline () at test.f90:17 ''' The test gdb.fortran/func-trampoline.exp is added for testing the change. 2024-05-24 Abdul Basit Ijaz --- gdb/NEWS | 5 +- gdb/doc/gdb.texinfo | 6 ++ gdb/infrun.c | 6 +- gdb/infrun.h | 6 ++ gdb/stack.c | 8 ++ gdb/symtab.c | 12 +++ gdb/symtab.h | 5 ++ gdb/testsuite/gdb.fortran/func-trampoline.exp | 77 +++++++++++++++++++ gdb/testsuite/gdb.fortran/func-trampoline.f90 | 39 ++++++++++ .../gdb.fortran/mixed-lang-stack.exp | 10 ++- 10 files changed, 166 insertions(+), 8 deletions(-) create mode 100644 gdb/testsuite/gdb.fortran/func-trampoline.exp create mode 100644 gdb/testsuite/gdb.fortran/func-trampoline.f90 diff --git a/gdb/NEWS b/gdb/NEWS index b435553d23a..58c81203a7e 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -917,8 +917,9 @@ show skip-trampoline-functions This setting is 'on' by default. When 'on' it controls whether GDB will recognize function calls that have been marked as trampolines in the debug info. It improves stepping behavior in that it steps over the trampoline - code and hides it from the user. Currently, only DWARF trampolines are - supported. + code and hides it from the user. It improves the printing of the stack by + hiding trampoline functions from the backtrace. Currently, only DWARF + trampolines are supported. If this is turned off, GDB will handle @dfn{trampoline functions} the same as any other function. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index fb8b224ee94..e737df86988 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -6535,6 +6535,12 @@ execution until leaving the trampoline region. The @code{stepi} command is not affected by the setting which is enabled by default. Currently, only DWARF trampolines marked via DW_AT_trampoline are supported by this. +When issuing a @code{backtrace}, if @code{skip-trampoline-functions} is set, +@value{GDBN} will skip trampoline frames while printing the stack. + +Currently, only DWARF trampolines marked via DW_AT_trampoline are supported by +this. + @item set skip-trampoline-functions off Causes @value{GDBN} to completely ignore any trampoline information a compiler might have emitted in its debug info. Trampolines will be treated like any diff --git a/gdb/infrun.c b/gdb/infrun.c index 0e79aa7201e..fab98a96ba6 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -191,7 +191,7 @@ static bool detach_fork = true; DW_AT_trampoline by the compiler. If false, GDB will ignore the attribute. */ -static bool skip_trampoline_functions = true; +bool skip_trampoline_functions = true; bool debug_infrun = false; static void @@ -10793,8 +10793,8 @@ Options are 'forward' or 'reverse'."), &skip_trampoline_functions, _("\ Set whether gdb attempts to hide trampolines marked in the debug info."), _("\ Show whether gdb attempts to hide trampolines marked in the debug info."), _("\ -If on, while stepping gdb will skip through functions and inlined functions\n\ -marked as trampolines by the compiler. If off, gdb will treat trampolines as\n\ +If on, gdb will skip through functions and inlined functions marked as\n\ +trampolines by the compiler. If off, gdb will treat trampolines as\n\ normal functions."), nullptr, show_skip_trampoline_functions, &setlist, &showlist); diff --git a/gdb/infrun.h b/gdb/infrun.h index ea1ec134c7c..fbe88ad4595 100644 --- a/gdb/infrun.h +++ b/gdb/infrun.h @@ -107,6 +107,12 @@ extern bool non_stop; starting an inferior. */ extern bool disable_randomization; +/* If set (default) GDB will step through functions/inlined subroutines marked + DW_AT_trampoline by the compiler. If false, GDB will ignore the + attribute. */ + +extern bool skip_trampoline_functions; + /* Returns a unique identifier for the current stop. This can be used to tell whether a command has proceeded the inferior past the current location. */ diff --git a/gdb/stack.c b/gdb/stack.c index c2323e1726d..de8b404365f 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -2060,6 +2060,14 @@ backtrace_command_1 (const frame_print_options &fp_opts, { QUIT; + if (skip_trampoline_functions && in_trampoline_frame (fi)) + { + /* Trampoline frames are not printed so they are not counted in + the backtrace limit. */ + count++; + continue; + } + /* Don't use print_stack_frame; if an error() occurs it probably means further attempts to backtrace would fail (on the other hand, perhaps the code does or could be fixed to make sure diff --git a/gdb/symtab.c b/gdb/symtab.c index 5eac2ee8535..1027143a110 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -4301,6 +4301,18 @@ in_trampoline_function (CORE_ADDR pc) /* See symtab.h. */ +bool +in_trampoline_frame (frame_info_ptr fi) +{ + CORE_ADDR pc; + if (get_frame_pc_if_available (fi, &pc)) + return in_trampoline_function (pc); + + return false; +} + +/* See symtab.h. */ + CORE_ADDR find_function_trampoline_target (CORE_ADDR pc) { diff --git a/gdb/symtab.h b/gdb/symtab.h index c60485dc6d3..234171ed404 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -2359,6 +2359,11 @@ extern CORE_ADDR find_solib_trampoline_target (const frame_info_ptr &, CORE_ADDR extern bool in_trampoline_function (CORE_ADDR pc); +/* Return whether or not the pc of the current frame is within a block that + belongs to a function that is marked as a trampoline by the compiler. */ + +extern bool in_trampoline_frame (frame_info_ptr); + /* Find the target of a trampoline function marked via the DW_AT_trampoline attribute and return its address. Returns 0 if the pc is not contained in a trampoline function (inlined or not). If DW_AT_trampoline diff --git a/gdb/testsuite/gdb.fortran/func-trampoline.exp b/gdb/testsuite/gdb.fortran/func-trampoline.exp new file mode 100644 index 00000000000..bfa0002cf0e --- /dev/null +++ b/gdb/testsuite/gdb.fortran/func-trampoline.exp @@ -0,0 +1,77 @@ +# Copyright 2024 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 . + +# Test "backtrace" and "backtrace -n" commands for functions with trampoline +# calls. + +require allow_fortran_tests + +if {![test_compiler_info {ifx-*} f90]} { + untested "This test is only applicable for IFX, which emits the\ + trampoline DIE in Dwarf." + return -1 +} + +standard_testfile ".f90" +load_lib fortran.exp + +# Initialize the test by running the program to the innermost +# function name "second". + +proc init_test {} { + global binfile srcfile inner_loc + + clean_restart ${binfile} + if {![fortran_runto_main]} { + return -1 + } + + # Set breakpoint inside the innermost function 'second'. + gdb_breakpoint "$srcfile:$inner_loc" + gdb_continue_to_breakpoint "innermost-body" ".*$srcfile:$inner_loc.*" +} + +if {[build_executable "failed to prepare" ${testfile} ${srcfile} \ + {debug f90}]} { + return -1 +} + +set inner_loc [gdb_get_line_number "second-breakpt"] +set middle_loc [gdb_get_line_number "first-breakpt"] +set outer_loc [gdb_get_line_number "main-outer-loc"] +set fill "\[^\r\n\]*" + +set inner_desc "second \\(x=20, y=9\\) at ${fill}$srcfile:$inner_loc" +set middle_desc "first \\(num1=16, num2=3\\) at ${fill}$srcfile:$middle_loc" +set outer_desc ".* at .*$srcfile:$outer_loc" + +with_test_prefix "backtrace" { + init_test + + # Limit the backtrace to 3 frames and ensure both frames for first + # and second function are shown only and trampoline frames are filtered. + gdb_test "backtrace 3" [multi_line \ + "#$decimal.* $inner_desc" \ + "#$decimal.* $middle_desc" \ + "#$decimal.* $outer_desc.*"] +} + +with_test_prefix "backtrace outerframes" { + init_test + + gdb_test "backtrace -3" [multi_line \ + "#$decimal.* $middle_desc" \ + "#$decimal.* $outer_desc.*"] +} diff --git a/gdb/testsuite/gdb.fortran/func-trampoline.f90 b/gdb/testsuite/gdb.fortran/func-trampoline.f90 new file mode 100644 index 00000000000..10eb3f5188f --- /dev/null +++ b/gdb/testsuite/gdb.fortran/func-trampoline.f90 @@ -0,0 +1,39 @@ +! Copyright 2024 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 . + +! Source code for func-trampoline.exp. + +integer(kind=4) function second(x, y) + integer(kind=4), intent(in) :: x + integer(kind=4), intent(in) :: y + + second = x * y ! second-breakpt +end function + +integer(kind=4) function first(num1, num2) + integer(kind=4), intent(in) :: num1 + integer(kind=4), intent(in) :: num2 + + first = second (num1 + 4, num2 * 3) ! first-breakpt +end function + +program func_trampoline + integer(kind=4) :: total + + total = first(16, 3) ! main-outer-loc + + write(*,*) "Result is ", total, "\n" + ! Expected: 180 +end program func_trampoline diff --git a/gdb/testsuite/gdb.fortran/mixed-lang-stack.exp b/gdb/testsuite/gdb.fortran/mixed-lang-stack.exp index eef84da0e44..4591880ca7b 100644 --- a/gdb/testsuite/gdb.fortran/mixed-lang-stack.exp +++ b/gdb/testsuite/gdb.fortran/mixed-lang-stack.exp @@ -41,7 +41,7 @@ set have_index [exec_has_index_section $binfile] # value to pass to GDB's 'set language ...' command. proc run_tests { lang } { with_test_prefix "lang=${lang}" { - global binfile hex have_index + global binfile hex have_index decimal clean_restart ${binfile} @@ -63,6 +63,10 @@ proc run_tests { lang } { set e_arg "\['\"\]abcdef\['\"\]" set 1b_args "\[^\r\n\]+$e_arg\[^\r\n\]+" set 1g_args "obj=\[^\r\n\]+" + # Generic decimal number is checked in regex for Frame #8 and #9 to + # handle filtered trampoline frames. Since Frame#8 and Frame#10 are + # set to trampoline in DWARF by IntelĀ® Fortran Compiler (ifx), they + # are not shown by the backtrace command. set bt_stack \ [multi_line \ "#0\\s+breakpt \\(\\) at \[^\r\n\]+" \ @@ -73,8 +77,8 @@ proc run_tests { lang } { "#5\\s+$hex in mixed_func_1d \\(\[^\r\n\]+\\) at \[^\r\n\]+" \ "#6\\s+$hex in mixed_func_1c \\(\[^\r\n\]+\\) at \[^\r\n\]+" \ "#7\\s+$hex in mixed_func_1b \\($1b_args\\) at \[^\r\n\]+" \ - "#8\\s+$hex in mixed_func_1a \\(\\) at \[^\r\n\]+" \ - "#9\\s+$hex in mixed_stack_main \\(\\) at \[^\r\n\]+" ] + "#$decimal\\s+$hex in mixed_func_1a \\(\\) at \[^\r\n\]+" \ + "#$decimal\\s+$hex in mixed_stack_main \\(\\) at \[^\r\n\]+" ] set main_args "argc=1, argv=${hex}( \[^\r\n\]+)?" set bt_stack_kfail \ [multi_line \