[PATCH] [gdb/cli] Fix return from frame containing inline frame
Guinevere Larsen
guinevere@redhat.com
Thu Jan 23 12:47:28 GMT 2025
On 1/17/25 5:18 PM, Tom de Vries wrote:
> Consider test-case gdb.base/return-3.exp:
> ...
> $ gdb -q outputs/gdb.base/return-3/return-3
> Reading symbols from outputs/gdb.base/return-3/return-3...
> (gdb)
> ...
>
> Function bar is an inlined function, and consequently we cannot return from
> it:
> ...
> (gdb) b bar
> Breakpoint 1 at 0x4006ac: file return-3.c, line 25.
> (gdb) r
> Starting program: return-3
> ...
> Breakpoint 1, bar () at return-3.c:25
> 25 c++;
> (gdb) return
> Can not force return from an inlined function.
> (gdb)
> ...
>
> However, function foo is not an inline function, and we should be able to
> return from it, however, we get the same error message:
> ...
> (gdb) up
> 31 bar ();
> (gdb) return
> Can not force return from an inlined function.
> (gdb)
> ...
>
> Fix this by using the selected frame rather than the current frame in
> return_command, such that we get instead:
> ...
> (gdb) up
> 31 bar ();
> (gdb) return
> 40 printf ("%d\n", c);
> (gdb)
> ...
>
> Tested on aarch64-linux.
>
> PR cli/32479
> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32479
Hi Tom!
Thanks for doing this, I encourage you to approve this!
Reviewed-By: Guinevere Larsen <guinevere@redhat.com>
> ---
> gdb/stack.c | 2 +-
> gdb/testsuite/gdb.base/return-3.c | 43 +++++++++++++++++++++++++++++
> gdb/testsuite/gdb.base/return-3.exp | 39 ++++++++++++++++++++++++++
> 3 files changed, 83 insertions(+), 1 deletion(-)
> create mode 100644 gdb/testsuite/gdb.base/return-3.c
> create mode 100644 gdb/testsuite/gdb.base/return-3.exp
>
> diff --git a/gdb/stack.c b/gdb/stack.c
> index 2d6712ab16b..4a92449e284 100644
> --- a/gdb/stack.c
> +++ b/gdb/stack.c
> @@ -2696,7 +2696,7 @@ return_command (const char *retval_exp, int from_tty)
> thisfun = get_frame_function (thisframe);
> gdbarch = get_frame_arch (thisframe);
>
> - if (get_frame_type (get_current_frame ()) == INLINE_FRAME)
> + if (get_frame_type (thisframe) == INLINE_FRAME)
> error (_("Can not force return from an inlined function."));
>
> /* Compute the return value. If the computation triggers an error,
> diff --git a/gdb/testsuite/gdb.base/return-3.c b/gdb/testsuite/gdb.base/return-3.c
> new file mode 100644
> index 00000000000..ecfaf61f841
> --- /dev/null
> +++ b/gdb/testsuite/gdb.base/return-3.c
> @@ -0,0 +1,43 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> + Copyright 2025 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/>. */
> +
> +#include <stdio.h>
> +
> +static int c;
> +
> +static inline void __attribute__((always_inline))
> +bar (void)
> +{
> + c++;
> +}
> +
> +static void __attribute__((noinline))
> +foo ()
> +{
> + bar ();
> + c++;
> +}
> +
> +int
> +main (void)
> +{
> + foo ();
> +
> + printf ("%d\n", c);
> +
> + return 0;
> +}
> diff --git a/gdb/testsuite/gdb.base/return-3.exp b/gdb/testsuite/gdb.base/return-3.exp
> new file mode 100644
> index 00000000000..2297ac07a18
> --- /dev/null
> +++ b/gdb/testsuite/gdb.base/return-3.exp
> @@ -0,0 +1,39 @@
> +# Copyright (C) 2025 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/>.
> +
> +standard_testfile
> +
> +if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } {
> + return -1
> +}
> +
> +if { ![runto bar] } {
> + return -1
> +}
> +
> +with_test_prefix "in bar" {
> + gdb_test "return" \
> + [string_to_regexp "Can not force return from an inlined function."]
> +}
> +
> +gdb_test "up" \
> + [string_to_regexp "foo ()"].*
> +
> +gdb_test_no_output "set confirm off"
> +
> +with_test_prefix "in foo" {
> + gdb_test "return" \
> + [string_to_regexp "main ()"].*
> +}
>
> base-commit: d8c4a58b59eedbe1f77717d4e0537579232e6a10
--
Cheers,
Guinevere Larsen
She/Her/Hers
More information about the Gdb-patches
mailing list