* [patch] Fix `return' of long/long-long results with no debuginfo
@ 2009-02-11 19:45 Jan Kratochvil
2009-02-11 20:40 ` Mark Kettenis
0 siblings, 1 reply; 38+ messages in thread
From: Jan Kratochvil @ 2009-02-11 19:45 UTC (permalink / raw)
To: gdb-patches
Hi,
the command `return' assumes `int' result when the current function has no
debug info. This assumption breaks for example `void *' return on x86_64.
Original bugreport: https://bugzilla.redhat.com/show_bug.cgi?id=365111
Regression-tested on x86_64-unknown-linux-gnu.
This testcase also covers the previous fix of the `return' crash:
http://sourceware.org/ml/gdb-patches/2009-01/msg00213.html
Thanks,
Jan
gdb/
2009-02-11 Jan Kratochvil <jan.kratochvil@redhat.com>
* stack.c (return_command): Default to the builtin_long_long type now.
gdb/testsuite/
2009-02-11 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.base/return-nodebug.exp, gdb.base/return-nodebug.c: New.
--- gdb/stack.c 11 Feb 2009 16:07:28 -0000 1.185
+++ gdb/stack.c 11 Feb 2009 19:42:10 -0000
@@ -1807,7 +1807,8 @@ return_command (char *retval_exp, int fr
if (thisfun != NULL)
return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun));
if (return_type == NULL)
- return_type = builtin_type (get_frame_arch (thisframe))->builtin_int;
+ return_type
+ = builtin_type (get_frame_arch (thisframe))->builtin_long_long;
CHECK_TYPEDEF (return_type);
return_value = value_cast (return_type, return_value);
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.base/return-nodebug.c 11 Feb 2009 19:42:12 -0000
@@ -0,0 +1,40 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2009 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 TYPE
+func (void)
+{
+ return (TYPE) -1;
+}
+
+static void
+marker (void)
+{
+}
+
+int
+main (void)
+{
+ printf ("result=" FORMAT "\n", CAST func ());
+
+ /* Cannot `next' with no debug info. */
+ marker ();
+
+ return 0;
+}
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.base/return-nodebug.exp 11 Feb 2009 19:42:12 -0000
@@ -0,0 +1,52 @@
+# Copyright (C) 2009 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/>.
+
+proc do_test {typenospace} {
+ global pf_prefix
+ set old_prefix $pf_prefix
+ lappend pf_prefix "$typenospace:"
+
+ if {[runto "func"]} {
+ # Test return from a function with no debug info (symbol; still it may
+ # have a minimal-symbol) if it does not crash.
+ gdb_test "return -1" "#0 .* main \\(.*" \
+ "return from function with no debug info" \
+ "Make selected stack frame return now\\? \\(y or n\\) " "y"
+
+ # And if it returned the full width of the result.
+ gdb_test "adv marker" "\r\nresult=-1\r\n.* in marker \\(.*" \
+ "full width of the returned result"
+ }
+
+ set pf_prefix $old_prefix
+}
+
+foreach case {{{char} %d (int)} \
+ {{short} %d (int)} \
+ {{int} %d} \
+ {{long} %ld} \
+ {{long long} %lld}} {
+ set type [lindex $case 0]
+ set format [lindex $case 1]
+ set cast [lindex $case 2]
+
+ set typeesc [string map {{ } {\ }} $type]
+ set typenospace [string map {{ } -} $type]
+
+ if {[prepare_for_testing return-nodebug.exp "return-nodebug-$typenospace" "return-nodebug.c" \
+ [list "additional_flags=-DFORMAT=\"$format\" -DTYPE=$typeesc -DCAST=$cast"]] == 0} {
+ do_test $typenospace
+ }
+}
^ permalink raw reply [flat|nested] 38+ messages in thread* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-02-11 19:45 [patch] Fix `return' of long/long-long results with no debuginfo Jan Kratochvil @ 2009-02-11 20:40 ` Mark Kettenis 2009-02-11 20:50 ` Daniel Jacobowitz 2009-02-21 15:58 ` Jan Kratochvil 0 siblings, 2 replies; 38+ messages in thread From: Mark Kettenis @ 2009-02-11 20:40 UTC (permalink / raw) To: jan.kratochvil; +Cc: gdb-patches > Date: Wed, 11 Feb 2009 20:45:11 +0100 > From: Jan Kratochvil <jan.kratochvil@redhat.com> > > Hi, > > the command `return' assumes `int' result when the current function has no > debug info. This assumption breaks for example `void *' return on x86_64. > > Original bugreport: https://bugzilla.redhat.com/show_bug.cgi?id=365111 > > Regression-tested on x86_64-unknown-linux-gnu. > > This testcase also covers the previous fix of the `return' crash: > http://sourceware.org/ml/gdb-patches/2009-01/msg00213.html > > > Thanks, > Jan Sorry, this is wrong. Functions without return type implicitly return int. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-02-11 20:40 ` Mark Kettenis @ 2009-02-11 20:50 ` Daniel Jacobowitz 2009-02-11 21:23 ` Mark Kettenis 2009-02-21 15:58 ` Jan Kratochvil 1 sibling, 1 reply; 38+ messages in thread From: Daniel Jacobowitz @ 2009-02-11 20:50 UTC (permalink / raw) To: Mark Kettenis; +Cc: jan.kratochvil, gdb-patches On Wed, Feb 11, 2009 at 09:40:00PM +0100, Mark Kettenis wrote: > Sorry, this is wrong. Functions without return type implicitly return int. I think it's a mistake to bring this rule (from K&R C, and removed in C99) to GDB. This is a different context; it's not functions declared without a return type in source code, but functions with an unknown return type (and unknown source language). Everything we pick will be wrong some of the time, but IMO "long" is maximally useful. "long long" on 32-bit platforms is going to pick up garbage from the next register for int or void * returns. Most platforms with int != long will have the return register with sizeof(long). -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-02-11 20:50 ` Daniel Jacobowitz @ 2009-02-11 21:23 ` Mark Kettenis 2009-02-11 21:47 ` Jan Kratochvil 0 siblings, 1 reply; 38+ messages in thread From: Mark Kettenis @ 2009-02-11 21:23 UTC (permalink / raw) To: drow; +Cc: jan.kratochvil, gdb-patches > Date: Wed, 11 Feb 2009 15:50:45 -0500 > From: Daniel Jacobowitz <drow@false.org> > > On Wed, Feb 11, 2009 at 09:40:00PM +0100, Mark Kettenis wrote: > > Sorry, this is wrong. Functions without return type implicitly return int. > > I think it's a mistake to bring this rule (from K&R C, and removed in > C99) to GDB. This is a different context; it's not functions declared > without a return type in source code, but functions with an unknown > return type (and unknown source language). I disagree. I think it is the behaviour that makes the most sense in a historical context. And I have a (somewhat) vague recollection that there are debug formats or compilers where we cant distinguish between functions without a return type and functions with "unknown" return type. > Everything we pick will be wrong some of the time, but IMO "long" is > maximally useful. "long long" on 32-bit platforms is going to pick > up garbage from the next register for int or void * returns. Most > platforms with int != long will have the return register with > sizeof(long). The right solution of course is to distribute libraries with debug sumbols. But in cases where that is impossible, would it be an idea to use the type of the return value expression given by the user instead of int as a fallback? In the case at hand, "return -1" will still fail, but it would be possible to do return (void *)-1 to do what the user wanted. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-02-11 21:23 ` Mark Kettenis @ 2009-02-11 21:47 ` Jan Kratochvil 2009-02-11 21:58 ` Mark Kettenis 2009-02-11 22:44 ` Mark Kettenis 0 siblings, 2 replies; 38+ messages in thread From: Jan Kratochvil @ 2009-02-11 21:47 UTC (permalink / raw) To: Mark Kettenis; +Cc: drow, gdb-patches On Wed, 11 Feb 2009 22:22:41 +0100, Mark Kettenis wrote: > And I have a (somewhat) vague recollection that there are debug formats or > compilers where we cant distinguish between functions without a return type > and functions with "unknown" return type. As `struct type' for a function type GDB debuginfo readers always create by make_function_type and this function crashes on NULL `type' we can assume TYPE_TARGET_TYPE is never NULL. For DWARF it is clear both according to the standard 3.3.2 Subroutine and Entry Point Return Types If the subroutine or entry point is a function that returns a value, then its debugging information entry has a DW_AT_type attribute [...] and according to the code: dwarf2read.c:die_type(): /* A missing DW_AT_type represents a void type. */ Made the condition in the patch more explicit now. Removed the original TYPE_CODE_VOID code emulating the K&R behavior to more follow the modern ANSI/ISO C compilers refuse `return value;' in a void-returning function without having typeless/`int'-defaulted functions permitted. > From: Daniel Jacobowitz <drow@false.org> > > Everything we pick will be wrong some of the time, but IMO "long" is > > maximally useful. "long long" on 32-bit platforms is going to pick > > up garbage from the next register for int or void * returns. Garbage would be seen by caller of a `long long' returning callee where GDB would return something smaller (like `int'). As GDB writes (not "reads") the register it just will write zero to one excessive but unused register. This register must be callee-saved (not caller-saved) by the ABI supporting `long long' return type and GDB already asserts the return type is RETURN_VALUE_REGISTER_CONVENTION. If GDB would return only the `long' size there would be no way how to do the `return' command on a debuginfo-less function natively returning `long long'. > The right solution of course is to distribute libraries with debug > sumbols. But in cases where that is impossible, would it be an idea > to use the type of the return value expression given by the user > instead of int as a fallback? Any return value gets retyped to `long long' which is intepreted by the caller even as lower-sized types (not guaranteed by ABI but at lest checked now by new gdb.base/return-nodebug.exp). > In the case at hand, "return -1" will still fail, but it would be > possible to do return (void *)-1 to do what the user wanted. `return -1' is checked by gdb.base/return-nodebug.exp and it works. Thanks, Jan gdb/ 2009-02-11 Jan Kratochvil <jan.kratochvil@redhat.com> * stack.c (return_command): Default to the builtin_long_long or at least builtin_long types now. Assert TYPE_TARGET_TYPE of a typed function is non-NULL. Error on return value for void returning functions. gdb/testsuite/ 2009-02-11 Jan Kratochvil <jan.kratochvil@redhat.com> * gdb.base/return-nodebug.exp, gdb.base/return-nodebug.c: New. * gdb.base/return2.exp (try to return value in a void function): New. --- gdb/stack.c 11 Feb 2009 16:07:28 -0000 1.185 +++ gdb/stack.c 11 Feb 2009 21:39:57 -0000 @@ -1805,9 +1805,23 @@ return_command (char *retval_exp, int fr /* Cast return value to the return type of the function. Should the cast fail, this call throws an error. */ if (thisfun != NULL) - return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun)); - if (return_type == NULL) - return_type = builtin_type (get_frame_arch (thisframe))->builtin_int; + { + return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun)); + gdb_assert (return_type != NULL); + if (TYPE_CODE (return_type) == TYPE_CODE_VOID) + error (_("Function %s does not return any value"), + SYMBOL_PRINT_NAME (thisfun)); + } + else + { + return_type + = builtin_type (get_frame_arch (thisframe))->builtin_long_long; + + /* Hopefull each ABI returns at least `long' type in register. */ + if (using_struct_return (NULL, return_type)) + return_type + = builtin_type (get_frame_arch (thisframe))->builtin_long; + } CHECK_TYPEDEF (return_type); return_value = value_cast (return_type, return_value); @@ -1816,14 +1830,7 @@ return_command (char *retval_exp, int fr if (value_lazy (return_value)) value_fetch_lazy (return_value); - if (TYPE_CODE (return_type) == TYPE_CODE_VOID) - /* If the return-type is "void", don't try to find the - return-value's location. However, do still evaluate the - return expression so that, even when the expression result - is discarded, side effects such as "return i++" still - occur. */ - return_value = NULL; - else if (thisfun != NULL + if (thisfun != NULL && using_struct_return (SYMBOL_TYPE (thisfun), return_type)) { query_prefix = "\ --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.base/return-nodebug.c 11 Feb 2009 21:40:00 -0000 @@ -0,0 +1,40 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2009 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 TYPE +func (void) +{ + return (TYPE) -1; +} + +static void +marker (void) +{ +} + +int +main (void) +{ + printf ("result=" FORMAT "\n", CAST func ()); + + /* Cannot `next' with no debug info. */ + marker (); + + return 0; +} --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.base/return-nodebug.exp 11 Feb 2009 21:40:00 -0000 @@ -0,0 +1,52 @@ +# Copyright (C) 2009 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/>. + +proc do_test {typenospace} { + global pf_prefix + set old_prefix $pf_prefix + lappend pf_prefix "$typenospace:" + + if {[runto "func"]} { + # Test return from a function with no debug info (symbol; still it may + # have a minimal-symbol) if it does not crash. + gdb_test "return -1" "#0 .* main \\(.*" \ + "return from function with no debug info" \ + "Make selected stack frame return now\\? \\(y or n\\) " "y" + + # And if it returned the full width of the result. + gdb_test "adv marker" "\r\nresult=-1\r\n.* in marker \\(.*" \ + "full width of the returned result" + } + + set pf_prefix $old_prefix +} + +foreach case {{{char} %d (int)} \ + {{short} %d (int)} \ + {{int} %d} \ + {{long} %ld} \ + {{long long} %lld}} { + set type [lindex $case 0] + set format [lindex $case 1] + set cast [lindex $case 2] + + set typeesc [string map {{ } {\ }} $type] + set typenospace [string map {{ } -} $type] + + if {[prepare_for_testing return-nodebug.exp "return-nodebug-$typenospace" "return-nodebug.c" \ + [list "additional_flags=-DFORMAT=\"$format\" -DTYPE=$typeesc -DCAST=$cast"]] == 0} { + do_test $typenospace + } +} --- gdb/testsuite/gdb.base/return2.exp 3 Jan 2009 05:58:03 -0000 1.11 +++ gdb/testsuite/gdb.base/return2.exp 11 Feb 2009 21:40:00 -0000 @@ -70,6 +70,8 @@ proc return_void { } { "set break on void_func" gdb_test "continue" "Breakpoint.* void_func.*" \ "continue to void_func" + gdb_test "return 23" "Function void_func does not return any value" \ + "try to return value in a void function" send_gdb "return \n" gdb_expect { -re "Make void_func return now.*y or n. $" { ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-02-11 21:47 ` Jan Kratochvil @ 2009-02-11 21:58 ` Mark Kettenis 2009-02-11 22:08 ` Jan Kratochvil 2009-02-11 22:44 ` Mark Kettenis 1 sibling, 1 reply; 38+ messages in thread From: Mark Kettenis @ 2009-02-11 21:58 UTC (permalink / raw) To: jan.kratochvil; +Cc: drow, gdb-patches > Date: Wed, 11 Feb 2009 22:46:47 +0100 > From: Jan Kratochvil <jan.kratochvil@redhat.com> Sorry Jan, are you really just ignoring my remarks and actually making this diff more unacceptable to me? > On Wed, 11 Feb 2009 22:22:41 +0100, Mark Kettenis wrote: > > And I have a (somewhat) vague recollection that there are debug formats or > > compilers where we cant distinguish between functions without a return type > > and functions with "unknown" return type. > > As `struct type' for a function type GDB debuginfo readers always create by > make_function_type and this function crashes on NULL `type' we can assume > TYPE_TARGET_TYPE is never NULL. > > For DWARF it is clear both according to the standard > 3.3.2 Subroutine and Entry Point Return Types > If the subroutine or entry point is a function that returns a value, then its > debugging information entry has a DW_AT_type attribute [...] > > and according to the code: > dwarf2read.c:die_type(): > /* A missing DW_AT_type represents a void type. */ > > > Made the condition in the patch more explicit now. Removed the original > TYPE_CODE_VOID code emulating the K&R behavior to more follow the modern > ANSI/ISO C compilers refuse `return value;' in a void-returning function > without having typeless/`int'-defaulted functions permitted. > > > > From: Daniel Jacobowitz <drow@false.org> > > > Everything we pick will be wrong some of the time, but IMO "long" is > > > maximally useful. "long long" on 32-bit platforms is going to pick > > > up garbage from the next register for int or void * returns. > > Garbage would be seen by caller of a `long long' returning callee where GDB > would return something smaller (like `int'). As GDB writes (not "reads") the > register it just will write zero to one excessive but unused register. This > register must be callee-saved (not caller-saved) by the ABI supporting `long > long' return type and GDB already asserts the return type is > RETURN_VALUE_REGISTER_CONVENTION. > > If GDB would return only the `long' size there would be no way how to do the > `return' command on a debuginfo-less function natively returning `long long'. > > > > The right solution of course is to distribute libraries with debug > > sumbols. But in cases where that is impossible, would it be an idea > > to use the type of the return value expression given by the user > > instead of int as a fallback? > > Any return value gets retyped to `long long' which is intepreted by the caller > even as lower-sized types (not guaranteed by ABI but at lest checked now by > new gdb.base/return-nodebug.exp). > > > > In the case at hand, "return -1" will still fail, but it would be > > possible to do return (void *)-1 to do what the user wanted. > > `return -1' is checked by gdb.base/return-nodebug.exp and it works. > > > Thanks, > Jan > > > gdb/ > 2009-02-11 Jan Kratochvil <jan.kratochvil@redhat.com> > > * stack.c (return_command): Default to the builtin_long_long or at > least builtin_long types now. Assert TYPE_TARGET_TYPE of a typed > function is non-NULL. Error on return value for void returning > functions. > > gdb/testsuite/ > 2009-02-11 Jan Kratochvil <jan.kratochvil@redhat.com> > > * gdb.base/return-nodebug.exp, gdb.base/return-nodebug.c: New. > * gdb.base/return2.exp (try to return value in a void function): New. > > --- gdb/stack.c 11 Feb 2009 16:07:28 -0000 1.185 > +++ gdb/stack.c 11 Feb 2009 21:39:57 -0000 > @@ -1805,9 +1805,23 @@ return_command (char *retval_exp, int fr > /* Cast return value to the return type of the function. Should > the cast fail, this call throws an error. */ > if (thisfun != NULL) > - return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun)); > - if (return_type == NULL) > - return_type = builtin_type (get_frame_arch (thisframe))->builtin_int; > + { > + return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun)); > + gdb_assert (return_type != NULL); > + if (TYPE_CODE (return_type) == TYPE_CODE_VOID) > + error (_("Function %s does not return any value"), > + SYMBOL_PRINT_NAME (thisfun)); > + } > + else > + { > + return_type > + = builtin_type (get_frame_arch (thisframe))->builtin_long_long; > + > + /* Hopefull each ABI returns at least `long' type in register. */ > + if (using_struct_return (NULL, return_type)) > + return_type > + = builtin_type (get_frame_arch (thisframe))->builtin_long; > + } > CHECK_TYPEDEF (return_type); > return_value = value_cast (return_type, return_value); > > @@ -1816,14 +1830,7 @@ return_command (char *retval_exp, int fr > if (value_lazy (return_value)) > value_fetch_lazy (return_value); > > - if (TYPE_CODE (return_type) == TYPE_CODE_VOID) > - /* If the return-type is "void", don't try to find the > - return-value's location. However, do still evaluate the > - return expression so that, even when the expression result > - is discarded, side effects such as "return i++" still > - occur. */ > - return_value = NULL; > - else if (thisfun != NULL > + if (thisfun != NULL > && using_struct_return (SYMBOL_TYPE (thisfun), return_type)) > { > query_prefix = "\ > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ gdb/testsuite/gdb.base/return-nodebug.c 11 Feb 2009 21:40:00 -0000 > @@ -0,0 +1,40 @@ > +/* This testcase is part of GDB, the GNU debugger. > + > + Copyright 2009 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 TYPE > +func (void) > +{ > + return (TYPE) -1; > +} > + > +static void > +marker (void) > +{ > +} > + > +int > +main (void) > +{ > + printf ("result=" FORMAT "\n", CAST func ()); > + > + /* Cannot `next' with no debug info. */ > + marker (); > + > + return 0; > +} > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ gdb/testsuite/gdb.base/return-nodebug.exp 11 Feb 2009 21:40:00 -0000 > @@ -0,0 +1,52 @@ > +# Copyright (C) 2009 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/>. > + > +proc do_test {typenospace} { > + global pf_prefix > + set old_prefix $pf_prefix > + lappend pf_prefix "$typenospace:" > + > + if {[runto "func"]} { > + # Test return from a function with no debug info (symbol; still it may > + # have a minimal-symbol) if it does not crash. > + gdb_test "return -1" "#0 .* main \\(.*" \ > + "return from function with no debug info" \ > + "Make selected stack frame return now\\? \\(y or n\\) " "y" > + > + # And if it returned the full width of the result. > + gdb_test "adv marker" "\r\nresult=-1\r\n.* in marker \\(.*" \ > + "full width of the returned result" > + } > + > + set pf_prefix $old_prefix > +} > + > +foreach case {{{char} %d (int)} \ > + {{short} %d (int)} \ > + {{int} %d} \ > + {{long} %ld} \ > + {{long long} %lld}} { > + set type [lindex $case 0] > + set format [lindex $case 1] > + set cast [lindex $case 2] > + > + set typeesc [string map {{ } {\ }} $type] > + set typenospace [string map {{ } -} $type] > + > + if {[prepare_for_testing return-nodebug.exp "return-nodebug-$typenospace" "return-nodebug.c" \ > + [list "additional_flags=-DFORMAT=\"$format\" -DTYPE=$typeesc -DCAST=$cast"]] == 0} { > + do_test $typenospace > + } > +} > --- gdb/testsuite/gdb.base/return2.exp 3 Jan 2009 05:58:03 -0000 1.11 > +++ gdb/testsuite/gdb.base/return2.exp 11 Feb 2009 21:40:00 -0000 > @@ -70,6 +70,8 @@ proc return_void { } { > "set break on void_func" > gdb_test "continue" "Breakpoint.* void_func.*" \ > "continue to void_func" > + gdb_test "return 23" "Function void_func does not return any value" \ > + "try to return value in a void function" > send_gdb "return \n" > gdb_expect { > -re "Make void_func return now.*y or n. $" { > ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-02-11 21:58 ` Mark Kettenis @ 2009-02-11 22:08 ` Jan Kratochvil 2009-02-11 22:38 ` Mark Kettenis 0 siblings, 1 reply; 38+ messages in thread From: Jan Kratochvil @ 2009-02-11 22:08 UTC (permalink / raw) To: Mark Kettenis; +Cc: drow, gdb-patches On Wed, 11 Feb 2009 22:22:41 +0100, Mark Kettenis wrote: # I disagree. I think it is the behaviour that makes the most sense in # a historical context. And I have a (somewhat) vague recollection that On Wed, 11 Feb 2009 22:57:51 +0100, Mark Kettenis wrote: > Sorry Jan, are you really just ignoring my remarks and actually making > this diff more unacceptable to me? I cannot agree GDB should prefer to simulate the K&R C behavior over ANSI/ISO C behavior. Sure I do not have the approval right so I will do anything I am told with the patch to check it in. Still FYI so far I has not been convinced to change my opinion on this (K&R vs. ANSI/ISO C) specific subject. I am sorry if spending the time to read my patch was not acceptable for you. Regards, Jan ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-02-11 22:08 ` Jan Kratochvil @ 2009-02-11 22:38 ` Mark Kettenis 2009-02-11 22:50 ` Jan Kratochvil 0 siblings, 1 reply; 38+ messages in thread From: Mark Kettenis @ 2009-02-11 22:38 UTC (permalink / raw) To: jan.kratochvil; +Cc: drow, gdb-patches > Date: Wed, 11 Feb 2009 23:08:24 +0100 > From: Jan Kratochvil <jan.kratochvil@redhat.com> > > On Wed, 11 Feb 2009 22:22:41 +0100, Mark Kettenis wrote: > # I disagree. I think it is the behaviour that makes the most sense in > # a historical context. And I have a (somewhat) vague recollection that > > On Wed, 11 Feb 2009 22:57:51 +0100, Mark Kettenis wrote: > > Sorry Jan, are you really just ignoring my remarks and actually making > > this diff more unacceptable to me? > > I cannot agree GDB should prefer to simulate the K&R C behavior over > ANSI/ISO C behavior. Sure I do not have the approval right so I > will do anything I am told with the patch to check it in. Still FYI > so far I has not been convinced to change my opinion on this (K&R > vs. ANSI/ISO C) specific subject. We can agree to disagree. That said, there should be no reason to unecessarily get rid of the K&R and older ISO C heritage if there is no good reason to do so. The bug report you cite provides a reason. In my reply to Daniel's mail I provided an alternative suggestion: > ..., would it be an idea to use the type of the return value > expression given by the user instead of int as a fallback? Which you seemed to ignore. I think it actually makes the return command more powerful, by letting the user (implicitly or explicitly) specify the return type of a function for which debugging information is missing. Can you please consider the suggestion I make? ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-02-11 22:38 ` Mark Kettenis @ 2009-02-11 22:50 ` Jan Kratochvil 2009-03-03 18:10 ` Tom Tromey 0 siblings, 1 reply; 38+ messages in thread From: Jan Kratochvil @ 2009-02-11 22:50 UTC (permalink / raw) To: Mark Kettenis; +Cc: drow, gdb-patches On Wed, 11 Feb 2009 23:37:38 +0100, Mark Kettenis wrote: > > ..., would it be an idea to use the type of the return value > > expression given by the user instead of int as a fallback? > > Which you seemed to ignore. I think it actually makes the return > command more powerful, by letting the user (implicitly or explicitly) > specify the return type of a function for which debugging information > is missing. Can you please consider the suggestion I make? Your suggestion ("type of the return value expression given by the user"): + improvement over the current state (one _can_ return long or long long) - may be more tricky to the user (requirement to cast to long or long long if the inferior function returns such type) (as the redhat.com Bug would be still filed on this implementation by the user I did not find it acceptable myself no matter of its technical aspects) My suggestion (long long cast forced by GDB): + improvement over the current state - like yours + easier for the user automatically fixing his mistakes - possibly incompatible with ABI having `int' value placement incompatible with `long long' value placement - possibly incompatible with ABI not having `long' returned in a register (both ABI requirements are compliant with the common ABIs I am aware of) You are right I should have been more addressing your opinion. Regards, Jan ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-02-11 22:50 ` Jan Kratochvil @ 2009-03-03 18:10 ` Tom Tromey 2009-03-04 21:29 ` Mark Kettenis 0 siblings, 1 reply; 38+ messages in thread From: Tom Tromey @ 2009-03-03 18:10 UTC (permalink / raw) To: Jan Kratochvil; +Cc: Mark Kettenis, drow, gdb-patches >>>>> "Jan" == Jan Kratochvil <jan.kratochvil@redhat.com> writes: Weighing in on an old-ish thread. AFAIK this has never reached any sort of resolution. Jan> Your suggestion ("type of the return value expression given by the user"): Jan> + improvement over the current state (one _can_ return long or long long) Jan> - may be more tricky to the user (requirement to cast to long or long long if Jan> the inferior function returns such type) How about, in the specific case of "return" from a function without debug info, we simply require the user to supply a cast to the desired type. This avoids any problems in choosing a default and it helps avoid errors introduced by using the type implicit in the expression. Tom ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-03-03 18:10 ` Tom Tromey @ 2009-03-04 21:29 ` Mark Kettenis 2009-03-05 0:15 ` Tom Tromey 0 siblings, 1 reply; 38+ messages in thread From: Mark Kettenis @ 2009-03-04 21:29 UTC (permalink / raw) To: tromey; +Cc: jan.kratochvil, drow, gdb-patches > From: Tom Tromey <tromey@redhat.com> > Date: Tue, 03 Mar 2009 11:10:19 -0700 > > >>>>> "Jan" == Jan Kratochvil <jan.kratochvil@redhat.com> writes: > > Weighing in on an old-ish thread. AFAIK this has never reached any > sort of resolution. > > Jan> Your suggestion ("type of the return value expression given by the user"): > Jan> + improvement over the current state (one _can_ return long or long long) > Jan> - may be more tricky to the user (requirement to cast to long or long long if > Jan> the inferior function returns such type) > > How about, in the specific case of "return" from a function without > debug info, we simply require the user to supply a cast to the desired > type. This avoids any problems in choosing a default and it helps > avoid errors introduced by using the type implicit in the expression. Do we have a way to figure out if such a cast is present in the expression passed as an argument to the return command? ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-03-04 21:29 ` Mark Kettenis @ 2009-03-05 0:15 ` Tom Tromey 2009-03-09 1:55 ` Jan Kratochvil 0 siblings, 1 reply; 38+ messages in thread From: Tom Tromey @ 2009-03-05 0:15 UTC (permalink / raw) To: Mark Kettenis; +Cc: jan.kratochvil, drow, gdb-patches >>>>> "Mark" == Mark Kettenis <mark.kettenis@xs4all.nl> writes: Mark> Do we have a way to figure out if such a cast is present in the Mark> expression passed as an argument to the return command? Yeah, it is not too hard. It just means having return_command call parse_expression directly, then look at the resulting expression. Tom ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-03-05 0:15 ` Tom Tromey @ 2009-03-09 1:55 ` Jan Kratochvil 2009-03-09 22:38 ` Mark Kettenis 0 siblings, 1 reply; 38+ messages in thread From: Jan Kratochvil @ 2009-03-09 1:55 UTC (permalink / raw) To: Tom Tromey; +Cc: Mark Kettenis, drow, gdb-patches On Thu, 05 Mar 2009 01:15:08 +0100, Tom Tromey wrote: > >>>>> "Mark" == Mark Kettenis <mark.kettenis@xs4all.nl> writes: > > Mark> Do we have a way to figure out if such a cast is present in the > Mark> expression passed as an argument to the return command? > > Yeah, it is not too hard. It just means having return_command call > parse_expression directly, then look at the resulting expression. Attached, check-in approval requested. Regards, Jan gdb/ 2009-03-09 Jan Kratochvil <jan.kratochvil@redhat.com> * stack.c (return_command <retval_exp>): New variables retval_expr and old_chain. Inline parse_and_eval to initialize retval_expr. Check RETVAL_EXPR for UNOP_CAST and set RETURN_TYPE to the RETURN_VALUE type if RETURN_TYPE is NULL. gdb/testsuite/ 2009-03-09 Jan Kratochvil <jan.kratochvil@redhat.com> * gdb.base/return-nodebug.exp, gdb.base/return-nodebug.S: New. --- gdb/stack.c 6 Mar 2009 18:51:05 -0000 1.186 +++ gdb/stack.c 9 Mar 2009 01:52:55 -0000 @@ -1796,18 +1796,26 @@ return_command (char *retval_exp, int fr message. */ if (retval_exp) { + struct expression *retval_expr = parse_expression (retval_exp); + struct cleanup *old_chain = make_cleanup (xfree, retval_expr); struct type *return_type = NULL; /* Compute the return value. Should the computation fail, this call throws an error. */ - return_value = parse_and_eval (retval_exp); + return_value = evaluate_expression (retval_expr); /* Cast return value to the return type of the function. Should the cast fail, this call throws an error. */ if (thisfun != NULL) return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun)); if (return_type == NULL) - return_type = builtin_type (get_frame_arch (thisframe))->builtin_int; + { + if (retval_expr->elts[0].opcode != UNOP_CAST) + error (_("Selected stack frame (with no associated function) " + "requires an explicit cast of the value to return")); + return_type = value_type (return_value); + } + do_cleanups (old_chain); CHECK_TYPEDEF (return_type); return_value = value_cast (return_type, return_value); --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.base/return-nodebug.c 9 Mar 2009 01:52:55 -0000 @@ -0,0 +1,49 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2009 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 TYPE +init (void) +{ + return 0; +} + +static TYPE +func (void) +{ + return 31; +} + +static void +marker (void) +{ +} + +int +main (void) +{ + /* Preinitialize registers to 0 to avoid false PASS by leftover garbage. */ + init (); + + printf ("result=" FORMAT "\n", CAST func ()); + + /* Cannot `next' with no debug info. */ + marker (); + + return 0; +} --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.base/return-nodebug.exp 9 Mar 2009 01:52:55 -0000 @@ -0,0 +1,60 @@ +# Copyright (C) 2009 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/>. + +proc do_test {type} { + set typenospace [string map {{ } -} $type] + + global pf_prefix + set old_prefix $pf_prefix + lappend pf_prefix "$typenospace:" + + if {[runto "func"]} { + # Test return from a function with no debug info (symbol; still it may + # have a minimal-symbol) if it does not crash. + + gdb_test "return -1" \ + "Selected stack frame \\(with no associated function\\) requires an explicit cast of the value to return" \ + "return from function with no debug info without a cast" + + # Cast of the result to the proper width must be done explicitely. + gdb_test "return ($type) -1" "#0 .* main \\(.*" \ + "return from function with no debug info with a cast" \ + "Make selected stack frame return now\\? \\(y or n\\) " "y" + + # And if it returned the full width of the result. + gdb_test "adv marker" "\r\nresult=-1\r\n.* in marker \\(.*" \ + "full width of the returned result" + } + + set pf_prefix $old_prefix +} + +foreach case {{{signed char} %d (int)} \ + {{short} %d (int)} \ + {{int} %d} \ + {{long} %ld} \ + {{long long} %lld}} { + set type [lindex $case 0] + set format [lindex $case 1] + set cast [lindex $case 2] + + set typeesc [string map {{ } {\ }} $type] + set typenospace [string map {{ } -} $type] + + if {[prepare_for_testing return-nodebug.exp "return-nodebug-$typenospace" "return-nodebug.c" \ + [list "additional_flags=-DFORMAT=\"$format\" -DTYPE=$typeesc -DCAST=$cast"]] == 0} { + do_test $type + } +} ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-03-09 1:55 ` Jan Kratochvil @ 2009-03-09 22:38 ` Mark Kettenis 2009-03-11 16:49 ` Joel Brobecker 0 siblings, 1 reply; 38+ messages in thread From: Mark Kettenis @ 2009-03-09 22:38 UTC (permalink / raw) To: jan.kratochvil; +Cc: tromey, drow, gdb-patches > Date: Mon, 9 Mar 2009 02:55:10 +0100 > From: Jan Kratochvil <jan.kratochvil@redhat.com> > > On Thu, 05 Mar 2009 01:15:08 +0100, Tom Tromey wrote: > > >>>>> "Mark" == Mark Kettenis <mark.kettenis@xs4all.nl> writes: > > > > Mark> Do we have a way to figure out if such a cast is present in the > > Mark> expression passed as an argument to the return command? > > > > Yeah, it is not too hard. It just means having return_command call > > parse_expression directly, then look at the resulting expression. > > Attached, check-in approval requested. I think this is a reasonable compromise, and I think the implementation is ok. But I'd like the opinion of one of the other global maintainers (Daniel?, Joel?) before going this way. > gdb/ > 2009-03-09 Jan Kratochvil <jan.kratochvil@redhat.com> > > * stack.c (return_command <retval_exp>): New variables retval_expr > and old_chain. Inline parse_and_eval to initialize retval_expr. Check > RETVAL_EXPR for UNOP_CAST and set RETURN_TYPE to the RETURN_VALUE type > if RETURN_TYPE is NULL. > > gdb/testsuite/ > 2009-03-09 Jan Kratochvil <jan.kratochvil@redhat.com> > > * gdb.base/return-nodebug.exp, gdb.base/return-nodebug.S: New. > > --- gdb/stack.c 6 Mar 2009 18:51:05 -0000 1.186 > +++ gdb/stack.c 9 Mar 2009 01:52:55 -0000 > @@ -1796,18 +1796,26 @@ return_command (char *retval_exp, int fr > message. */ > if (retval_exp) > { > + struct expression *retval_expr = parse_expression (retval_exp); > + struct cleanup *old_chain = make_cleanup (xfree, retval_expr); > struct type *return_type = NULL; > > /* Compute the return value. Should the computation fail, this > call throws an error. */ > - return_value = parse_and_eval (retval_exp); > + return_value = evaluate_expression (retval_expr); > > /* Cast return value to the return type of the function. Should > the cast fail, this call throws an error. */ > if (thisfun != NULL) > return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun)); > if (return_type == NULL) > - return_type = builtin_type (get_frame_arch (thisframe))->builtin_int; > + { > + if (retval_expr->elts[0].opcode != UNOP_CAST) > + error (_("Selected stack frame (with no associated function) " > + "requires an explicit cast of the value to return")); > + return_type = value_type (return_value); > + } > + do_cleanups (old_chain); > CHECK_TYPEDEF (return_type); > return_value = value_cast (return_type, return_value); > > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ gdb/testsuite/gdb.base/return-nodebug.c 9 Mar 2009 01:52:55 -0000 > @@ -0,0 +1,49 @@ > +/* This testcase is part of GDB, the GNU debugger. > + > + Copyright 2009 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 TYPE > +init (void) > +{ > + return 0; > +} > + > +static TYPE > +func (void) > +{ > + return 31; > +} > + > +static void > +marker (void) > +{ > +} > + > +int > +main (void) > +{ > + /* Preinitialize registers to 0 to avoid false PASS by leftover garbage. */ > + init (); > + > + printf ("result=" FORMAT "\n", CAST func ()); > + > + /* Cannot `next' with no debug info. */ > + marker (); > + > + return 0; > +} > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ gdb/testsuite/gdb.base/return-nodebug.exp 9 Mar 2009 01:52:55 -0000 > @@ -0,0 +1,60 @@ > +# Copyright (C) 2009 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/>. > + > +proc do_test {type} { > + set typenospace [string map {{ } -} $type] > + > + global pf_prefix > + set old_prefix $pf_prefix > + lappend pf_prefix "$typenospace:" > + > + if {[runto "func"]} { > + # Test return from a function with no debug info (symbol; still it may > + # have a minimal-symbol) if it does not crash. > + > + gdb_test "return -1" \ > + "Selected stack frame \\(with no associated function\\) requires an explicit cast of the value to return" \ > + "return from function with no debug info without a cast" > + > + # Cast of the result to the proper width must be done explicitely. > + gdb_test "return ($type) -1" "#0 .* main \\(.*" \ > + "return from function with no debug info with a cast" \ > + "Make selected stack frame return now\\? \\(y or n\\) " "y" > + > + # And if it returned the full width of the result. > + gdb_test "adv marker" "\r\nresult=-1\r\n.* in marker \\(.*" \ > + "full width of the returned result" > + } > + > + set pf_prefix $old_prefix > +} > + > +foreach case {{{signed char} %d (int)} \ > + {{short} %d (int)} \ > + {{int} %d} \ > + {{long} %ld} \ > + {{long long} %lld}} { > + set type [lindex $case 0] > + set format [lindex $case 1] > + set cast [lindex $case 2] > + > + set typeesc [string map {{ } {\ }} $type] > + set typenospace [string map {{ } -} $type] > + > + if {[prepare_for_testing return-nodebug.exp "return-nodebug-$typenospace" "return-nodebug.c" \ > + [list "additional_flags=-DFORMAT=\"$format\" -DTYPE=$typeesc -DCAST=$cast"]] == 0} { > + do_test $type > + } > +} > ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-03-09 22:38 ` Mark Kettenis @ 2009-03-11 16:49 ` Joel Brobecker 2009-03-11 20:23 ` Tom Tromey 0 siblings, 1 reply; 38+ messages in thread From: Joel Brobecker @ 2009-03-11 16:49 UTC (permalink / raw) To: Mark Kettenis; +Cc: jan.kratochvil, tromey, drow, gdb-patches > 2009-03-09 Jan Kratochvil <jan.kratochvil@redhat.com> > > * stack.c (return_command <retval_exp>): New variables retval_expr > and old_chain. Inline parse_and_eval to initialize retval_expr. Check > RETVAL_EXPR for UNOP_CAST and set RETURN_TYPE to the RETURN_VALUE type > if RETURN_TYPE is NULL. This looks good to me, but I don't understand the error message when the user forgot to cast the result. I wonder if we shouldn't just preserve the old behavior which is to implicitly cast to "int"? > > if (return_type == NULL) > > - return_type = builtin_type (get_frame_arch (thisframe))->builtin_int; > > + { > > + if (retval_expr->elts[0].opcode != UNOP_CAST) > > + error (_("Selected stack frame (with no associated function) " > > + "requires an explicit cast of the value to return")); > > + return_type = value_type (return_value); > > + } -- Joel ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-03-11 16:49 ` Joel Brobecker @ 2009-03-11 20:23 ` Tom Tromey 2009-03-11 21:48 ` Joel Brobecker 0 siblings, 1 reply; 38+ messages in thread From: Tom Tromey @ 2009-03-11 20:23 UTC (permalink / raw) To: Joel Brobecker; +Cc: Mark Kettenis, jan.kratochvil, drow, gdb-patches >>>>> "Joel" == Joel Brobecker <brobecker@adacore.com> writes: >> 2009-03-09 Jan Kratochvil <jan.kratochvil@redhat.com> >> >> * stack.c (return_command <retval_exp>): New variables retval_expr >> and old_chain. Inline parse_and_eval to initialize retval_expr. Check >> RETVAL_EXPR for UNOP_CAST and set RETURN_TYPE to the RETURN_VALUE type >> if RETURN_TYPE is NULL. Joel> This looks good to me, but I don't understand the error message when Joel> the user forgot to cast the result. I wonder if we shouldn't just Joel> preserve the old behavior which is to implicitly cast to "int"? We've come full circle :-) The original patch was motivated by a case where casting to int gave a bad result. Then Mark had a counter-proposal, which was to use the expression's type, rather than assuming 'int'. Finally, I suggested simply requiring a cast, resulting in this patch. So, the real question for you is how you think it ought to work. I think we have implementations of all of the approaches now. Tom ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-03-11 20:23 ` Tom Tromey @ 2009-03-11 21:48 ` Joel Brobecker 2009-03-13 19:50 ` Jan Kratochvil 0 siblings, 1 reply; 38+ messages in thread From: Joel Brobecker @ 2009-03-11 21:48 UTC (permalink / raw) To: Tom Tromey; +Cc: Mark Kettenis, jan.kratochvil, drow, gdb-patches > The original patch was motivated by a case where casting to int gave a > bad result. Then Mark had a counter-proposal, which was to use the > expression's type, rather than assuming 'int'. Finally, I suggested > simply requiring a cast, resulting in this patch. Ah, OK - I didn't understand the final decision very well. Sorry about that. I'm starting to understand what the error message is trying to say, now. Can we maybe explore other suggestions? I can suggest for instance: Return value type not available for selected stack frame.\n Please use an explicit cast of the value to return. I think we should also probably add a note in the documentation as well. In case a user still gets confused as to why he gets an error. > So, the real question for you is how you think it ought to work. Yes, I think so. -- Joel ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-03-11 21:48 ` Joel Brobecker @ 2009-03-13 19:50 ` Jan Kratochvil 2009-03-13 23:00 ` Joel Brobecker 2009-03-14 10:45 ` Eli Zaretskii 0 siblings, 2 replies; 38+ messages in thread From: Jan Kratochvil @ 2009-03-13 19:50 UTC (permalink / raw) To: Joel Brobecker; +Cc: Tom Tromey, Mark Kettenis, drow, gdb-patches On Wed, 11 Mar 2009 21:59:01 +0100, Joel Brobecker wrote: > I'm starting to understand what the error message is trying to say, now. > Can we maybe explore other suggestions? I can suggest for instance: > > Return value type not available for selected stack frame.\n > Please use an explicit cast of the value to return. Used this text. > I think we should also probably add a note in the documentation as well. > In case a user still gets confused as to why he gets an error. Written a new part for `Returning'. Thanks, Jan gdb/ 2009-03-13 Jan Kratochvil <jan.kratochvil@redhat.com> * stack.c (return_command <retval_exp>): New variables retval_expr and old_chain. Inline parse_and_eval to initialize retval_expr. Check RETVAL_EXPR for UNOP_CAST and set RETURN_TYPE to the RETURN_VALUE type if RETURN_TYPE is NULL. gdb/doc/ 2009-03-13 Jan Kratochvil <jan.kratochvil@redhat.com> * gdb.texinfo (Returning): New description for missing debug info. gdb/testsuite/ 2009-03-13 Jan Kratochvil <jan.kratochvil@redhat.com> * gdb.base/return-nodebug.exp, gdb.base/return-nodebug.S: New. --- gdb/stack.c 6 Mar 2009 18:51:05 -0000 1.186 +++ gdb/stack.c 13 Mar 2009 16:56:21 -0000 @@ -1796,18 +1796,27 @@ return_command (char *retval_exp, int fr message. */ if (retval_exp) { + struct expression *retval_expr = parse_expression (retval_exp); + struct cleanup *old_chain = make_cleanup (xfree, retval_expr); struct type *return_type = NULL; /* Compute the return value. Should the computation fail, this call throws an error. */ - return_value = parse_and_eval (retval_exp); + return_value = evaluate_expression (retval_expr); /* Cast return value to the return type of the function. Should the cast fail, this call throws an error. */ if (thisfun != NULL) return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun)); if (return_type == NULL) - return_type = builtin_type (get_frame_arch (thisframe))->builtin_int; + { + if (retval_expr->elts[0].opcode != UNOP_CAST) + error (_("Return value type not available for selected " + "stack frame.\n" + "Please use an explicit cast of the value to return.")); + return_type = value_type (return_value); + } + do_cleanups (old_chain); CHECK_TYPEDEF (return_type); return_value = value_cast (return_type, return_value); --- gdb/doc/gdb.texinfo 5 Mar 2009 23:11:11 -0000 1.561 +++ gdb/doc/gdb.texinfo 13 Mar 2009 16:56:32 -0000 @@ -12494,6 +12494,41 @@ returned. In contrast, the @code{finish and Stepping, ,Continuing and Stepping}) resumes execution until the selected stack frame returns naturally. +@value{GDBN} needs to know how the @var{expression} argument should be set for +the inferior. The concrete registers assignment depends on the OS ABI and the +type being returned by the selected stack frame. + +As the selected stack frame function may not have its debug info available in +such cases @value{GDBN} needs to find out the type to return from user. For +example typing @samp{return -1} with its implicit type @code{int} would set +only a part of a @code{long long int} result for a debug info less function. +Therefore the implicit return type is accepted for debug info featuring +functions as in this case: + +@smallexample +Breakpoint 1, func () at gdb.base/return-nodebug.c:29 +29 return 31; +(@value{GDBP}) return -1 +Make func return now? (y or n) y +#0 0x004004f6 in main () at gdb.base/return-nodebug.c:43 +43 printf ("result=%lld\n", func ()); +(@value{GDBP}) +@end smallexample + +But for functions missing their debug info the user is required to specify the +return type by an appropriate cast explicitely: + +@smallexample +Breakpoint 2, 0x0040050b in func () +(@value{GDBP}) return -1 +Return value type not available for selected stack frame. +Please use an explicit cast of the value to return. +(@value{GDBP}) return (long long int) -1 +Make selected stack frame return now? (y or n) y +#0 0x00400526 in main () +(@value{GDBP}) +@end smallexample + @node Calling @section Calling Program Functions --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.base/return-nodebug.c 13 Mar 2009 16:56:32 -0000 @@ -0,0 +1,49 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2009 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 TYPE +init (void) +{ + return 0; +} + +static TYPE +func (void) +{ + return 31; +} + +static void +marker (void) +{ +} + +int +main (void) +{ + /* Preinitialize registers to 0 to avoid false PASS by leftover garbage. */ + init (); + + printf ("result=" FORMAT "\n", CAST func ()); + + /* Cannot `next' with no debug info. */ + marker (); + + return 0; +} --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.base/return-nodebug.exp 13 Mar 2009 16:56:32 -0000 @@ -0,0 +1,60 @@ +# Copyright (C) 2009 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/>. + +proc do_test {type} { + set typenospace [string map {{ } -} $type] + + global pf_prefix + set old_prefix $pf_prefix + lappend pf_prefix "$typenospace:" + + if {[runto "func"]} { + # Test return from a function with no debug info (symbol; still it may + # have a minimal-symbol) if it does not crash. + + gdb_test "return -1" \ + "Return value type not available for selected stack frame\\.\r\nPlease use an explicit cast of the value to return\\." \ + "return from function with no debug info without a cast" + + # Cast of the result to the proper width must be done explicitely. + gdb_test "return ($type) -1" "#0 .* main \\(.*" \ + "return from function with no debug info with a cast" \ + "Make selected stack frame return now\\? \\(y or n\\) " "y" + + # And if it returned the full width of the result. + gdb_test "adv marker" "\r\nresult=-1\r\n.* in marker \\(.*" \ + "full width of the returned result" + } + + set pf_prefix $old_prefix +} + +foreach case {{{signed char} %d (int)} \ + {{short} %d (int)} \ + {{int} %d} \ + {{long} %ld} \ + {{long long} %lld}} { + set type [lindex $case 0] + set format [lindex $case 1] + set cast [lindex $case 2] + + set typeesc [string map {{ } {\ }} $type] + set typenospace [string map {{ } -} $type] + + if {[prepare_for_testing return-nodebug.exp "return-nodebug-$typenospace" "return-nodebug.c" \ + [list "additional_flags=-DFORMAT=\"$format\" -DTYPE=$typeesc -DCAST=$cast"]] == 0} { + do_test $type + } +} ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-03-13 19:50 ` Jan Kratochvil @ 2009-03-13 23:00 ` Joel Brobecker 2009-03-14 10:45 ` Eli Zaretskii 1 sibling, 0 replies; 38+ messages in thread From: Joel Brobecker @ 2009-03-13 23:00 UTC (permalink / raw) To: Jan Kratochvil; +Cc: Tom Tromey, Mark Kettenis, drow, gdb-patches > 2009-03-13 Jan Kratochvil <jan.kratochvil@redhat.com> > > * stack.c (return_command <retval_exp>): New variables retval_expr > and old_chain. Inline parse_and_eval to initialize retval_expr. Check > RETVAL_EXPR for UNOP_CAST and set RETURN_TYPE to the RETURN_VALUE type > if RETURN_TYPE is NULL. This part looks good to me. > gdb/testsuite/ > 2009-03-13 Jan Kratochvil <jan.kratochvil@redhat.com> > > * gdb.base/return-nodebug.exp, gdb.base/return-nodebug.S: New. This part looks good to me too. Just a couple of things: - The name of the C file has a small typo in the extension.... - A comment seems malformed: > + # Test return from a function with no debug info (symbol; still it may > + # have a minimal-symbol) if it does not crash. The part in between parens sound strange. I can suggest: # Verify that we do not crash when using "return" from a function # with no debugging info (it may still have an associated minimal # symbol). I'm not sure that the side note about having minimal symbols is really necessary, though, but it's definitely not harmful in this case... (thanks for teaching me about "prepare_for_testing" ;-) -- Joel ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-03-13 19:50 ` Jan Kratochvil 2009-03-13 23:00 ` Joel Brobecker @ 2009-03-14 10:45 ` Eli Zaretskii 2009-03-14 22:09 ` Jan Kratochvil 1 sibling, 1 reply; 38+ messages in thread From: Eli Zaretskii @ 2009-03-14 10:45 UTC (permalink / raw) To: Jan Kratochvil; +Cc: brobecker, tromey, mark.kettenis, drow, gdb-patches > Date: Fri, 13 Mar 2009 18:11:35 +0100 > From: Jan Kratochvil <jan.kratochvil@redhat.com> > Cc: Tom Tromey <tromey@redhat.com>, Mark Kettenis <mark.kettenis@xs4all.nl>, drow@false.org, gdb-patches@sourceware.org > > gdb/doc/ > 2009-03-13 Jan Kratochvil <jan.kratochvil@redhat.com> > > * gdb.texinfo (Returning): New description for missing debug info. Thanks, this part is approved, provided that you add the missing punctuation and clarify the text, as indicated below. > + The concrete registers assignment depends on the OS ABI and the > +type being returned by the selected stack frame. I'm not sure the reader will understand why this sentence is here. Perhaps it is important to have this note, but then please add some (apparently missing) text that would explain how register assignment is relevant to the issue at hand. Maybe you need to begin with the normal case, where both the caller and the callee have debug info, and take it from there to the two less obvious cases. See below. > +As the selected stack frame function may not have its debug info available in > +such cases @value{GDBN} needs to find out the type to return from user. For ^ Missing comma. > +example typing @samp{return -1} with its implicit type @code{int} would set ^ Missing comma. Also, please use @kbd{return -1} instead of @samp, as you are describing keyboard input. > would set > +only a part of a @code{long long int} result for a debug info less function. I think it is better to talk about more general mismatch of an `int' and the function's return type, because the "partial fill" case is just a special case, and even then only on some platforms. That's assuming that there is indeed a place for generalization: would your first example still work the same if the return value of the function were `double'? > +Therefore the implicit return type is accepted for debug info featuring > +functions as in this case: > + > +@smallexample > +Breakpoint 1, func () at gdb.base/return-nodebug.c:29 > +29 return 31; > +(@value{GDBP}) return -1 > +Make func return now? (y or n) y > +#0 0x004004f6 in main () at gdb.base/return-nodebug.c:43 > +43 printf ("result=%lld\n", func ()); > +(@value{GDBP}) > +@end smallexample > + > +But for functions missing their debug info the user is required to specify the > +return type by an appropriate cast explicitely: ^^^^^^^^^^^ A typo. Anyway, this is confusing: the paragraph begins by talking about functions without debug info, but then you give an example for a function _with_ debug info, and say "Therefore", as if the example where GDB does accept incomplete spec of the return value somehow _follows_ from the immediately preceeding discussion. I would begin with describing the normal case explicitly, before the text you wrote. Something like: Normally, both the selected stack frame and the one above it have debug info. @value{GDBN} uses the debug info when the value of @var{expression} does not have an explicit data type. For example, if you type @kbd{return -1}, and the function in the current stack frame is declared to return a @code{long long int}, @value{GDBN} transparently converts the implicit @code{int} value of -1 into a @code{long long int}: <Put here your first example.> However, if the selected stack frame does not have a debug info, e.g., if the function was compiled without debug info, ... and now describe the use-case you are talking about and give your second example. OK? ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-03-14 10:45 ` Eli Zaretskii @ 2009-03-14 22:09 ` Jan Kratochvil 2009-03-14 22:18 ` Eli Zaretskii 2009-03-15 9:22 ` Joel Brobecker 0 siblings, 2 replies; 38+ messages in thread From: Jan Kratochvil @ 2009-03-14 22:09 UTC (permalink / raw) To: Joel Brobecker, Eli Zaretskii Cc: Tom Tromey, Mark Kettenis, drow, gdb-patches On Fri, 13 Mar 2009 23:46:53 +0100, Joel Brobecker wrote: > > + # Test return from a function with no debug info (symbol; still it may > > + # have a minimal-symbol) if it does not crash. > > The part in between parens sound strange. I can suggest: > > # Verify that we do not crash when using "return" from a function > # with no debugging info (it may still have an associated minimal > # symbol). > > I'm not sure that the side note about having minimal symbols is really > necessary, though, but it's definitely not harmful in this case... The statement `no debugging info' itself is too ambiguous. I had a mess in it myself some years ago and I still find people do not properly distinguish .symtab/.dynsym/.debug_info, which of these are ELF vs. DWARF, gcc (none)/-s/-g/strip and how they are related to GDB minimal_symbol/partial_symbol/symbol. As you removed the `symbol' part, used now this text (also in the patch): # Verify that we do not crash when using "return" from a function with # no debugging info. Such function has no `struct symbol'. It may # still have an associated `struct minimal_symbol'. On Sat, 14 Mar 2009 11:21:30 +0100, Eli Zaretskii wrote: > Thanks, this part is approved, provided that you add the missing > punctuation and clarify the text, as indicated below. Tried to address all your objections. > would your first example still work the same if the return value of the > function were `double'? Yes, there is no testcase for float types but it also gets the implicit/explicit casting rules (and different registers assignments). > Normally, both the selected stack frame and the one above it have > debug info. Talking about the debug info of the caller IMO makes the situation needlessly more difficult. Only the callee debug info availability is important for `return'. > @value{GDBN} uses the debug info when the value of > @var{expression} does not have an explicit data type. The current approved patch still fully follows the type found in the debug info if the debug info is present. The change was that if the debug info is not present the original code assumed int, the new code requires in the missing debug info case an explicit cast and uses this type it was casted as by the GDB user. Thanks, Jan gdb/ 2009-03-14 Jan Kratochvil <jan.kratochvil@redhat.com> * stack.c (return_command <retval_exp>): New variables retval_expr and old_chain. Inline parse_and_eval to initialize retval_expr. Check RETVAL_EXPR for UNOP_CAST and set RETURN_TYPE to the RETURN_VALUE type if RETURN_TYPE is NULL. gdb/doc/ 2009-03-14 Jan Kratochvil <jan.kratochvil@redhat.com> * gdb.texinfo (Returning): New description for missing debug info. gdb/testsuite/ 2009-03-14 Jan Kratochvil <jan.kratochvil@redhat.com> * gdb.base/return-nodebug.exp, gdb.base/return-nodebug.c: New. --- gdb/stack.c 6 Mar 2009 18:51:05 -0000 1.186 +++ gdb/stack.c 14 Mar 2009 21:34:47 -0000 @@ -1796,18 +1796,27 @@ return_command (char *retval_exp, int fr message. */ if (retval_exp) { + struct expression *retval_expr = parse_expression (retval_exp); + struct cleanup *old_chain = make_cleanup (xfree, retval_expr); struct type *return_type = NULL; /* Compute the return value. Should the computation fail, this call throws an error. */ - return_value = parse_and_eval (retval_exp); + return_value = evaluate_expression (retval_expr); /* Cast return value to the return type of the function. Should the cast fail, this call throws an error. */ if (thisfun != NULL) return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun)); if (return_type == NULL) - return_type = builtin_type (get_frame_arch (thisframe))->builtin_int; + { + if (retval_expr->elts[0].opcode != UNOP_CAST) + error (_("Return value type not available for selected " + "stack frame.\n" + "Please use an explicit cast of the value to return.")); + return_type = value_type (return_value); + } + do_cleanups (old_chain); CHECK_TYPEDEF (return_type); return_value = value_cast (return_type, return_value); --- gdb/doc/gdb.texinfo 14 Mar 2009 01:38:08 -0000 1.562 +++ gdb/doc/gdb.texinfo 14 Mar 2009 21:34:58 -0000 @@ -12494,6 +12494,53 @@ returned. In contrast, the @code{finish and Stepping, ,Continuing and Stepping}) resumes execution until the selected stack frame returns naturally. +@value{GDBN} needs to know how the @var{expression} argument should be set for +the inferior. The concrete registers assignment depends on the OS ABI and the +type being returned by the selected stack frame. For example it is common for +OS ABI to return floating point values in FPU registers while integer values in +CPU registers. Still some ABIs return even floating point values in CPU +registers. Larger integer widths (such as @code{long long int}) also have +specific placement rules. @value{GDBN} already knows the OS ABI from its +current target so it needs to find out also the type being returned to make the +assignment into the right register(s). + +Normally, the selected stack frame has debug info. @value{GDBN} will always +use the debug info instead of the implicit type of @var{expression} when the +debug info is available. For example, if you type @kbd{return -1}, and the +function in the current stack frame is declared to return a @code{long long +int}, @value{GDBN} transparently converts the implicit @code{int} value of -1 +into a @code{long long int}: + +@smallexample +Breakpoint 1, func () at gdb.base/return-nodebug.c:29 +29 return 31; +(@value{GDBP}) return -1 +Make func return now? (y or n) y +#0 0x004004f6 in main () at gdb.base/return-nodebug.c:43 +43 printf ("result=%lld\n", func ()); +(@value{GDBP}) +@end smallexample + +However, if the selected stack frame does not have a debug info, e.g., if the +function was compiled without debug info, @value{GDBN} has to find out the type +to return from user. Specifying a different type by mistake may set the value +in different inferior registers than the caller code expects. For example, +typing @kbd{return -1} with its implicit type @code{int} would set only a part +of a @code{long long int} result for a debug info less function (on 32-bit +architectures). Therefore the user is required to specify the return type by +an appropriate cast explicitly: + +@smallexample +Breakpoint 2, 0x0040050b in func () +(@value{GDBP}) return -1 +Return value type not available for selected stack frame. +Please use an explicit cast of the value to return. +(@value{GDBP}) return (long long int) -1 +Make selected stack frame return now? (y or n) y +#0 0x00400526 in main () +(@value{GDBP}) +@end smallexample + @node Calling @section Calling Program Functions --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.base/return-nodebug.c 14 Mar 2009 21:34:58 -0000 @@ -0,0 +1,49 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2009 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 TYPE +init (void) +{ + return 0; +} + +static TYPE +func (void) +{ + return 31; +} + +static void +marker (void) +{ +} + +int +main (void) +{ + /* Preinitialize registers to 0 to avoid false PASS by leftover garbage. */ + init (); + + printf ("result=" FORMAT "\n", CAST func ()); + + /* Cannot `next' with no debug info. */ + marker (); + + return 0; +} --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.base/return-nodebug.exp 14 Mar 2009 21:34:58 -0000 @@ -0,0 +1,61 @@ +# Copyright (C) 2009 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/>. + +proc do_test {type} { + set typenospace [string map {{ } -} $type] + + global pf_prefix + set old_prefix $pf_prefix + lappend pf_prefix "$typenospace:" + + if {[runto "func"]} { + # Verify that we do not crash when using "return" from a function with + # no debugging info. Such function has no `struct symbol'. It may + # still have an associated `struct minimal_symbol'. + + gdb_test "return -1" \ + "Return value type not available for selected stack frame\\.\r\nPlease use an explicit cast of the value to return\\." \ + "return from function with no debug info without a cast" + + # Cast of the result to the proper width must be done explicitely. + gdb_test "return ($type) -1" "#0 .* main \\(.*" \ + "return from function with no debug info with a cast" \ + "Make selected stack frame return now\\? \\(y or n\\) " "y" + + # And if it returned the full width of the result. + gdb_test "adv marker" "\r\nresult=-1\r\n.* in marker \\(.*" \ + "full width of the returned result" + } + + set pf_prefix $old_prefix +} + +foreach case {{{signed char} %d (int)} \ + {{short} %d (int)} \ + {{int} %d} \ + {{long} %ld} \ + {{long long} %lld}} { + set type [lindex $case 0] + set format [lindex $case 1] + set cast [lindex $case 2] + + set typeesc [string map {{ } {\ }} $type] + set typenospace [string map {{ } -} $type] + + if {[prepare_for_testing return-nodebug.exp "return-nodebug-$typenospace" "return-nodebug.c" \ + [list "additional_flags=-DFORMAT=\"$format\" -DTYPE=$typeesc -DCAST=$cast"]] == 0} { + do_test $type + } +} ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-03-14 22:09 ` Jan Kratochvil @ 2009-03-14 22:18 ` Eli Zaretskii 2009-03-15 9:22 ` Joel Brobecker 1 sibling, 0 replies; 38+ messages in thread From: Eli Zaretskii @ 2009-03-14 22:18 UTC (permalink / raw) To: Jan Kratochvil; +Cc: brobecker, tromey, mark.kettenis, drow, gdb-patches > Date: Sat, 14 Mar 2009 22:44:01 +0100 > From: Jan Kratochvil <jan.kratochvil@redhat.com> > Cc: Tom Tromey <tromey@redhat.com>, Mark Kettenis <mark.kettenis@xs4all.nl>, > drow@false.org, gdb-patches@sourceware.org > > On Sat, 14 Mar 2009 11:21:30 +0100, Eli Zaretskii wrote: > > Thanks, this part is approved, provided that you add the missing > > punctuation and clarify the text, as indicated below. > > Tried to address all your objections. Thanks, this version is fine. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-03-14 22:09 ` Jan Kratochvil 2009-03-14 22:18 ` Eli Zaretskii @ 2009-03-15 9:22 ` Joel Brobecker 2009-03-15 18:15 ` Jan Kratochvil 1 sibling, 1 reply; 38+ messages in thread From: Joel Brobecker @ 2009-03-15 9:22 UTC (permalink / raw) To: Jan Kratochvil Cc: Eli Zaretskii, Tom Tromey, Mark Kettenis, drow, gdb-patches > The statement `no debugging info' itself is too ambiguous. I had a > mess in it myself some years ago and I still find people do not > properly distinguish .symtab/.dynsym/.debug_info, which of these are > ELF vs. DWARF, gcc (none)/-s/-g/strip and how they are related to GDB > minimal_symbol/partial_symbol/symbol. No problem with your version. The reason why I wondered whether this was necessary or not is that I assumed that the testsuite scripts are going to be read mostly by GDB developers... -- Joel ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-03-15 9:22 ` Joel Brobecker @ 2009-03-15 18:15 ` Jan Kratochvil 2009-03-18 4:36 ` Pedro Alves 0 siblings, 1 reply; 38+ messages in thread From: Jan Kratochvil @ 2009-03-15 18:15 UTC (permalink / raw) To: Eli Zaretskii, Joel Brobecker; +Cc: tromey, mark.kettenis, drow, gdb-patches Hi, finally checked-in: http://sourceware.org/ml/gdb-cvs/2009-03/msg00093.html Thanks, Jan ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-03-15 18:15 ` Jan Kratochvil @ 2009-03-18 4:36 ` Pedro Alves 2009-03-18 14:44 ` Joel Brobecker 2009-03-18 15:39 ` Jan Kratochvil 0 siblings, 2 replies; 38+ messages in thread From: Pedro Alves @ 2009-03-18 4:36 UTC (permalink / raw) To: gdb-patches Cc: Jan Kratochvil, Eli Zaretskii, Joel Brobecker, tromey, mark.kettenis, drow Unfortunatelly, this test is failing against gdbserver: Running ../../../src/gdb/testsuite/gdb.base/return-nodebug.exp ... FAIL: gdb.base/return-nodebug.exp: signed-char: full width of the returned result FAIL: gdb.base/return-nodebug.exp: short: full width of the returned result FAIL: gdb.base/return-nodebug.exp: int: full width of the returned result FAIL: gdb.base/return-nodebug.exp: long: full width of the returned result FAIL: gdb.base/return-nodebug.exp: long-long: full width of the returned result The issue is that it relies on parsing the output of printf, which doesn't work against remote targets that don't implement some kind of semi-hosting io, like gdbserver. ( as a side, but related note, tests that need to rely on inferior output, should be guarded with "if [target_info exists gdb,noinferiorio]" ) What do you think we rewrite test to not rely on printf at all, like below? This passes for me on native x86_64-linux, and against x86_64-linux gdbserver. -- Pedro Alves 2009-03-18 Pedro Alves <pedro@codesourcery.com> * return-nodebug.c: Don't include stdio.h. (init): Delete. (func): Delete definition and provide extern declaration. (t): New. (main): Don't call printf. Call func and store its result in t. * return-nodebug1.c: New. * return-nodebug.exp: Don't expect stdio output. Instead, print the global variable t. Drop printf formatters and cast types from foreach loop. Don't use prepare_for_testing. Compile return-nodebug.c and return-nodebug1.c in separate steps. Don't define FORMAT or CAST. --- gdb/testsuite/gdb.base/return-nodebug.c | 22 ++------------- gdb/testsuite/gdb.base/return-nodebug.exp | 44 ++++++++++++++++++++---------- gdb/testsuite/gdb.base/return-nodebug1.c | 22 +++++++++++++++ 3 files changed, 56 insertions(+), 32 deletions(-) Index: src/gdb/testsuite/gdb.base/return-nodebug.c =================================================================== --- src.orig/gdb/testsuite/gdb.base/return-nodebug.c 2009-03-18 03:11:16.000000000 +0000 +++ src/gdb/testsuite/gdb.base/return-nodebug.c 2009-03-18 03:49:06.000000000 +0000 @@ -15,34 +15,20 @@ 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 TYPE -init (void) -{ - return 0; -} - -static TYPE -func (void) -{ - return 31; -} +extern TYPE func (void); static void marker (void) { } +TYPE t; + int main (void) { - /* Preinitialize registers to 0 to avoid false PASS by leftover garbage. */ - init (); - - printf ("result=" FORMAT "\n", CAST func ()); + t = func (); - /* Cannot `next' with no debug info. */ marker (); return 0; Index: src/gdb/testsuite/gdb.base/return-nodebug.exp =================================================================== --- src.orig/gdb/testsuite/gdb.base/return-nodebug.exp 2009-03-18 02:58:19.000000000 +0000 +++ src/gdb/testsuite/gdb.base/return-nodebug.exp 2009-03-18 03:52:58.000000000 +0000 @@ -34,28 +34,44 @@ proc do_test {type} { "return from function with no debug info with a cast" \ "Make selected stack frame return now\\? \\(y or n\\) " "y" + gdb_test "advance marker" "marker \\(.*" \ + "advance to marker" + # And if it returned the full width of the result. - gdb_test "adv marker" "\r\nresult=-1\r\n.* in marker \\(.*" \ - "full width of the returned result" + gdb_test "print /d t" " = -1" } set pf_prefix $old_prefix } -foreach case {{{signed char} %d (int)} \ - {{short} %d (int)} \ - {{int} %d} \ - {{long} %ld} \ - {{long long} %lld}} { - set type [lindex $case 0] - set format [lindex $case 1] - set cast [lindex $case 2] - +foreach type {{signed char} {short} {int} {long} {long long}} { set typeesc [string map {{ } {\ }} $type] set typenospace [string map {{ } -} $type] - if {[prepare_for_testing return-nodebug.exp "return-nodebug-$typenospace" "return-nodebug.c" \ - [list "additional_flags=-DFORMAT=\"$format\" -DTYPE=$typeesc -DCAST=$cast"]] == 0} { - do_test $type + set testfile "return-nodebug" + set srcfile ${testfile}.c + set srcfile1 ${testfile}1.c + set binfile ${objdir}/${subdir}/${testfile}-${typenospace} + + set additional_flags "additional_flags=-DTYPE=$typeesc" + + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}-${typenospace}0.o" object [list debug $additional_flags]] != "" } { + continue + } + + # This one is compiled without debug info. + if { [gdb_compile "${srcdir}/${subdir}/${srcfile1}" "${binfile}-${typenospace}1.o" object [list $additional_flags]] != "" } { + continue + } + + if { [gdb_compile "${binfile}0.o ${binfile}1.o" "${binfile}" executable {debug}] != "" } { + continue } + + gdb_exit + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + gdb_load ${binfile} + + do_test $type } Index: src/gdb/testsuite/gdb.base/return-nodebug1.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/gdb/testsuite/gdb.base/return-nodebug1.c 2009-03-18 03:12:13.000000000 +0000 @@ -0,0 +1,22 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2009 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/>. */ + +TYPE +func (void) +{ + return 31; +} ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-03-18 4:36 ` Pedro Alves @ 2009-03-18 14:44 ` Joel Brobecker 2009-03-18 15:39 ` Jan Kratochvil 1 sibling, 0 replies; 38+ messages in thread From: Joel Brobecker @ 2009-03-18 14:44 UTC (permalink / raw) To: Pedro Alves Cc: gdb-patches, Jan Kratochvil, Eli Zaretskii, tromey, mark.kettenis, drow > The issue is that it relies on parsing the output of printf, which > doesn't work against remote targets that don't implement some kind > of semi-hosting io, like gdbserver. Yeah - the worse part is that I saw the use of printf, frowned on it, but let it go because I didn't see a quick way of avoiding it. Lessons learned for me. > 2009-03-18 Pedro Alves <pedro@codesourcery.com> > > * return-nodebug.c: Don't include stdio.h. > (init): Delete. > (func): Delete definition and provide extern declaration. > (t): New. > (main): Don't call printf. Call func and store its result in t. > * return-nodebug1.c: New. > * return-nodebug.exp: Don't expect stdio output. Instead, print > the global variable t. Drop printf formatters and cast types from > foreach loop. Don't use prepare_for_testing. Compile > return-nodebug.c and return-nodebug1.c in separate steps. Don't > define FORMAT or CAST. Looks great to me. In the future, don't feel obliged to fix it yourself unless you want to. I can help fix my own messes... -- Joel ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-03-18 4:36 ` Pedro Alves 2009-03-18 14:44 ` Joel Brobecker @ 2009-03-18 15:39 ` Jan Kratochvil 2009-03-18 15:46 ` Pedro Alves 1 sibling, 1 reply; 38+ messages in thread From: Jan Kratochvil @ 2009-03-18 15:39 UTC (permalink / raw) To: Pedro Alves Cc: gdb-patches, Eli Zaretskii, Joel Brobecker, tromey, mark.kettenis, drow On Wed, 18 Mar 2009 05:20:37 +0100, Pedro Alves wrote: > Unfortunatelly, this test is failing against gdbserver: > > Running ../../../src/gdb/testsuite/gdb.base/return-nodebug.exp ... > FAIL: gdb.base/return-nodebug.exp: signed-char: full width of the returned result > FAIL: gdb.base/return-nodebug.exp: short: full width of the returned result > FAIL: gdb.base/return-nodebug.exp: int: full width of the returned result > FAIL: gdb.base/return-nodebug.exp: long: full width of the returned result > FAIL: gdb.base/return-nodebug.exp: long-long: full width of the returned result got now a link the gdbserver mode can be tested by: http://sourceware.org/gdb/wiki/Native_gdbserver_testing > ( as a side, but related note, tests that need to rely on inferior output, > should be guarded with "if [target_info exists gdb,noinferiorio]" ) Thanks for the info. > What do you think we rewrite test to not rely on printf at all, like below? Yes, the fix looks fine to me. Just fixed the gdb_compile lines as it did not compile on a clean sourcetree. Thanks, Jan 2009-03-18 Pedro Alves <pedro@codesourcery.com> * return-nodebug.c: Don't include stdio.h. (init): Delete. (func): Delete definition and provide extern declaration. (t): New. (main): Don't call printf. Call func and store its result in t. * return-nodebug1.c: New. * return-nodebug.exp: Don't expect stdio output. Instead, print the global variable t. Drop printf formatters and cast types from foreach loop. Don't use prepare_for_testing. Compile return-nodebug.c and return-nodebug1.c in separate steps. Don't define FORMAT or CAST. --- gdb/testsuite/gdb.base/return-nodebug.c 15 Mar 2009 09:19:40 -0000 1.1 +++ gdb/testsuite/gdb.base/return-nodebug.c 18 Mar 2009 15:05:00 -0000 @@ -15,34 +15,20 @@ 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 TYPE -init (void) -{ - return 0; -} - -static TYPE -func (void) -{ - return 31; -} +extern TYPE func (void); static void marker (void) { } +TYPE t; + int main (void) { - /* Preinitialize registers to 0 to avoid false PASS by leftover garbage. */ - init (); - - printf ("result=" FORMAT "\n", CAST func ()); + t = func (); - /* Cannot `next' with no debug info. */ marker (); return 0; --- gdb/testsuite/gdb.base/return-nodebug.exp 15 Mar 2009 09:19:40 -0000 1.1 +++ gdb/testsuite/gdb.base/return-nodebug.exp 18 Mar 2009 15:05:00 -0000 @@ -34,28 +34,44 @@ proc do_test {type} { "return from function with no debug info with a cast" \ "Make selected stack frame return now\\? \\(y or n\\) " "y" + gdb_test "advance marker" "marker \\(.*" \ + "advance to marker" + # And if it returned the full width of the result. - gdb_test "adv marker" "\r\nresult=-1\r\n.* in marker \\(.*" \ - "full width of the returned result" + gdb_test "print /d t" " = -1" } set pf_prefix $old_prefix } -foreach case {{{signed char} %d (int)} \ - {{short} %d (int)} \ - {{int} %d} \ - {{long} %ld} \ - {{long long} %lld}} { - set type [lindex $case 0] - set format [lindex $case 1] - set cast [lindex $case 2] - +foreach type {{signed char} {short} {int} {long} {long long}} { set typeesc [string map {{ } {\ }} $type] set typenospace [string map {{ } -} $type] - if {[prepare_for_testing return-nodebug.exp "return-nodebug-$typenospace" "return-nodebug.c" \ - [list "additional_flags=-DFORMAT=\"$format\" -DTYPE=$typeesc -DCAST=$cast"]] == 0} { - do_test $type + set testfile "return-nodebug" + set srcfile ${testfile}.c + set srcfile1 ${testfile}1.c + set binfile ${objdir}/${subdir}/${testfile}-${typenospace} + + set additional_flags "additional_flags=-DTYPE=$typeesc" + + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}0.o" object [list debug $additional_flags]] != "" } { + continue + } + + # This one is compiled without debug info. + if { [gdb_compile "${srcdir}/${subdir}/${srcfile1}" "${binfile}1.o" object [list $additional_flags]] != "" } { + continue + } + + if { [gdb_compile "${binfile}0.o ${binfile}1.o" "${binfile}" executable {debug}] != "" } { + continue } + + gdb_exit + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + gdb_load ${binfile} + + do_test $type } --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.base/return-nodebug1.c 18 Mar 2009 15:05:00 -0000 @@ -0,0 +1,22 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2009 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/>. */ + +TYPE +func (void) +{ + return 31; +} ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-03-18 15:39 ` Jan Kratochvil @ 2009-03-18 15:46 ` Pedro Alves 0 siblings, 0 replies; 38+ messages in thread From: Pedro Alves @ 2009-03-18 15:46 UTC (permalink / raw) To: gdb-patches; +Cc: Jan Kratochvil, Joel Brobecker On Wednesday 18 March 2009 13:54:48, Joel Brobecker wrote: > Looks great to me. Thanks. > In the future, don't feel obliged to fix it yourself unless you want to. > I can help fix my own messes... It's not a problem. In this case, I thought it would be faster for me to go ahead, since I knew exactly what had to be done. It only took me a few minutes. On Wednesday 18 March 2009 15:13:20, Jan Kratochvil wrote: > Yes, the fix looks fine to me. > > Just fixed the gdb_compile lines as it did not compile on a clean sourcetree. > Ah, -+ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}-${typenospace}0.o" object [list debug $additional_flags]] != "" } { ++ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}0.o" object [list debug $additional_flags]] != "" Ooops, early experimentation, then I moved -${typenospace} to ${binfile}, but the .o files were still around. Thanks. I brought back the "full width of the returned result" string that I removed by mistake. -gdb_test "print /d t" " = -1" +gdb_test "print /d t" " = -1" "full width of the returned result" Now checked in. -- Pedro Alves 2009-03-18 Pedro Alves <pedro@codesourcery.com> * return-nodebug.c: Don't include stdio.h. (init): Delete. (func): Delete definition and provide extern declaration. (t): New. (main): Don't call printf. Call func and store its result in t. * return-nodebug1.c: New. * return-nodebug.exp: Don't expect stdio output. Instead, print the global variable t. Drop printf formatters and cast types from foreach loop. Don't use prepare_for_testing. Compile return-nodebug.c and return-nodebug1.c in separate steps. Don't define FORMAT or CAST. --- gdb/testsuite/gdb.base/return-nodebug.c | 22 ++------------- gdb/testsuite/gdb.base/return-nodebug.exp | 44 ++++++++++++++++++++---------- gdb/testsuite/gdb.base/return-nodebug1.c | 22 +++++++++++++++ 3 files changed, 56 insertions(+), 32 deletions(-) Index: src/gdb/testsuite/gdb.base/return-nodebug.c =================================================================== --- src.orig/gdb/testsuite/gdb.base/return-nodebug.c 2009-03-18 15:20:12.000000000 +0000 +++ src/gdb/testsuite/gdb.base/return-nodebug.c 2009-03-18 15:21:35.000000000 +0000 @@ -15,34 +15,20 @@ 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 TYPE -init (void) -{ - return 0; -} - -static TYPE -func (void) -{ - return 31; -} +extern TYPE func (void); static void marker (void) { } +TYPE t; + int main (void) { - /* Preinitialize registers to 0 to avoid false PASS by leftover garbage. */ - init (); - - printf ("result=" FORMAT "\n", CAST func ()); + t = func (); - /* Cannot `next' with no debug info. */ marker (); return 0; Index: src/gdb/testsuite/gdb.base/return-nodebug.exp =================================================================== --- src.orig/gdb/testsuite/gdb.base/return-nodebug.exp 2009-03-18 15:20:12.000000000 +0000 +++ src/gdb/testsuite/gdb.base/return-nodebug.exp 2009-03-18 15:24:00.000000000 +0000 @@ -34,28 +34,44 @@ proc do_test {type} { "return from function with no debug info with a cast" \ "Make selected stack frame return now\\? \\(y or n\\) " "y" + gdb_test "advance marker" "marker \\(.*" \ + "advance to marker" + # And if it returned the full width of the result. - gdb_test "adv marker" "\r\nresult=-1\r\n.* in marker \\(.*" \ - "full width of the returned result" + gdb_test "print /d t" " = -1" "full width of the returned result" } set pf_prefix $old_prefix } -foreach case {{{signed char} %d (int)} \ - {{short} %d (int)} \ - {{int} %d} \ - {{long} %ld} \ - {{long long} %lld}} { - set type [lindex $case 0] - set format [lindex $case 1] - set cast [lindex $case 2] - +foreach type {{signed char} {short} {int} {long} {long long}} { set typeesc [string map {{ } {\ }} $type] set typenospace [string map {{ } -} $type] - if {[prepare_for_testing return-nodebug.exp "return-nodebug-$typenospace" "return-nodebug.c" \ - [list "additional_flags=-DFORMAT=\"$format\" -DTYPE=$typeesc -DCAST=$cast"]] == 0} { - do_test $type + set testfile "return-nodebug" + set srcfile ${testfile}.c + set srcfile1 ${testfile}1.c + set binfile ${objdir}/${subdir}/${testfile}-${typenospace} + + set additional_flags "additional_flags=-DTYPE=$typeesc" + + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}0.o" object [list debug $additional_flags]] != "" } { + continue + } + + # This one is compiled without debug info. + if { [gdb_compile "${srcdir}/${subdir}/${srcfile1}" "${binfile}1.o" object [list $additional_flags]] != "" } { + continue + } + + if { [gdb_compile "${binfile}0.o ${binfile}1.o" "${binfile}" executable {debug}] != "" } { + continue } + + gdb_exit + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + gdb_load ${binfile} + + do_test $type } Index: src/gdb/testsuite/gdb.base/return-nodebug1.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/gdb/testsuite/gdb.base/return-nodebug1.c 2009-03-18 15:21:35.000000000 +0000 @@ -0,0 +1,22 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2009 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/>. */ + +TYPE +func (void) +{ + return 31; +} ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-02-11 21:47 ` Jan Kratochvil 2009-02-11 21:58 ` Mark Kettenis @ 2009-02-11 22:44 ` Mark Kettenis 2009-02-12 9:41 ` Jan Kratochvil 2009-02-21 12:47 ` Jan Kratochvil 1 sibling, 2 replies; 38+ messages in thread From: Mark Kettenis @ 2009-02-11 22:44 UTC (permalink / raw) To: jan.kratochvil; +Cc: drow, gdb-patches > Date: Wed, 11 Feb 2009 22:46:47 +0100 > From: Jan Kratochvil <jan.kratochvil@redhat.com> > > > From: Daniel Jacobowitz <drow@false.org> > > > Everything we pick will be wrong some of the time, but IMO "long" is > > > maximally useful. "long long" on 32-bit platforms is going to pick > > > up garbage from the next register for int or void * returns. > > Garbage would be seen by caller of a `long long' returning callee where GDB > would return something smaller (like `int'). As GDB writes (not "reads") the > register it just will write zero to one excessive but unused register. This > register must be callee-saved (not caller-saved) by the ABI supporting `long > long' return type and GDB already asserts the return type is > RETURN_VALUE_REGISTER_CONVENTION. Thinking a bit more of this now, things all depend on the calling convention. I'm not convinced casting to `long long' is safe in all cases, especially on 32-bit big-endian machines. It really might do the wrong thing there, exposing garbage or the wrong 32 bits of the 64-bit value. The 'int' case is really special in a sense, very much because of the K&R heritage. It has to work for all types that are sizeof(int) or smaller. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-02-11 22:44 ` Mark Kettenis @ 2009-02-12 9:41 ` Jan Kratochvil 2009-02-12 14:36 ` Pierre Muller 2009-02-14 21:59 ` Mark Kettenis 2009-02-21 12:47 ` Jan Kratochvil 1 sibling, 2 replies; 38+ messages in thread From: Jan Kratochvil @ 2009-02-12 9:41 UTC (permalink / raw) To: Mark Kettenis; +Cc: drow, gdb-patches On Wed, 11 Feb 2009 23:44:21 +0100, Mark Kettenis wrote: > Thinking a bit more of this now, things all depend on the calling > convention. I'm not convinced casting to `long long' is safe in all > cases, especially on 32-bit big-endian machines. It really might do > the wrong thing there, exposing garbage or the wrong 32 bits of the > 64-bit value. > > The 'int' case is really special in a sense, very much because of the > K&R heritage. It has to work for all types that are sizeof(int) or > smaller. OK to check-in this patch? Regression-tested on x86_64-unknown-linux-gnu. Thanks, Jan gdb/ 2009-02-12 Mark Kettenis <kettenis@gnu.org> * stack.c (return_command): Returned type for functions with no debug info is now the type of user specified expression. gdb/testsuite/ 2009-02-12 Jan Kratochvil <jan.kratochvil@redhat.com> * gdb.base/return-nodebug.exp, gdb.base/return-nodebug.c: New. --- gdb/stack.c 11 Feb 2009 16:07:28 -0000 1.185 +++ gdb/stack.c 12 Feb 2009 09:24:18 -0000 @@ -1806,6 +1806,8 @@ return_command (char *retval_exp, int fr the cast fail, this call throws an error. */ if (thisfun != NULL) return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun)); + else + return_type = value_type (return_value); if (return_type == NULL) return_type = builtin_type (get_frame_arch (thisframe))->builtin_int; CHECK_TYPEDEF (return_type); --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.base/return-nodebug.c 12 Feb 2009 09:24:18 -0000 @@ -0,0 +1,40 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2009 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 TYPE +func (void) +{ + return (TYPE) -1; +} + +static void +marker (void) +{ +} + +int +main (void) +{ + printf ("result=" FORMAT "\n", CAST func ()); + + /* Cannot `next' with no debug info. */ + marker (); + + return 0; +} --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.base/return-nodebug.exp 12 Feb 2009 09:24:18 -0000 @@ -0,0 +1,55 @@ +# Copyright (C) 2009 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/>. + +proc do_test {type} { + set typenospace [string map {{ } -} $type] + + global pf_prefix + set old_prefix $pf_prefix + lappend pf_prefix "$typenospace:" + + if {[runto "func"]} { + # Test return from a function with no debug info (symbol; still it may + # have a minimal-symbol) if it does not crash. + # Cast of the result to the proper width must be done explicitely. + gdb_test "return ($type) -1" "#0 .* main \\(.*" \ + "return from function with no debug info" \ + "Make selected stack frame return now\\? \\(y or n\\) " "y" + + # And if it returned the full width of the result. + gdb_test "adv marker" "\r\nresult=-1\r\n.* in marker \\(.*" \ + "full width of the returned result" + } + + set pf_prefix $old_prefix +} + +foreach case {{{char} %d (int)} \ + {{short} %d (int)} \ + {{int} %d} \ + {{long} %ld} \ + {{long long} %lld}} { + set type [lindex $case 0] + set format [lindex $case 1] + set cast [lindex $case 2] + + set typeesc [string map {{ } {\ }} $type] + set typenospace [string map {{ } -} $type] + + if {[prepare_for_testing return-nodebug.exp "return-nodebug-$typenospace" "return-nodebug.c" \ + [list "additional_flags=-DFORMAT=\"$format\" -DTYPE=$typeesc -DCAST=$cast"]] == 0} { + do_test $type + } +} ^ permalink raw reply [flat|nested] 38+ messages in thread
* RE: [patch] Fix `return' of long/long-long results with no debuginfo 2009-02-12 9:41 ` Jan Kratochvil @ 2009-02-12 14:36 ` Pierre Muller 2009-02-12 14:44 ` Jan Kratochvil 2009-02-14 21:59 ` Mark Kettenis 1 sibling, 1 reply; 38+ messages in thread From: Pierre Muller @ 2009-02-12 14:36 UTC (permalink / raw) To: 'Jan Kratochvil', 'Mark Kettenis'; +Cc: drow, gdb-patches Concerning the test, wouldn't it be better to set the return value to another value than the one that is normally returned by the function? This would allow to FAIL on targets where the substitution fails and the program is just continued... Just use some other value in func definition, for instance +static TYPE +func (void)+{ + return (TYPE) 31; +} I checked your patch, because I was worried about the weird syntax and thought that this would fail on my old cygwin dejagnu, but it does give me 10 PASS, even with the above modification. Pierre Muller Pascal language support maintainer for GDB > -----Message d'origine----- > De : gdb-patches-owner@sourceware.org [mailto:gdb-patches- > owner@sourceware.org] De la part de Jan Kratochvil > Envoyé : Thursday, February 12, 2009 10:42 AM > À : Mark Kettenis > Cc : drow@false.org; gdb-patches@sourceware.org > Objet : Re: [patch] Fix `return' of long/long-long results with no > debuginfo > > On Wed, 11 Feb 2009 23:44:21 +0100, Mark Kettenis wrote: > > Thinking a bit more of this now, things all depend on the calling > > convention. I'm not convinced casting to `long long' is safe in all > > cases, especially on 32-bit big-endian machines. It really might do > > the wrong thing there, exposing garbage or the wrong 32 bits of the > > 64-bit value. > > > > The 'int' case is really special in a sense, very much because of the > > K&R heritage. It has to work for all types that are sizeof(int) or > > smaller. > > OK to check-in this patch? > > Regression-tested on x86_64-unknown-linux-gnu. > > > Thanks, > Jan > > > gdb/ > 2009-02-12 Mark Kettenis <kettenis@gnu.org> > > * stack.c (return_command): Returned type for functions with no > debug > info is now the type of user specified expression. > > gdb/testsuite/ > 2009-02-12 Jan Kratochvil <jan.kratochvil@redhat.com> > > * gdb.base/return-nodebug.exp, gdb.base/return-nodebug.c: New. > > --- gdb/stack.c 11 Feb 2009 16:07:28 -0000 1.185 > +++ gdb/stack.c 12 Feb 2009 09:24:18 -0000 > @@ -1806,6 +1806,8 @@ return_command (char *retval_exp, int fr > the cast fail, this call throws an error. */ > if (thisfun != NULL) > return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun)); > + else > + return_type = value_type (return_value); > if (return_type == NULL) > return_type = builtin_type (get_frame_arch (thisframe))- > >builtin_int; > CHECK_TYPEDEF (return_type); > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ gdb/testsuite/gdb.base/return-nodebug.c 12 Feb 2009 09:24:18 - > 0000 > @@ -0,0 +1,40 @@ > +/* This testcase is part of GDB, the GNU debugger. > + > + Copyright 2009 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 TYPE > +func (void) > +{ > + return (TYPE) -1; > +} > + > +static void > +marker (void) > +{ > +} > + > +int > +main (void) > +{ > + printf ("result=" FORMAT "\n", CAST func ()); > + > + /* Cannot `next' with no debug info. */ > + marker (); > + > + return 0; > +} > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ gdb/testsuite/gdb.base/return-nodebug.exp 12 Feb 2009 09:24:18 - > 0000 > @@ -0,0 +1,55 @@ > +# Copyright (C) 2009 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/>. > + > +proc do_test {type} { > + set typenospace [string map {{ } -} $type] > + > + global pf_prefix > + set old_prefix $pf_prefix > + lappend pf_prefix "$typenospace:" > + > + if {[runto "func"]} { > + # Test return from a function with no debug info (symbol; still > it may > + # have a minimal-symbol) if it does not crash. > + # Cast of the result to the proper width must be done > explicitely. > + gdb_test "return ($type) -1" "#0 .* main \\(.*" \ > + "return from function with no debug info" \ > + "Make selected stack frame return now\\? \\(y or n\\) " > "y" > + > + # And if it returned the full width of the result. > + gdb_test "adv marker" "\r\nresult=-1\r\n.* in marker \\(.*" \ > + "full width of the returned result" > + } > + > + set pf_prefix $old_prefix > +} > + > +foreach case {{{char} %d (int)} \ > + {{short} %d (int)} \ > + {{int} %d} \ > + {{long} %ld} \ > + {{long long} %lld}} { > + set type [lindex $case 0] > + set format [lindex $case 1] > + set cast [lindex $case 2] > + > + set typeesc [string map {{ } {\ }} $type] > + set typenospace [string map {{ } -} $type] > + > + if {[prepare_for_testing return-nodebug.exp "return-nodebug- > $typenospace" "return-nodebug.c" \ > + [list "additional_flags=-DFORMAT=\"$format\" -DTYPE=$typeesc - > DCAST=$cast"]] == 0} { > + do_test $type > + } > +} ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-02-12 14:36 ` Pierre Muller @ 2009-02-12 14:44 ` Jan Kratochvil 0 siblings, 0 replies; 38+ messages in thread From: Jan Kratochvil @ 2009-02-12 14:44 UTC (permalink / raw) To: Pierre Muller; +Cc: 'Mark Kettenis', drow, gdb-patches On Thu, 12 Feb 2009 15:35:58 +0100, Pierre Muller wrote: > Just use some other value in func definition, > for instance > +static TYPE > +func (void)+{ > + return (TYPE) 31; > +} I fully agree, it was my mistake. Thanks, Jan gdb/ 2009-02-12 Mark Kettenis <kettenis@gnu.org> * stack.c (return_command): Returned type for functions with no debug info is now the type of user specified expression. gdb/testsuite/ 2009-02-12 Jan Kratochvil <jan.kratochvil@redhat.com> * gdb.base/return-nodebug.exp, gdb.base/return-nodebug.c: New. --- gdb/stack.c 11 Feb 2009 16:07:28 -0000 1.185 +++ gdb/stack.c 12 Feb 2009 09:24:18 -0000 @@ -1806,6 +1806,8 @@ return_command (char *retval_exp, int fr the cast fail, this call throws an error. */ if (thisfun != NULL) return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun)); + else + return_type = value_type (return_value); if (return_type == NULL) return_type = builtin_type (get_frame_arch (thisframe))->builtin_int; CHECK_TYPEDEF (return_type); --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.base/return-nodebug.c 12 Feb 2009 09:24:18 -0000 @@ -0,0 +1,40 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2009 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 TYPE +func (void) +{ + return 31; +} + +static void +marker (void) +{ +} + +int +main (void) +{ + printf ("result=" FORMAT "\n", CAST func ()); + + /* Cannot `next' with no debug info. */ + marker (); + + return 0; +} --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.base/return-nodebug.exp 12 Feb 2009 09:24:18 -0000 @@ -0,0 +1,55 @@ +# Copyright (C) 2009 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/>. + +proc do_test {type} { + set typenospace [string map {{ } -} $type] + + global pf_prefix + set old_prefix $pf_prefix + lappend pf_prefix "$typenospace:" + + if {[runto "func"]} { + # Test return from a function with no debug info (symbol; still it may + # have a minimal-symbol) if it does not crash. + # Cast of the result to the proper width must be done explicitely. + gdb_test "return ($type) -1" "#0 .* main \\(.*" \ + "return from function with no debug info" \ + "Make selected stack frame return now\\? \\(y or n\\) " "y" + + # And if it returned the full width of the result. + gdb_test "adv marker" "\r\nresult=-1\r\n.* in marker \\(.*" \ + "full width of the returned result" + } + + set pf_prefix $old_prefix +} + +foreach case {{{char} %d (int)} \ + {{short} %d (int)} \ + {{int} %d} \ + {{long} %ld} \ + {{long long} %lld}} { + set type [lindex $case 0] + set format [lindex $case 1] + set cast [lindex $case 2] + + set typeesc [string map {{ } {\ }} $type] + set typenospace [string map {{ } -} $type] + + if {[prepare_for_testing return-nodebug.exp "return-nodebug-$typenospace" "return-nodebug.c" \ + [list "additional_flags=-DFORMAT=\"$format\" -DTYPE=$typeesc -DCAST=$cast"]] == 0} { + do_test $type + } +} ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-02-12 9:41 ` Jan Kratochvil 2009-02-12 14:36 ` Pierre Muller @ 2009-02-14 21:59 ` Mark Kettenis 1 sibling, 0 replies; 38+ messages in thread From: Mark Kettenis @ 2009-02-14 21:59 UTC (permalink / raw) To: jan.kratochvil; +Cc: drow, gdb-patches > Date: Thu, 12 Feb 2009 10:41:34 +0100 > From: Jan Kratochvil <jan.kratochvil@redhat.com> > > On Wed, 11 Feb 2009 23:44:21 +0100, Mark Kettenis wrote: > > Thinking a bit more of this now, things all depend on the calling > > convention. I'm not convinced casting to `long long' is safe in all > > cases, especially on 32-bit big-endian machines. It really might do > > the wrong thing there, exposing garbage or the wrong 32 bits of the > > 64-bit value. > > > > The 'int' case is really special in a sense, very much because of the > > K&R heritage. It has to work for all types that are sizeof(int) or > > smaller. > > OK to check-in this patch? > > 2009-02-12 Mark Kettenis <kettenis@gnu.org> > > * stack.c (return_command): Returned type for functions with no debug > info is now the type of user specified expression. Looks good to me, but please put your own name on the ChangeLog entry. I just suggested the idea, but I was too lazy to actually write the code ;). ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-02-11 22:44 ` Mark Kettenis 2009-02-12 9:41 ` Jan Kratochvil @ 2009-02-21 12:47 ` Jan Kratochvil 2009-02-21 13:44 ` Mark Kettenis 1 sibling, 1 reply; 38+ messages in thread From: Jan Kratochvil @ 2009-02-21 12:47 UTC (permalink / raw) To: Mark Kettenis; +Cc: drow, gdb-patches On Wed, 11 Feb 2009 23:44:21 +0100, Mark Kettenis wrote: > Thinking a bit more of this now, things all depend on the calling > convention. I'm not convinced casting to `long long' is safe in all > cases, especially on 32-bit big-endian machines. It really might do > the wrong thing there, exposing garbage or the wrong 32 bits of the > 64-bit value. OK to check-in this patch? This patch could have a regression on ABI which defines caller saved vs. callee saved registers depending on the return type of the function. I do not believe there exists such ABI. Regression-tested on GNU/Linux on: HEAD{x86_64}, 6.8{x86_64(+inf. i386), i386, s390x(+inf. s390), ia64} Thanks, Jan gdb/ 2009-02-20 Jan Kratochvil <jan.kratochvil@redhat.com> * stack.c (return_extended_value_cast, return_extended_value): New. (return_command): Returned type for functions with no debug info has now at least the width of the type of user specified expression while it tries to use the largest compatible width. gdb/testsuite/ 2009-02-20 Jan Kratochvil <jan.kratochvil@redhat.com> * gdb.base/return-nodebug.exp, gdb.base/return-nodebug.S: New. --- gdb/stack.c 11 Feb 2009 16:07:28 -0000 1.185 +++ gdb/stack.c 20 Feb 2009 21:47:34 -0000 @@ -1777,7 +1777,75 @@ down_command (char *count_exp, int from_ down_silently_base (count_exp); print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC); } -\f + +/* Verify whether if RETURN_VALUE width gets extended to EXT_TYPE it will still + be the same value after reading it back using the RETURN_VALUE type. */ + +static int +return_extended_value_cast (struct value *return_value, struct type *ext_type) +{ + struct regcache *current_regcache = get_current_regcache (); + struct gdbarch *gdbarch = get_regcache_arch (current_regcache); + struct type *return_type = value_type (return_value); + struct value *ext_value, *compare_value; + + if (gdbarch_return_value (gdbarch, NULL, ext_type, NULL, NULL, NULL) + != RETURN_VALUE_REGISTER_CONVENTION) + return 0; + + ext_value = value_cast (ext_type, return_value); + gdbarch_return_value (gdbarch, NULL, ext_type, + current_regcache, NULL /*read*/, + value_contents (ext_value) /*write*/); + + compare_value = allocate_value (return_type); + gdbarch_return_value (gdbarch, NULL, return_type, current_regcache, + value_contents_raw (compare_value) /*read*/, + NULL /*write*/); + + return value_equal (return_value, compare_value); +} + +/* Set RETURN_VALUE extended to the largest type width which will still be the + same value after reading it back using the RETURN_VALUE type. */ + +static void +return_extended_value (struct value *return_value) +{ + struct type *return_type = value_type (return_value); + struct regcache *current_regcache = get_current_regcache (); + struct gdbarch *gdbarch = get_regcache_arch (current_regcache); + const struct builtin_type *builtins = builtin_type (gdbarch); + struct type **extp, *ext_tab[] = + { + builtins->builtin_long_long, + builtins->builtin_long, + return_type + }; + unsigned width_tried = 0; + + for (extp = ext_tab; extp < ext_tab + ARRAY_SIZE (ext_tab); extp++) + { + struct type *ext_type = *extp; + + /* Do not retry extension to the integer of an already tried width. */ + if (ext_type != return_type && width_tried == TYPE_LENGTH (ext_type)) + continue; + + /* Do not extend to non-original smaller (or the same size) type. */ + if (ext_type != return_type + && TYPE_LENGTH (ext_type) <= TYPE_LENGTH (return_type)) + continue; + + gdb_assert (TYPE_LENGTH (return_type) <= TYPE_LENGTH (ext_type)); + width_tried = TYPE_LENGTH (ext_type); + if (return_extended_value_cast (return_value, ext_type)) + break; + } + + /* Ensure at least the attempt with original RETURN_TYPE was successful. */ + gdb_assert (extp < ext_tab + ARRAY_SIZE (ext_tab)); +} void return_command (char *retval_exp, int from_tty) @@ -1806,6 +1874,8 @@ return_command (char *retval_exp, int fr the cast fail, this call throws an error. */ if (thisfun != NULL) return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun)); + else + return_type = value_type (return_value); if (return_type == NULL) return_type = builtin_type (get_frame_arch (thisframe))->builtin_int; CHECK_TYPEDEF (return_type); @@ -1862,9 +1932,13 @@ If you continue, the return value that y gdb_assert (gdbarch_return_value (gdbarch, func_type, return_type, NULL, NULL, NULL) == RETURN_VALUE_REGISTER_CONVENTION); - gdbarch_return_value (gdbarch, func_type, return_type, - get_current_regcache (), NULL /*read*/, - value_contents (return_value) /*write*/); + + if (thisfun != NULL) + gdbarch_return_value (gdbarch, func_type, return_type, + get_current_regcache (), NULL /*read*/, + value_contents (return_value) /*write*/); + else + return_extended_value (return_value); } /* If we are at the end of a call dummy now, pop the dummy frame --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.base/return-nodebug.c 20 Feb 2009 21:47:34 -0000 @@ -0,0 +1,49 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2009 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 TYPE +init (void) +{ + return 0; +} + +static TYPE +func (void) +{ + return 31; +} + +static void +marker (void) +{ +} + +int +main (void) +{ + /* Preinitialize registers to 0 to avoid false PASS by leftover garbage. */ + init (); + + printf ("result=" FORMAT "\n", CAST func ()); + + /* Cannot `next' with no debug info. */ + marker (); + + return 0; +} --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.base/return-nodebug.exp 20 Feb 2009 21:47:34 -0000 @@ -0,0 +1,54 @@ +# Copyright (C) 2009 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/>. + +proc do_test {type} { + set typenospace [string map {{ } -} $type] + + global pf_prefix + set old_prefix $pf_prefix + lappend pf_prefix "$typenospace:" + + if {[runto "func"]} { + # Test return from a function with no debug info (symbol; still it may + # have a minimal-symbol) if it does not crash. + gdb_test "return -1" "#0 .* main \\(.*" \ + "return from function with no debug info" \ + "Make selected stack frame return now\\? \\(y or n\\) " "y" + + # And if it returned the full width of the result. + gdb_test "adv marker" "\r\nresult=-1\r\n.* in marker \\(.*" \ + "full width of the returned result" + } + + set pf_prefix $old_prefix +} + +foreach case {{{signed char} %d (int)} \ + {{short} %d (int)} \ + {{int} %d} \ + {{long} %ld} \ + {{long long} %lld}} { + set type [lindex $case 0] + set format [lindex $case 1] + set cast [lindex $case 2] + + set typeesc [string map {{ } {\ }} $type] + set typenospace [string map {{ } -} $type] + + if {[prepare_for_testing return-nodebug.exp "return-nodebug-$typenospace" "return-nodebug.c" \ + [list "additional_flags=-DFORMAT=\"$format\" -DTYPE=$typeesc -DCAST=$cast"]] == 0} { + do_test $type + } +} ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-02-21 12:47 ` Jan Kratochvil @ 2009-02-21 13:44 ` Mark Kettenis 0 siblings, 0 replies; 38+ messages in thread From: Mark Kettenis @ 2009-02-21 13:44 UTC (permalink / raw) To: jan.kratochvil; +Cc: drow, gdb-patches > Date: Sat, 21 Feb 2009 01:04:09 +0100 > From: Jan Kratochvil <jan.kratochvil@redhat.com> > > On Wed, 11 Feb 2009 23:44:21 +0100, Mark Kettenis wrote: > > Thinking a bit more of this now, things all depend on the calling > > convention. I'm not convinced casting to `long long' is safe in all > > cases, especially on 32-bit big-endian machines. It really might do > > the wrong thing there, exposing garbage or the wrong 32 bits of the > > 64-bit value. > > OK to check-in this patch? Hell no! What is all that extra code about? > gdb/ > 2009-02-20 Jan Kratochvil <jan.kratochvil@redhat.com> > > * stack.c (return_extended_value_cast, return_extended_value): New. > (return_command): Returned type for functions with no debug info has > now at least the width of the type of user specified expression while > it tries to use the largest compatible width. > > gdb/testsuite/ > 2009-02-20 Jan Kratochvil <jan.kratochvil@redhat.com> > > * gdb.base/return-nodebug.exp, gdb.base/return-nodebug.S: New. > > --- gdb/stack.c 11 Feb 2009 16:07:28 -0000 1.185 > +++ gdb/stack.c 20 Feb 2009 21:47:34 -0000 > @@ -1777,7 +1777,75 @@ down_command (char *count_exp, int from_ > down_silently_base (count_exp); > print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC); > } > -\f > + > +/* Verify whether if RETURN_VALUE width gets extended to EXT_TYPE it will still > + be the same value after reading it back using the RETURN_VALUE type. */ > + > +static int > +return_extended_value_cast (struct value *return_value, struct type *ext_type) > +{ > + struct regcache *current_regcache = get_current_regcache (); > + struct gdbarch *gdbarch = get_regcache_arch (current_regcache); > + struct type *return_type = value_type (return_value); > + struct value *ext_value, *compare_value; > + > + if (gdbarch_return_value (gdbarch, NULL, ext_type, NULL, NULL, NULL) > + != RETURN_VALUE_REGISTER_CONVENTION) > + return 0; > + > + ext_value = value_cast (ext_type, return_value); > + gdbarch_return_value (gdbarch, NULL, ext_type, > + current_regcache, NULL /*read*/, > + value_contents (ext_value) /*write*/); > + > + compare_value = allocate_value (return_type); > + gdbarch_return_value (gdbarch, NULL, return_type, current_regcache, > + value_contents_raw (compare_value) /*read*/, > + NULL /*write*/); > + > + return value_equal (return_value, compare_value); > +} > + > +/* Set RETURN_VALUE extended to the largest type width which will still be the > + same value after reading it back using the RETURN_VALUE type. */ > + > +static void > +return_extended_value (struct value *return_value) > +{ > + struct type *return_type = value_type (return_value); > + struct regcache *current_regcache = get_current_regcache (); > + struct gdbarch *gdbarch = get_regcache_arch (current_regcache); > + const struct builtin_type *builtins = builtin_type (gdbarch); > + struct type **extp, *ext_tab[] = > + { > + builtins->builtin_long_long, > + builtins->builtin_long, > + return_type > + }; > + unsigned width_tried = 0; > + > + for (extp = ext_tab; extp < ext_tab + ARRAY_SIZE (ext_tab); extp++) > + { > + struct type *ext_type = *extp; > + > + /* Do not retry extension to the integer of an already tried width. */ > + if (ext_type != return_type && width_tried == TYPE_LENGTH (ext_type)) > + continue; > + > + /* Do not extend to non-original smaller (or the same size) type. */ > + if (ext_type != return_type > + && TYPE_LENGTH (ext_type) <= TYPE_LENGTH (return_type)) > + continue; > + > + gdb_assert (TYPE_LENGTH (return_type) <= TYPE_LENGTH (ext_type)); > + width_tried = TYPE_LENGTH (ext_type); > + if (return_extended_value_cast (return_value, ext_type)) > + break; > + } > + > + /* Ensure at least the attempt with original RETURN_TYPE was successful. */ > + gdb_assert (extp < ext_tab + ARRAY_SIZE (ext_tab)); > +} > > void > return_command (char *retval_exp, int from_tty) > @@ -1806,6 +1874,8 @@ return_command (char *retval_exp, int fr > the cast fail, this call throws an error. */ > if (thisfun != NULL) > return_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (thisfun)); > + else > + return_type = value_type (return_value); > if (return_type == NULL) > return_type = builtin_type (get_frame_arch (thisframe))->builtin_int; > CHECK_TYPEDEF (return_type); > @@ -1862,9 +1932,13 @@ If you continue, the return value that y > gdb_assert (gdbarch_return_value (gdbarch, func_type, return_type, NULL, > NULL, NULL) > == RETURN_VALUE_REGISTER_CONVENTION); > - gdbarch_return_value (gdbarch, func_type, return_type, > - get_current_regcache (), NULL /*read*/, > - value_contents (return_value) /*write*/); > + > + if (thisfun != NULL) > + gdbarch_return_value (gdbarch, func_type, return_type, > + get_current_regcache (), NULL /*read*/, > + value_contents (return_value) /*write*/); > + else > + return_extended_value (return_value); > } > > /* If we are at the end of a call dummy now, pop the dummy frame > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ gdb/testsuite/gdb.base/return-nodebug.c 20 Feb 2009 21:47:34 -0000 > @@ -0,0 +1,49 @@ > +/* This testcase is part of GDB, the GNU debugger. > + > + Copyright 2009 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 TYPE > +init (void) > +{ > + return 0; > +} > + > +static TYPE > +func (void) > +{ > + return 31; > +} > + > +static void > +marker (void) > +{ > +} > + > +int > +main (void) > +{ > + /* Preinitialize registers to 0 to avoid false PASS by leftover garbage. */ > + init (); > + > + printf ("result=" FORMAT "\n", CAST func ()); > + > + /* Cannot `next' with no debug info. */ > + marker (); > + > + return 0; > +} > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ gdb/testsuite/gdb.base/return-nodebug.exp 20 Feb 2009 21:47:34 -0000 > @@ -0,0 +1,54 @@ > +# Copyright (C) 2009 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/>. > + > +proc do_test {type} { > + set typenospace [string map {{ } -} $type] > + > + global pf_prefix > + set old_prefix $pf_prefix > + lappend pf_prefix "$typenospace:" > + > + if {[runto "func"]} { > + # Test return from a function with no debug info (symbol; still it may > + # have a minimal-symbol) if it does not crash. > + gdb_test "return -1" "#0 .* main \\(.*" \ > + "return from function with no debug info" \ > + "Make selected stack frame return now\\? \\(y or n\\) " "y" > + > + # And if it returned the full width of the result. > + gdb_test "adv marker" "\r\nresult=-1\r\n.* in marker \\(.*" \ > + "full width of the returned result" > + } > + > + set pf_prefix $old_prefix > +} > + > +foreach case {{{signed char} %d (int)} \ > + {{short} %d (int)} \ > + {{int} %d} \ > + {{long} %ld} \ > + {{long long} %lld}} { > + set type [lindex $case 0] > + set format [lindex $case 1] > + set cast [lindex $case 2] > + > + set typeesc [string map {{ } {\ }} $type] > + set typenospace [string map {{ } -} $type] > + > + if {[prepare_for_testing return-nodebug.exp "return-nodebug-$typenospace" "return-nodebug.c" \ > + [list "additional_flags=-DFORMAT=\"$format\" -DTYPE=$typeesc -DCAST=$cast"]] == 0} { > + do_test $type > + } > +} > ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-02-11 20:40 ` Mark Kettenis 2009-02-11 20:50 ` Daniel Jacobowitz @ 2009-02-21 15:58 ` Jan Kratochvil 2009-02-21 16:21 ` Mark Kettenis 1 sibling, 1 reply; 38+ messages in thread From: Jan Kratochvil @ 2009-02-21 15:58 UTC (permalink / raw) To: Mark Kettenis; +Cc: drow, gdb-patches On Wed, 11 Feb 2009 22:22:41 +0100, Mark Kettenis wrote: > would it be an idea to use the type of the return value expression given by > the user instead of int as a fallback? > > In the case at hand, "return -1" will still fail, but it would be > possible to do return (void *)-1 to do what the user wanted. It has been proven by the original bugreport even experienced programmers will make a mistake forgetting about the type cast. Therefore GDB "will not work" from the user POV in the most common programming usecase of the `(gdb) return' command: * x86_64 as the current+future primary development architecture. * `void *' (pointer) as the most common return type in modern code. * `(gdb) return 0' to simulate a failed function (`0' because `return NULL' may produce: No symbol "NULL" in current context.) Screenshot of the problem reproducer is at the bottom of this mail. While I do not have such machine at hand (could try UAE - m68k - for caller expecting `long long') I agree with your argument to my former unconditionally `long long'-casting patch: On Wed, 11 Feb 2009 23:44:21 +0100, Mark Kettenis wrote: > I'm not convinced casting to `long long' is safe in all cases, especially on > 32-bit big-endian machines. It really might do the wrong thing there, > exposing garbage or the wrong 32 bits of the 64-bit value. To find a way out of the both requirements this patch implements: > On Sat, 21 Feb 2009 01:04:09 +0100, Jan Kratochvil wrote: > > +/* Set RETURN_VALUE extended to the largest type width which will still be the > > + same value after reading it back using the RETURN_VALUE type. */ So this patch tries as best as it can the original intention of a widest cast but still it verifies it has not broken the compatibility with the type specified by user. Specified either intentionally or unintentionally. It has no regressions. The only imperfection I find is on the big endian 32bit arches one has to use an explicitely cast for callers expecting `long long'. But it cannot be guessed better and big endian arches are minority. Thanks for the review, Jan Reproducer for http://sourceware.org/ml/gdb-patches/2009-02/msg00260.html w/the patch at http://sourceware.org/ml/gdb-patches/2009-02/msg00280.html: cat >/tmp/return.c <<EOH #include <stdio.h> #include <stdint.h> static void * init (void) { return (void *) (intptr_t) -1; } static void * func (void) { return (void *) 0xdeadf00d00c0ffee; } int main (void) { init (); printf ("%p\n", func ()); return 0; } EOH gcc -o /tmp/return /tmp/return.c -Wall # no -g ./gdb -nx /tmp/return GNU gdb (GDB) 6.8.50.20090220-cvs Copyright (C) 2009 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-unknown-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... (no debugging symbols found) (gdb) break func Breakpoint 1 at 0x4004dd (gdb) run Starting program: /tmp/return Breakpoint 1, 0x00000000004004dd in func () (gdb) return 0 Make selected stack frame return now? (y or n) y #0 0x00000000004004f7 in main () (gdb) continue Continuing. 0xffffffff00000000 ^^^^^^^^^^^^^^^^^^ -> expected: (nil) Program exited normally. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-02-21 15:58 ` Jan Kratochvil @ 2009-02-21 16:21 ` Mark Kettenis 2009-02-21 16:32 ` Jan Kratochvil 0 siblings, 1 reply; 38+ messages in thread From: Mark Kettenis @ 2009-02-21 16:21 UTC (permalink / raw) To: jan.kratochvil; +Cc: drow, gdb-patches > Date: Sat, 21 Feb 2009 13:47:24 +0100 > From: Jan Kratochvil <jan.kratochvil@redhat.com> > > On Wed, 11 Feb 2009 22:22:41 +0100, Mark Kettenis wrote: > > would it be an idea to use the type of the return value expression given by > > the user instead of int as a fallback? > > > > In the case at hand, "return -1" will still fail, but it would be > > possible to do return (void *)-1 to do what the user wanted. > > It has been proven by the original bugreport even experienced > programmers will make a mistake forgetting about the type cast. And I' say it again. You're doing such users a far bigger favour by distributing libraries with debug information. than with bloating gdb with code to work around issues. > Therefore GDB "will not work" from the user POV in the most common > programming usecase of the `(gdb) return' command: > * x86_64 as the current+future primary development architecture. > * `void *' (pointer) as the most common return type in modern code. You're pulling that one out of your arse for sure. > * `(gdb) return 0' to simulate a failed function > (`0' because `return NULL' may produce: No symbol "NULL" in current context.) > Screenshot of the problem reproducer is at the bottom of this mail. Ah, yes. Gieven the amd64 ISA zero-extends stores into the low 32 bits of a GPR, amd64_return_value() should do the same. > While I do not have such machine at hand (could try UAE - m68k - for caller > expecting `long long') I agree with your argument to my former unconditionally > `long long'-casting patch: > On Wed, 11 Feb 2009 23:44:21 +0100, Mark Kettenis wrote: > > I'm not convinced casting to `long long' is safe in all cases, especially on > > 32-bit big-endian machines. It really might do the wrong thing there, > > exposing garbage or the wrong 32 bits of the 64-bit value. > > To find a way out of the both requirements this patch implements: > > On Sat, 21 Feb 2009 01:04:09 +0100, Jan Kratochvil wrote: > > > +/* Set RETURN_VALUE extended to the largest type width which will still be the > > > + same value after reading it back using the RETURN_VALUE type. */ > > So this patch tries as best as it can the original intention of a widest cast > but still it verifies it has not broken the compatibility with the type > specified by user. Specified either intentionally or unintentionally. Well, I think your code violates the KISS principle. > It has no regressions. The only imperfection I find is on the big endian > 32bit arches one has to use an explicitely cast for callers expecting `long > long'. But it cannot be guessed better and big endian arches are minority. Perhaps that's true for the architectures that Red Hat ships products for. It's certainly not true for the industry as a whole. ^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [patch] Fix `return' of long/long-long results with no debuginfo 2009-02-21 16:21 ` Mark Kettenis @ 2009-02-21 16:32 ` Jan Kratochvil 0 siblings, 0 replies; 38+ messages in thread From: Jan Kratochvil @ 2009-02-21 16:32 UTC (permalink / raw) To: Mark Kettenis; +Cc: drow, gdb-patches On Sat, 21 Feb 2009 14:43:44 +0100, Mark Kettenis wrote: > > It has been proven by the original bugreport even experienced > > programmers will make a mistake forgetting about the type cast. > > And I' say it again. You're doing such users a far bigger favour by > distributing libraries with debug information. than with bloating gdb > with code to work around issues. Fedora GDB already has a custom patch to make this more easy: http://cvs.fedora.redhat.com/viewvc/rpms/gdb/devel/gdb-6.6-buildid-locate.patch?view=co $ gdb --args sleep 1h GNU gdb Fedora (6.8-29.fc10) [...] This GDB was configured as "x86_64-redhat-linux-gnu"... (no debugging symbols found) Missing separate debuginfos, use: debuginfo-install coreutils-6.12-18.fc10.x86_64 (gdb) q $ gdb -q ./main (gdb) r Starting program: /md1/home/lace/src/main Program exited normally. Missing separate debuginfos, use: debuginfo-install glibc-2.9-3.x86_64 (gdb) q Still you can find in the bugreport(s) people do not do it: https://bugzilla.redhat.com/show_bug.cgi?id=365111 Mostly cited reason is that debuginfo files are currently too big, which is being actively worked on: https://fedoraproject.org/wiki/Features/DebugInfoRevamp The state of the debugging is not perfect but I hope Fedora does the best effort it can for it instead of turning down patches without even giving a reason now. Regards, Jan ^ permalink raw reply [flat|nested] 38+ messages in thread
end of thread, other threads:[~2009-03-18 15:39 UTC | newest] Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2009-02-11 19:45 [patch] Fix `return' of long/long-long results with no debuginfo Jan Kratochvil 2009-02-11 20:40 ` Mark Kettenis 2009-02-11 20:50 ` Daniel Jacobowitz 2009-02-11 21:23 ` Mark Kettenis 2009-02-11 21:47 ` Jan Kratochvil 2009-02-11 21:58 ` Mark Kettenis 2009-02-11 22:08 ` Jan Kratochvil 2009-02-11 22:38 ` Mark Kettenis 2009-02-11 22:50 ` Jan Kratochvil 2009-03-03 18:10 ` Tom Tromey 2009-03-04 21:29 ` Mark Kettenis 2009-03-05 0:15 ` Tom Tromey 2009-03-09 1:55 ` Jan Kratochvil 2009-03-09 22:38 ` Mark Kettenis 2009-03-11 16:49 ` Joel Brobecker 2009-03-11 20:23 ` Tom Tromey 2009-03-11 21:48 ` Joel Brobecker 2009-03-13 19:50 ` Jan Kratochvil 2009-03-13 23:00 ` Joel Brobecker 2009-03-14 10:45 ` Eli Zaretskii 2009-03-14 22:09 ` Jan Kratochvil 2009-03-14 22:18 ` Eli Zaretskii 2009-03-15 9:22 ` Joel Brobecker 2009-03-15 18:15 ` Jan Kratochvil 2009-03-18 4:36 ` Pedro Alves 2009-03-18 14:44 ` Joel Brobecker 2009-03-18 15:39 ` Jan Kratochvil 2009-03-18 15:46 ` Pedro Alves 2009-02-11 22:44 ` Mark Kettenis 2009-02-12 9:41 ` Jan Kratochvil 2009-02-12 14:36 ` Pierre Muller 2009-02-12 14:44 ` Jan Kratochvil 2009-02-14 21:59 ` Mark Kettenis 2009-02-21 12:47 ` Jan Kratochvil 2009-02-21 13:44 ` Mark Kettenis 2009-02-21 15:58 ` Jan Kratochvil 2009-02-21 16:21 ` Mark Kettenis 2009-02-21 16:32 ` Jan Kratochvil
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox