From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18052 invoked by alias); 13 Mar 2009 17:12:17 -0000 Received: (qmail 17513 invoked by uid 22791); 13 Mar 2009 17:12:15 -0000 X-SWARE-Spam-Status: No, hits=-1.3 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_37,KAM_STOCKGEN,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mx2.redhat.com (HELO mx2.redhat.com) (66.187.237.31) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 13 Mar 2009 17:12:08 +0000 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n2DHBhB3012645; Fri, 13 Mar 2009 13:11:43 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n2DHBgqf001166; Fri, 13 Mar 2009 13:11:42 -0400 Received: from host0.dyn.jankratochvil.net (sebastian-int.corp.redhat.com [172.16.52.221]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id n2DHBej8000428; Fri, 13 Mar 2009 13:11:41 -0400 Received: from host0.dyn.jankratochvil.net (localhost [127.0.0.1]) by host0.dyn.jankratochvil.net (8.14.3/8.14.3) with ESMTP id n2DHBaJW004814; Fri, 13 Mar 2009 18:11:38 +0100 Received: (from jkratoch@localhost) by host0.dyn.jankratochvil.net (8.14.3/8.14.2/Submit) id n2DHBZYu004811; Fri, 13 Mar 2009 18:11:35 +0100 Date: Fri, 13 Mar 2009 19:50:00 -0000 From: Jan Kratochvil To: Joel Brobecker Cc: Tom Tromey , Mark Kettenis , drow@false.org, gdb-patches@sourceware.org Subject: Re: [patch] Fix `return' of long/long-long results with no debuginfo Message-ID: <20090313171134.GA4396@host0.dyn.jankratochvil.net> References: <200902112237.n1BMbbOb006035@brahms.sibelius.xs4all.nl> <20090211225012.GA28683@host0.dyn.jankratochvil.net> <200903042129.n24LTUKa000770@brahms.sibelius.xs4all.nl> <20090309015510.GA28986@host0.dyn.jankratochvil.net> <200903092233.n29MXEfG019900@brahms.sibelius.xs4all.nl> <20090311163024.GA25708@adacore.com> <20090311205901.GB25708@adacore.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20090311205901.GB25708@adacore.com> User-Agent: Mutt/1.5.18 (2008-05-17) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-03/txt/msg00214.txt.bz2 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 * stack.c (return_command ): 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 * gdb.texinfo (Returning): New description for missing debug info. gdb/testsuite/ 2009-03-13 Jan Kratochvil * 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 . */ + +#include + +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 . + +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 + } +}