Problem with Nov 21 1997 valops.c:call_function_by_hand change
Peter.Schauer
Peter.Schauer@regent.e-technik.tu-muenchen.de
Mon May 4 12:47:00 GMT 1998
This change:
Fri Nov 21 19:43:23 1997 Jim Blandy <jimb@zwingli.cygnus.com>
* valops.c (call_function_by_hand): If the function has a
prototype, convert its arguments as if by assignment. Otherwise,
do the usual promotions.
causes at least two problems.
1) When passing an int to a function expecting a reference to an int,
GDB now fails. value_cast doesn't convert to a reference, and it
shouldn't, whereas value_arg_coerce used to get it right in gdb-4.16.
pes@resunserv_1002$ cat tcall.cc
int int_val = 87;
int &int_ref = int_val;
int t_ref(int & a)
{
return a;
}
main () {}
pes@resunserv_1003$ gcc -g tcall.cc
pes@resunserv_1004$ gdb a.out
GNU gdb 4.17
This GDB was configured as "sparc-sun-solaris2.5.1"...
(gdb) b main
Breakpoint 1 at 0x10ad0: file tcall.cc, line 9.
(gdb) r
Starting program: a.out
Breakpoint 1, main () at tcall.cc:9
9 main () {}
(gdb) p t_ref(int_val)
Program received signal SIGBUS, Bus error.
0x109ac in t_ref (a=@0x57) at tcall.cc:6
6 return a;
The program being debugged stopped while in a function called from GDB.
When the function (t_ref(int &)) is done executing, GDB will silently
stop (instead of continuing to evaluate the expression containing
the function call).
2) When using dwarf2 debugging info under Linux (via -ggdb) for the
gdb/testsuite/gdb.base/callfuncs.c testcase, t_small_values gets
TYPE_FLAG_PROTOTYPED set, and the argument types are the non-promoted
types.
value_cast then changes the passed integer arguments to char/short
arguments, causing misplaced arguments on the stack, as the default
promotion to int via value_arg_coerce is missing now.
bash-2.01$ gdb callfuncs
GNU gdb 4.17
This GDB was configured as "i586-pc-linux-gnu"...
(gdb) b main
Breakpoint 1 at 0x80486c5: file callfuncs.c, line 135.
(gdb) r
Starting program: callfuncs
Breakpoint 1, main () at callfuncs.c:135
135 malloc(1);
(gdb) i source
Current source file is ...
Compilation directory is ...
Located in ...
Contains 268 lines.
Source language is c.
Compiled with DWARF 2 debugging format.
(gdb) p t_small_values(1,2,3,4,5,6,7,8,9,10)
$1 = 117887498
The following patch solves both problems by reverting call_function_by_hand
to using value_arg_coerce instead of value_cast.
Any comments, suggestions ?
*** gdb/valops.c.orig Tue Feb 10 08:39:18 1998
--- gdb/valops.c Mon May 4 21:30:02 1998
***************
*** 47,53 ****
#ifdef CALL_DUMMY
static CORE_ADDR find_function_addr PARAMS ((value_ptr, struct type **));
! static value_ptr value_arg_coerce PARAMS ((value_ptr, struct type *));
#endif
--- 47,53 ----
#ifdef CALL_DUMMY
static CORE_ADDR find_function_addr PARAMS ((value_ptr, struct type **));
! static value_ptr value_arg_coerce PARAMS ((value_ptr, struct type *, int));
#endif
***************
*** 944,955 ****
/* Perform the standard coercions that are specified
for arguments to be passed to C functions.
! If PARAM_TYPE is non-NULL, it is the expected parameter type. */
static value_ptr
! value_arg_coerce (arg, param_type)
value_ptr arg;
struct type *param_type;
{
register struct type *arg_type = check_typedef (VALUE_TYPE (arg));
register struct type *type
--- 944,957 ----
/* Perform the standard coercions that are specified
for arguments to be passed to C functions.
! If PARAM_TYPE is non-NULL, it is the expected parameter type.
! Performs float to double conversion only if COERCE_FLOAT is non-zero. */
static value_ptr
! value_arg_coerce (arg, param_type, coerce_float)
value_ptr arg;
struct type *param_type;
+ int coerce_float;
{
register struct type *arg_type = check_typedef (VALUE_TYPE (arg));
register struct type *type
***************
*** 973,980 ****
type = builtin_type_int;
break;
case TYPE_CODE_FLT:
! /* coerce float to double, unless the function prototype specifies float */
! if (COERCE_FLOAT_TO_DOUBLE)
{
if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double))
type = builtin_type_double;
--- 975,982 ----
type = builtin_type_int;
break;
case TYPE_CODE_FLT:
! /* coerce float to double if requested. */
! if (coerce_float)
{
if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double))
type = builtin_type_double;
***************
*** 1214,1232 ****
promotions. FIXME: if we had a prototype, this should only
be allowed if ... were present. */
if (i >= TYPE_NFIELDS (ftype))
! args[i] = value_arg_coerce (args[i], 0);
else
{
struct type *param_type = TYPE_FIELD_TYPE (ftype, i);
! /* If we have a prototype, cast as for assignment. */
if (TYPE_FLAGS (ftype) & TYPE_FLAG_PROTOTYPED)
! args[i] = value_cast (param_type, args[i]);
!
! /* Otherwise, do the standard promotions. */
else
! args[i] = value_arg_coerce (args[i], param_type);
}
}
--- 1216,1238 ----
promotions. FIXME: if we had a prototype, this should only
be allowed if ... were present. */
if (i >= TYPE_NFIELDS (ftype))
! args[i] = value_arg_coerce (args[i], NULL, 1);
else
{
struct type *param_type = TYPE_FIELD_TYPE (ftype, i);
! /* We do not request float to double promotions if we have
! a prototype. */
if (TYPE_FLAGS (ftype) & TYPE_FLAG_PROTOTYPED)
! args[i] = value_arg_coerce (args[i], param_type, 0);
else
! /* FIXME: We should always convert floats to doubles in the
! non-prototyped case. As many debugging formats include
! no information about prototyping, we have to live with
! COERCE_FLOAT_TO_DOUBLE for now. */
! args[i] = value_arg_coerce (args[i], param_type,
! COERCE_FLOAT_TO_DOUBLE);
}
}
--
Peter Schauer pes@regent.e-technik.tu-muenchen.de
More information about the Gdb
mailing list