[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