Re: [patch] Fix `return' of long/long-long results with no debuginfo

Jan Kratochvil
2009-02-21T12:47:53Z

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.