When you call a function through a pointer that is determined by a
complex calculation, the wrong parameter may be passed to that
function.

For example, in gcc there is a data structure that contains function
pointers: 
-----
(gdb) p function_units[1]
$7 = {name = 0x2df638 "fp_alu", bitmask = 2, multiplicity = 1, 
  simultaneity = 0, default_cost = 0, max_issue_delay = 5, 
  ready_cost_function = 0x273d1c <fp_alu_unit_ready_cost>, 
  conflict_cost_function = 0x291880 <fp_alu_unit_conflict_cost>, 
  max_blockage = 5, 
  blockage_range_function = 0x274290 <fp_alu_unit_blockage_range>, 
  blockage_function = 0x290d3c <fp_alu_unit_blockage>}
-----
Set a breakpoint in one of these functions.
-----
(gdb) b fp_alu_unit_blockage_range
Breakpoint 4 at 0x274298: file insn-attrtab.c, line 2051.
-----
Then call it from gdb, passing a parameter (insn) which has a value:
-----
(gdb) p insn
$8 = 0x32afe8
(gdb) p function_units[1]. blockage_range_function(insn)

Breakpoint 4, fp_alu_unit_blockage_range (insn=0x2f3eec) at insn-attrtab.c:2051
The program being debugged stopped while in a function called from GDB.
When the function (fp_alu_unit_blockage_range) is done executing, GDB will silently
stop (instead of continuing to evaluate the expression containing
the function call).
-----

Notice that insn has the wrong value when stopped inside the target
function. 
But when the function is called directly the parameter is correct:
-----
(gdb) p fp_alu_unit_blockage_range(insn )

Breakpoint 4, fp_alu_unit_blockage_range (insn=0x32afe8) at insn-attrtab.c:2051
The program being debugged stopped while in a function called from GDB.
When the function (fp_alu_unit_blockage_range) is done executing, GDB will silently
stop (instead of continuing to evaluate the expression containing
the function call).
-----

You can also get the right answer by parenthesizing the complex
function call to make things more explicit:

-----
(gdb) p (*function_units[1]. blockage_range_function)(insn)

Breakpoint 4, fp_alu_unit_blockage_range (insn=0x32afe8) at insn-attrtab.c:2051
The program being debugged stopped while in a function called from GDB.
When the function (fp_alu_unit_blockage_range) is done executing, GDB will silently
stop (instead of continuing to evaluate the expression containing
the function call).
-----


More details for reproducing the bug:

gdb 4.17 compiled with gcc, probably gcc 2.8.1.

Program being debugged: cc1, part of gcc 2.8.1, built on Sun Solaris
2.5.1 using the default configuration. (Type "configure" and "make
cc1") on the command line.

Input to the compiler being debugged: x.c
----
extern float a[];
main(  int i,  float x, float y)
{

    a[i] = x + y;
}
-----

Added the following to the default .gdbinit included with gcc:
-----
b sched.c:3371
r x.c -O2

------

My guess (actually Raj Prakash's guess) as to what is happening: The
expression stack is somehow forgetting to pop off a value
corresponding to the function pointer being dereferenced, and another
value from the stack is being passed to the function. Notice that the
value of one of the intermediate expressions

-----
(gdb) p &function_units[1]
$9 = (struct function_unit_desc *) 0x2f3eec

-----

is the bogus number being passed to the function.

Thanks for looking into this.

chet

-- 
Chet Wood
[EMAIL PROTECTED]

Reply via email to