public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* [GDB & Fortran] Anyone has success experience with printing the result of Fortran function calls?
@ 2005-08-22 10:14 Wu Zhou
  2005-11-02  2:39 ` The root cause for SEGV in evaluating fortran function call, any solution or suggestion? Wu Zhou
  0 siblings, 1 reply; 23+ messages in thread
From: Wu Zhou @ 2005-08-22 10:14 UTC (permalink / raw)
  To: gdb, fortran


I just found a problem while using gdb to debug fortran program: gdb will 
drop into SEGV error while trying to print the result of a function call. 
I had tried the same test on FC4, SLES9, FC2 and RH9, all reported the 
same error.

Anyone has success experience with this?  If you do, please tell me 
the configuration.  Thanks a buch for that in advance!

Maybe I need to try more ancient configuration?

Regards
- Wu Zhou 

^ permalink raw reply	[flat|nested] 23+ messages in thread

* The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-08-22 10:14 [GDB & Fortran] Anyone has success experience with printing the result of Fortran function calls? Wu Zhou
@ 2005-11-02  2:39 ` Wu Zhou
  2005-11-02 14:53   ` Daniel Jacobowitz
  2005-11-02 15:51   ` Mark Kettenis
  0 siblings, 2 replies; 23+ messages in thread
From: Wu Zhou @ 2005-11-02  2:39 UTC (permalink / raw)
  To: gdb

Hi all,

I had found the reason why gdb will drop into SEGV when evaluating the 
fortran function calls.  In g77 (gfortran might be the same), when we try 
to call FUNC_NAME (ARGS), the ARGS is passed as the pointer to the real 
parameters.  

While we issue "print FUNC_NAME (ARGS), these ARGS are passed as the 
original types.  So fortran code can't handle that and SEGV occurs.  
Considering this special argument-passing mechanism, do we have any 
workaround for it in gdb's evaluation code?  Create a dummy memory address 
for the arguments and pass that address instead?  or any others? 

Your comments are highly appreciated.  Thanks a lot. 

Regards
- Wu Zhou

On Mon, 22 Aug 2005, Wu Zhou wrote:

> 
> I just found a problem while using gdb to debug fortran program: gdb will 
> drop into SEGV error while trying to print the result of a function call. 
> I had tried the same test on FC4, SLES9, FC2 and RH9, all reported the 
> same error.
> 
> Anyone has success experience with this?  If you do, please tell me 
> the configuration.  Thanks a buch for that in advance!
> 
> Maybe I need to try more ancient configuration?
> 
> Regards
> - Wu Zhou 
> 

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-11-02  2:39 ` The root cause for SEGV in evaluating fortran function call, any solution or suggestion? Wu Zhou
@ 2005-11-02 14:53   ` Daniel Jacobowitz
  2005-11-03  3:12     ` Wu Zhou
  2005-11-02 15:51   ` Mark Kettenis
  1 sibling, 1 reply; 23+ messages in thread
From: Daniel Jacobowitz @ 2005-11-02 14:53 UTC (permalink / raw)
  To: Wu Zhou; +Cc: gdb

On Wed, Nov 02, 2005 at 10:43:03AM +0800, Wu Zhou wrote:
> Hi all,
> 
> I had found the reason why gdb will drop into SEGV when evaluating the 
> fortran function calls.  In g77 (gfortran might be the same), when we try 
> to call FUNC_NAME (ARGS), the ARGS is passed as the pointer to the real 
> parameters.  
> 
> While we issue "print FUNC_NAME (ARGS), these ARGS are passed as the 
> original types.  So fortran code can't handle that and SEGV occurs.  
> Considering this special argument-passing mechanism, do we have any 
> workaround for it in gdb's evaluation code?  Create a dummy memory address 
> for the arguments and pass that address instead?  or any others? 

I don't think there's any way to handle that right now: you'll have to
add one.  I am not sure where in the call-function process it should
be.  Probably, you will also need a way to allocate them - on the stack
would be better than malloc, which is how gdb usually allocates memory.

-- 
Daniel Jacobowitz
CodeSourcery, LLC

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-11-02  2:39 ` The root cause for SEGV in evaluating fortran function call, any solution or suggestion? Wu Zhou
  2005-11-02 14:53   ` Daniel Jacobowitz
@ 2005-11-02 15:51   ` Mark Kettenis
  2005-11-03  2:50     ` Wu Zhou
  2005-11-03  7:42     ` Jim Blandy
  1 sibling, 2 replies; 23+ messages in thread
From: Mark Kettenis @ 2005-11-02 15:51 UTC (permalink / raw)
  To: woodzltc; +Cc: gdb

> X-From_: gdb-return-22951-m.m.kettenis=alumnus.utwente.nl@sourceware.org  Wed Nov  2 03:39:44 2005
> Mailing-List: contact gdb-help@sourceware.org; run by ezmlm
> Sender: gdb-owner@sourceware.org
> Date: Wed, 2 Nov 2005 10:43:03 +0800 (CST)
> From: Wu Zhou <woodzltc@cn.ibm.com>
> X-UTwente-MailScanner-Information: Scanned by MailScanner. Contact helpdesk@ITBE.utwente.nl for more information.
> X-UTwente-MailScanner: Found to be clean
> X-MailScanner-From: gdb-return-22951-m.m.kettenis=alumnus.utwente.nl@sourceware.org
> X-Spam-Checker-Version: SpamAssassin 3.0.4 (2005-06-05) on 
> 	elgar.sibelius.xs4all.nl
> X-Spam-Level: 
> X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=failed 
> 	version=3.0.4
> 
> Hi all,
> 
> I had found the reason why gdb will drop into SEGV when evaluating the 
> fortran function calls.  In g77 (gfortran might be the same), when we try 
> to call FUNC_NAME (ARGS), the ARGS is passed as the pointer to the real 
> parameters.  
> 
> While we issue "print FUNC_NAME (ARGS), these ARGS are passed as the 
> original types.  So fortran code can't handle that and SEGV occurs.  
> Considering this special argument-passing mechanism, do we have any 
> workaround for it in gdb's evaluation code?  Create a dummy memory address 
> for the arguments and pass that address instead?  or any others? 
> 
> Your comments are highly appreciated.  Thanks a lot. 

What you describe sounds very similar to what
gdbarch_stabs_argument_has_addr is all about.  Currently these are
only used on SPARC, and only for stabs.

One could argue that the debug information generated by g77 is wrong,
because it doesn't reflect the actual implementation of FUNC_NAME.  Or
perhaps GDB symbol reading code causes problems.  Can you post a
concrete example of a function call that goes wrong, and add a bit of
explanation about the types involved for those of us who are not very
familiar with Fortran?

Thanks,

Mark

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-11-02 15:51   ` Mark Kettenis
@ 2005-11-03  2:50     ` Wu Zhou
  2005-11-03  7:42     ` Jim Blandy
  1 sibling, 0 replies; 23+ messages in thread
From: Wu Zhou @ 2005-11-03  2:50 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: gdb

Hi Mark,

On Wed, 2 Nov 2005, Mark Kettenis wrote:

> What you describe sounds very similar to what
> gdbarch_stabs_argument_has_addr is all about.  Currently these are
> only used on SPARC, and only for stabs.

Thanks for your pointer.  It looks very much like the same (If I understand
correctly :-).  Look at the following testcase please:

        PROGRAM funcall
          integer a, b
          b = 2
          a = res(b)
        END PROGRAM

        function res(m)
          integer m
          integer res
          res = m * m
        end function

The debuginfo for function res is like this:

 <1><da>: Abbrev Number: 7 (DW_TAG_subprogram)
     DW_AT_sibling     : <10f>
     DW_AT_external    : 1
     DW_AT_name        : res_
     DW_AT_decl_file   : 1
     DW_AT_decl_line   : 23
     DW_AT_type        : <bb>
     DW_AT_low_pc      : 0x804863f
     DW_AT_high_pc     : 0x8048655
     DW_AT_frame_base  : 1 byte block: 55       (DW_OP_reg5)
 <2><f5>: Abbrev Number: 8 (DW_TAG_formal_parameter)
     DW_AT_name        : m
     DW_AT_type        : <10f>   =====> This is a const pointer to integer
     DW_AT_artificial  : 1
     DW_AT_location    : 2 byte block: 91 8     (DW_OP_fbreg: 8)

 <1><10f>: Abbrev Number: 9 (DW_TAG_const_type)
     DW_AT_type        : <114>
 <1><114>: Abbrev Number: 10 (DW_TAG_pointer_type)
     DW_AT_byte_size   : 4
     DW_AT_type        : <bb>
 <1><bb>: Abbrev Number: 6 (DW_TAG_base_type)
     DW_AT_name        : integer
     DW_AT_byte_size   : 4
     DW_AT_encoding    : 5      (signed)

So my question is: how will gdb to handle this situation if the gdbarch 
shows that stabs argument has addr, especially when the command line pass 
an integer type, but the debuginfo said that it need a pointer?

> 
> One could argue that the debug information generated by g77 is wrong,
> because it doesn't reflect the actual implementation of FUNC_NAME.  Or
> perhaps GDB symbol reading code causes problems.  Can you post a
> concrete example of a function call that goes wrong, and add a bit of
> explanation about the types involved for those of us who are not very
> familiar with Fortran?

Both of your arguments seem reasonable.  But even in the first argument it 
might also be desirable that we could handle it gracefully, right? 

Here is the debugging session for the above testcase (maybe I could 
convert it into a real testcase for gdb testsuite?), hoping that 
it could clarify the things a little.

(gdb) r
Starting program: /root/DE/gdb-6.3/gdb/testsuite/gdb.fortran/func-call

Breakpoint 1, MAIN__ () at func-call.f:19
19                b = 2
Current language:  auto; currently fortran
(gdb) n
20                a = res(b)
(gdb) p res (2)
No symbol "res" in current context.
(gdb) p res_ (2)     =========> Use constand '2' as argument, get SEGV

Program received signal SIGSEGV, Segmentation fault.
0x08048648 in res_ (m=0x2) at func-call.f:26
26                res = m * m
The program being debugged was signaled while in a function called from 
GDB.
GDB remains in the frame where the signal was received.
To change this behavior use "set unwindonsignal on"
Evaluation of the expression containing the function (res_) will be 
abandoned.
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /root/DE/gdb-6.3/gdb/testsuite/gdb.fortran/func-call

Breakpoint 1, MAIN__ () at func-call.f:19
19                b = 2
(gdb) n
20                a = res(b)
(gdb) p res_ (b)    =========> Use variable 'b' as argument, get SEGV

Program received signal SIGSEGV, Segmentation fault.
0x08048648 in res_ (m=0x2) at func-call.f:26
26                res = m * m
The program being debugged was signaled while in a function called from 
GDB.
GDB remains in the frame where the signal was received.
To change this behavior use "set unwindonsignal on"
Evaluation of the expression containing the function (res_) will be 
abandoned.
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /root/DE/gdb-6.3/gdb/testsuite/gdb.fortran/func-call

Breakpoint 1, MAIN__ () at func-call.f:19
19                b = 2
(gdb) n
20                a = res(b)
(gdb) p res_ (&b)    ========> Use '&b' as argument, get correct result
$1 = 4

Regards
- Wu Zhou

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-11-02 14:53   ` Daniel Jacobowitz
@ 2005-11-03  3:12     ` Wu Zhou
  2005-11-03 21:34       ` Mark Kettenis
  0 siblings, 1 reply; 23+ messages in thread
From: Wu Zhou @ 2005-11-03  3:12 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gdb

Hi Daniel,

On Wed, 2 Nov 2005, Daniel Jacobowitz wrote:

> On Wed, Nov 02, 2005 at 10:43:03AM +0800, Wu Zhou wrote:
> > Hi all,
> > 
> > I had found the reason why gdb will drop into SEGV when evaluating the 
> > fortran function calls.  In g77 (gfortran might be the same), when we try 
> > to call FUNC_NAME (ARGS), the ARGS is passed as the pointer to the real 
> > parameters.  
> > 
> > While we issue "print FUNC_NAME (ARGS), these ARGS are passed as the 
> > original types.  So fortran code can't handle that and SEGV occurs.  
> > Considering this special argument-passing mechanism, do we have any 
> > workaround for it in gdb's evaluation code?  Create a dummy memory address 
> > for the arguments and pass that address instead?  or any others? 
> 
> I don't think there's any way to handle that right now: you'll have to
> add one.  I am not sure where in the call-function process it should
> be.  Probably, you will also need a way to allocate them - on the stack
> would be better than malloc, which is how gdb usually allocates memory.

Maybe we can convert the argument to its pointer before we enter into
call_function_by_hand (evaluate_subexp_standard: case OP_FUNCALL)?  
Normally what function you will use to allocate memory on the stack?  I am 
not very familar with that kind of code.  Thanks!

Regards
- Wu Zhou
 

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-11-02 15:51   ` Mark Kettenis
  2005-11-03  2:50     ` Wu Zhou
@ 2005-11-03  7:42     ` Jim Blandy
  2005-11-03 10:16       ` Wu Zhou
  2005-11-07  0:02       ` Daniel Jacobowitz
  1 sibling, 2 replies; 23+ messages in thread
From: Jim Blandy @ 2005-11-03  7:42 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: woodzltc, gdb


Mark Kettenis <mark.kettenis@xs4all.nl> writes:
> One could argue that the debug information generated by g77 is wrong,
> because it doesn't reflect the actual implementation of FUNC_NAME.  Or
> perhaps GDB symbol reading code causes problems.  Can you post a
> concrete example of a function call that goes wrong, and add a bit of
> explanation about the types involved for those of us who are not very
> familiar with Fortran?

The types in the debug information should not reflect the extra level
of indirection; the fact that they're passed by reference is just part
of the meaning of a Fortran function call.  But the location
expression should encode the extra level of indirection.

Probably value_arg_coerce should be a language method.  The C
promotion rules aren't appropriate for Fortran anyway, and the Fortran
version could take care of applying value_addr (or something like
that), and turning the array of actuals into an array of pointers to
the actuals.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-11-03  7:42     ` Jim Blandy
@ 2005-11-03 10:16       ` Wu Zhou
  2005-11-07  0:02       ` Daniel Jacobowitz
  1 sibling, 0 replies; 23+ messages in thread
From: Wu Zhou @ 2005-11-03 10:16 UTC (permalink / raw)
  To: Jim Blandy; +Cc: Mark Kettenis, gdb

On Wed, 2 Nov 2005, Jim Blandy wrote:

> 
> Mark Kettenis <mark.kettenis@xs4all.nl> writes:
> > One could argue that the debug information generated by g77 is wrong,
> > because it doesn't reflect the actual implementation of FUNC_NAME.  Or
> > perhaps GDB symbol reading code causes problems.  Can you post a
> > concrete example of a function call that goes wrong, and add a bit of
> > explanation about the types involved for those of us who are not very
> > familiar with Fortran?
> 
> The types in the debug information should not reflect the extra level
> of indirection; the fact that they're passed by reference is just part
> of the meaning of a Fortran function call.  But the location
> expression should encode the extra level of indirection.
> 
> Probably value_arg_coerce should be a language method.  The C
> promotion rules aren't appropriate for Fortran anyway, and the Fortran
> version could take care of applying value_addr (or something like
> that), and turning the array of actuals into an array of pointers to
> the actuals.

Jim, it seems that you just said out what I am thinking of.  Function 
value_arg_coerce is said to perform the standard coercion that are 
specified for arguments to be passed to C functions (you can see that in 
the comment).  But it is also used for Fortran functions (maybe all 
other function GDB supports). 

What is more, I find that when I pass "res_(b)" to gfortran code in gdb 
command line, it will get the correct result.  All the difference is that 
gfortran handle the parameters as reference to the actuals.  So 
value_arg_coerce will call value_addr to convert args into the address of 
them, so we can get the correct result.

However with gfortran, "print res_(2)" still doesn't get the correct 
result.  But it fail more gracefully, it reports the following error 
message:  
  Attempt to take address of value not located in memory.

Which is well expected with reference to the code in value_arg_coerce.

So I am thinking of a somwhat different value_arg_coerce for Fortran code: 
when the parameter type is a reference (for gfortran) or pointer (for 
g77), we can call something like value_addr to changed the argument into 
its address.

I did some tests today, but no success so far.  Will take some more look 
into this.

Any suggestion, comments on this?  Thanks!

Regards
- Wu Zhou

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-11-03  3:12     ` Wu Zhou
@ 2005-11-03 21:34       ` Mark Kettenis
  2005-11-04  3:15         ` Wu Zhou
  2005-11-04 11:20         ` Dave Korn
  0 siblings, 2 replies; 23+ messages in thread
From: Mark Kettenis @ 2005-11-03 21:34 UTC (permalink / raw)
  To: woodzltc; +Cc: drow, gdb

> Date: Thu, 3 Nov 2005 11:14:51 +0800 (CST)
> From: Wu Zhou <woodzltc@cn.ibm.com>
> 
> Maybe we can convert the argument to its pointer before we enter into
> call_function_by_hand (evaluate_subexp_standard: case OP_FUNCALL)?  
> Normally what function you will use to allocate memory on the stack?  I am 
> not very familar with that kind of code.  Thanks!

Allocating memory on the stack is actually quite eazy.  Just
substract/add the amount of space you need from/to the stack pointer,
and use the new/old stack pointer as the address for the memory.
Whether you should substract or add depends on whether the stack grows
downward or upward.  Use gdbarch_inner_than(gdbarch, 1, 2) to check.
There's quite a bit of code in infcall.c that uses this trick.

Mark

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-11-03 21:34       ` Mark Kettenis
@ 2005-11-04  3:15         ` Wu Zhou
  2005-11-04  3:52           ` Wu Zhou
  2005-11-07  0:09           ` Daniel Jacobowitz
  2005-11-04 11:20         ` Dave Korn
  1 sibling, 2 replies; 23+ messages in thread
From: Wu Zhou @ 2005-11-04  3:15 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: drow, gdb

Hi Mark,

On Thu, 3 Nov 2005, Mark Kettenis wrote:

> > Date: Thu, 3 Nov 2005 11:14:51 +0800 (CST)
> > From: Wu Zhou <woodzltc@cn.ibm.com>
> > 
> > Maybe we can convert the argument to its pointer before we enter into
> > call_function_by_hand (evaluate_subexp_standard: case OP_FUNCALL)?  
> > Normally what function you will use to allocate memory on the stack?  I am 
> > not very familar with that kind of code.  Thanks!
> 
> Allocating memory on the stack is actually quite eazy.  Just
> substract/add the amount of space you need from/to the stack pointer,
> and use the new/old stack pointer as the address for the memory.
> Whether you should substract or add depends on whether the stack grows
> downward or upward.  Use gdbarch_inner_than(gdbarch, 1, 2) to check.
> There's quite a bit of code in infcall.c that uses this trick.
> 

Thanks.  I did some tests following this way.  But didn't get any success. 
So I had to post here again to see if anybody can help me out.  

My basic idea is to create a value which hold the address to the original 
argument. This is done in valur_addr for these argument which is not lval 
and whose type is TYPE_CODE_INT.  Then I use the above method to get a new 
value which hold the address to the original address.  Although it doesn't 
report SEGV or "can not access memory" message, it didn't ouptut the 
correct result I expected.  I expect 4 (which is 2 * 2), but it return 
different number for me every time I run it.

Following is the changed I made to valur_arg_coerce and value_addr.  Could 
anyone help me pointed out what is the reason why it fail.  Thanks a lot!

Index: infcall.c
===================================================================
RCS file: /cvs/src/src/gdb/infcall.c,v
retrieving revision 1.73
diff -c -3 -p -r1.73 infcall.c
*** infcall.c	2 Sep 2005 19:02:44 -0000	1.73
--- infcall.c	4 Nov 2005 03:11:35 -0000
*************** value_arg_coerce (struct value *arg, str
*** 109,114 ****
--- 109,115 ----
    switch (TYPE_CODE (type))
      {
      case TYPE_CODE_REF:
+     case TYPE_CODE_PTR:
        if (TYPE_CODE (arg_type) != TYPE_CODE_REF
  	  && TYPE_CODE (arg_type) != TYPE_CODE_PTR)
  	{
*************** value_arg_coerce (struct value *arg, str
*** 154,160 ****
  	  type = lookup_pointer_type (TYPE_TARGET_TYPE (type));
        break;
      case TYPE_CODE_UNDEF:
-     case TYPE_CODE_PTR:
      case TYPE_CODE_STRUCT:
      case TYPE_CODE_UNION:
      case TYPE_CODE_VOID:
--- 155,160 ----
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.161
diff -c -3 -p -r1.161 valops.c
*** valops.c	27 May 2005 04:39:32 -0000	1.161
--- valops.c	4 Nov 2005 03:11:49 -0000
*************** value_addr (struct value *arg1)
*** 868,877 ****
      }
    if (TYPE_CODE (type) == TYPE_CODE_FUNC)
      return value_coerce_function (arg1);
! 
    if (VALUE_LVAL (arg1) != lval_memory)
      error (_("Attempt to take address of value not located in memory."));
  
    /* Get target memory address */
    arg2 = value_from_pointer (lookup_pointer_type (value_type (arg1)),
  			     (VALUE_ADDRESS (arg1)
--- 868,905 ----
      }
    if (TYPE_CODE (type) == TYPE_CODE_FUNC)
      return value_coerce_function (arg1);
! /*
    if (VALUE_LVAL (arg1) != lval_memory)
      error (_("Attempt to take address of value not located in memory."));
+ */
+ 
+   if (TYPE_CODE (type) == TYPE_CODE_INT  && VALUE_LVAL (arg1) == not_lval)
+     {
+       int len = TYPE_LENGTH (type);
+       CORE_ADDR addr;
+       CORE_ADDR sp = read_sp ();
+       if (INNER_THAN (1, 2))
+ 	{
+ 	  /* stack grows downward */
+ 	  sp -= len;
+ 	  /* ... so the address of the thing we push is the
+ 	     stack pointer after we push it.  */
+ 	  addr = sp;
+ 	}
+       else
+ 	{
+ 	  /* The stack grows up, so the address of the thing
+ 	     we push is the stack pointer before we push it.  */
+ 	  addr = sp;
+ 	  sp += len;
+ 	}
+ 
+       addr = (CORE_ADDR) malloc (len);
+       write_memory (addr, value_contents_all (arg1), len);
+       arg2 = value_from_pointer (lookup_pointer_type (type), addr);
  
+       return arg2;
+     }
    /* Get target memory address */
    arg2 = value_from_pointer (lookup_pointer_type (value_type (arg1)),
  			     (VALUE_ADDRESS (arg1)


Regards
- Wu Zhou

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-11-04  3:15         ` Wu Zhou
@ 2005-11-04  3:52           ` Wu Zhou
  2005-11-07  0:09           ` Daniel Jacobowitz
  1 sibling, 0 replies; 23+ messages in thread
From: Wu Zhou @ 2005-11-04  3:52 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: drow, gdb

I also added a testcase for this.  It should be easy to test in the coding 
process.  I tested it with gfortran and mainline gdb, it report 5PASS + 
1FAIL ('p res_(2)' reports "Attempt to take address of value not located 
in memory").  The test with g77 and mainline gdb shows 4 PASS and 2 FAIL 
(SEGV with 'p res_(2)' and 'p res_(b)').  And test with the g77 and the 
latest patched gdb, it showed 5PASS + 1FAIL (error output with 'p res_(2)').

Do you think that it make sense for this goes into the testsuite tree? 

Here is the patch:

Index: gdb.fortran/func-call.f
===================================================================
RCS file: gdb.fortran/func-call.f
diff -N gdb.fortran/func-call.f
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gdb.fortran/func-call.f	4 Nov 2005 03:47:22 -0000
***************
*** 0 ****
--- 1,27 ----
+ c Copyright 2005 Free Software Foundation, Inc.
+ 
+ c This program is free software; you can redistribute it and/or modify
+ c it under the terms of the GNU General Public License as published by
+ c the Free Software Foundation; either version 2 of the License, or
+ c (at your option) any later version.
+ c
+ c This program is distributed in the hope that it will be useful,
+ c but WITHOUT ANY WARRANTY; without even the implied warranty of
+ c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ c GNU General Public License for more details.
+ c
+ c You should have received a copy of the GNU General Public License
+ c along with this program; if not, write to the Free Software
+ c Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ 
+         PROGRAM funcall 
+           integer a, b
+           b = 2
+           a = res(b) 
+         END PROGRAM 
+ 
+         function res(m)
+           integer m
+           integer res
+           res = m * m
+         end function
Index: gdb.fortran/func-call.exp
===================================================================
RCS file: gdb.fortran/func-call.exp
diff -N gdb.fortran/func-call.exp
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gdb.fortran/func-call.exp	4 Nov 2005 03:47:22 -0000
***************
*** 0 ****
--- 1,79 ----
+ # Copyright 2005 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 2 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, write to the Free Software
+ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+ 
+ # This file was written by Wu Zhou. (woodzltc@cn.ibm.com)
+ 
+ if $tracelevel then {
+ 	strace $tracelevel
+ }
+ 
+ set testfile "func-call"
+ set srcfile ${testfile}.f
+ set binfile ${objdir}/${subdir}/${testfile}
+ 
+ if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f77 quiet}] != "" } {
+     untested "Couldn't compile ${srcfile}"
+     return -1
+ }
+ 
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+ 
+ # To test "print res_(2)"
+ 
+ if ![runto MAIN__] then {
+     perror "couldn't run to breakpoint MAIN__"
+     continue
+ }
+ 
+ gdb_breakpoint [gdb_get_line_number "a = res(b)"]
+ gdb_continue_to_breakpoint "initialize argument b"
+ gdb_test_multiple "print res_(2)" "print res_(2)" {
+     -re ".*\[0-9\]+ = 4.*$gdb_prompt $" {
+         pass "use constant 2 as the argument"
+     }
+     -re "Program received signal SIGSEGV, Segmentation fault.*$gdb_prompt $" {
+         fail "print res_(2) get SEGV"   
+     }
+     -re ".*$gdb_prompt $" {
+         fail "other unexpected error"
+     }
+ }
+ 
+ # To test "print res_(b)"
+ 
+ if ![runto MAIN__] then {
+     perror "couldn't run to breakpoint MAIN__"
+     continue
+ }
+ 
+ gdb_breakpoint [gdb_get_line_number "a = res(b)"]
+ gdb_continue_to_breakpoint "initialize argument b"
+ gdb_test "print res_(b)" ".*\[0-9\]+ = 4.*" "use variable 'b' as the argument"
+ 
+ # To test "print res_(&b)"
+ 
+ if ![runto MAIN__] then {
+     perror "couldn't run to breakpoint MAIN__"
+     continue
+ }
+ 
+ gdb_breakpoint [gdb_get_line_number "a = res(b)"]
+ gdb_continue_to_breakpoint "initialize argument b"
+ gdb_test "print res_(&b)" ".*\[0-9\]+ = 4.*" "use the address of 'b' as the argument"
+ 


On Fri, 4 Nov 2005, Wu Zhou wrote:

> Hi Mark,
> 
> On Thu, 3 Nov 2005, Mark Kettenis wrote:
> 
> > > Date: Thu, 3 Nov 2005 11:14:51 +0800 (CST)
> > > From: Wu Zhou <woodzltc@cn.ibm.com>
> > > 
> > > Maybe we can convert the argument to its pointer before we enter into
> > > call_function_by_hand (evaluate_subexp_standard: case OP_FUNCALL)?  
> > > Normally what function you will use to allocate memory on the stack?  I am 
> > > not very familar with that kind of code.  Thanks!
> > 
> > Allocating memory on the stack is actually quite eazy.  Just
> > substract/add the amount of space you need from/to the stack pointer,
> > and use the new/old stack pointer as the address for the memory.
> > Whether you should substract or add depends on whether the stack grows
> > downward or upward.  Use gdbarch_inner_than(gdbarch, 1, 2) to check.
> > There's quite a bit of code in infcall.c that uses this trick.
> > 
> 
> Thanks.  I did some tests following this way.  But didn't get any success. 
> So I had to post here again to see if anybody can help me out.  
> 
> My basic idea is to create a value which hold the address to the original 
> argument. This is done in valur_addr for these argument which is not lval 
> and whose type is TYPE_CODE_INT.  Then I use the above method to get a new 
> value which hold the address to the original address.  Although it doesn't 
> report SEGV or "can not access memory" message, it didn't ouptut the 
> correct result I expected.  I expect 4 (which is 2 * 2), but it return 
> different number for me every time I run it.
> 
> Following is the changed I made to valur_arg_coerce and value_addr.  Could 
> anyone help me pointed out what is the reason why it fail.  Thanks a lot!
> 
> Index: infcall.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/infcall.c,v
> retrieving revision 1.73
> diff -c -3 -p -r1.73 infcall.c
> *** infcall.c	2 Sep 2005 19:02:44 -0000	1.73
> --- infcall.c	4 Nov 2005 03:11:35 -0000
> *************** value_arg_coerce (struct value *arg, str
> *** 109,114 ****
> --- 109,115 ----
>     switch (TYPE_CODE (type))
>       {
>       case TYPE_CODE_REF:
> +     case TYPE_CODE_PTR:
>         if (TYPE_CODE (arg_type) != TYPE_CODE_REF
>   	  && TYPE_CODE (arg_type) != TYPE_CODE_PTR)
>   	{
> *************** value_arg_coerce (struct value *arg, str
> *** 154,160 ****
>   	  type = lookup_pointer_type (TYPE_TARGET_TYPE (type));
>         break;
>       case TYPE_CODE_UNDEF:
> -     case TYPE_CODE_PTR:
>       case TYPE_CODE_STRUCT:
>       case TYPE_CODE_UNION:
>       case TYPE_CODE_VOID:
> --- 155,160 ----
> Index: valops.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/valops.c,v
> retrieving revision 1.161
> diff -c -3 -p -r1.161 valops.c
> *** valops.c	27 May 2005 04:39:32 -0000	1.161
> --- valops.c	4 Nov 2005 03:11:49 -0000
> *************** value_addr (struct value *arg1)
> *** 868,877 ****
>       }
>     if (TYPE_CODE (type) == TYPE_CODE_FUNC)
>       return value_coerce_function (arg1);
> ! 
>     if (VALUE_LVAL (arg1) != lval_memory)
>       error (_("Attempt to take address of value not located in memory."));
>   
>     /* Get target memory address */
>     arg2 = value_from_pointer (lookup_pointer_type (value_type (arg1)),
>   			     (VALUE_ADDRESS (arg1)
> --- 868,905 ----
>       }
>     if (TYPE_CODE (type) == TYPE_CODE_FUNC)
>       return value_coerce_function (arg1);
> ! /*
>     if (VALUE_LVAL (arg1) != lval_memory)
>       error (_("Attempt to take address of value not located in memory."));
> + */
> + 
> +   if (TYPE_CODE (type) == TYPE_CODE_INT  && VALUE_LVAL (arg1) == not_lval)
> +     {
> +       int len = TYPE_LENGTH (type);
> +       CORE_ADDR addr;
> +       CORE_ADDR sp = read_sp ();
> +       if (INNER_THAN (1, 2))
> + 	{
> + 	  /* stack grows downward */
> + 	  sp -= len;
> + 	  /* ... so the address of the thing we push is the
> + 	     stack pointer after we push it.  */
> + 	  addr = sp;
> + 	}
> +       else
> + 	{
> + 	  /* The stack grows up, so the address of the thing
> + 	     we push is the stack pointer before we push it.  */
> + 	  addr = sp;
> + 	  sp += len;
> + 	}
> + 
> +       addr = (CORE_ADDR) malloc (len);
> +       write_memory (addr, value_contents_all (arg1), len);
> +       arg2 = value_from_pointer (lookup_pointer_type (type), addr);
>   
> +       return arg2;
> +     }
>     /* Get target memory address */
>     arg2 = value_from_pointer (lookup_pointer_type (value_type (arg1)),
>   			     (VALUE_ADDRESS (arg1)
> 

 
 Regards
 - Wu Zhou
 
 

^ permalink raw reply	[flat|nested] 23+ messages in thread

* RE: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-11-03 21:34       ` Mark Kettenis
  2005-11-04  3:15         ` Wu Zhou
@ 2005-11-04 11:20         ` Dave Korn
  2005-11-06 23:58           ` Daniel Jacobowitz
  1 sibling, 1 reply; 23+ messages in thread
From: Dave Korn @ 2005-11-04 11:20 UTC (permalink / raw)
  To: 'Mark Kettenis', woodzltc; +Cc: drow, gdb

Mark Kettenis wrote:
>> Date: Thu, 3 Nov 2005 11:14:51 +0800 (CST)
>> From: Wu Zhou <woodzltc@cn.ibm.com>
>> 
>> Maybe we can convert the argument to its pointer before we enter into
>> call_function_by_hand (evaluate_subexp_standard: case OP_FUNCALL)?
>> Normally what function you will use to allocate memory on the stack?  I
>> am not very familar with that kind of code.  Thanks!
> 
> Allocating memory on the stack is actually quite eazy.  Just
> substract/add the amount of space you need from/to the stack pointer,
> and use the new/old stack pointer as the address for the memory.
> Whether you should substract or add depends on whether the stack grows
> downward or upward.  Use gdbarch_inner_than(gdbarch, 1, 2) to check.
> There's quite a bit of code in infcall.c that uses this trick.
> 
> Mark


... but beware of the red zone on 64-bit x86, right .... ?

[e.g. see http://sources.redhat.com/ml/gdb-patches/2003-08/msg00092.html ]

    cheers,
      DaveK
-- 
Can't think of a witty .sigline today....

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-11-04 11:20         ` Dave Korn
@ 2005-11-06 23:58           ` Daniel Jacobowitz
  0 siblings, 0 replies; 23+ messages in thread
From: Daniel Jacobowitz @ 2005-11-06 23:58 UTC (permalink / raw)
  To: Dave Korn; +Cc: 'Mark Kettenis', woodzltc, gdb

On Fri, Nov 04, 2005 at 11:20:04AM -0000, Dave Korn wrote:
> ... but beware of the red zone on 64-bit x86, right .... ?
> 
> [e.g. see http://sources.redhat.com/ml/gdb-patches/2003-08/msg00092.html ]

Which is why this should be done inside the relevant bits of infcall
that already know about the redzone.

-- 
Daniel Jacobowitz
CodeSourcery, LLC

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-11-03  7:42     ` Jim Blandy
  2005-11-03 10:16       ` Wu Zhou
@ 2005-11-07  0:02       ` Daniel Jacobowitz
  2005-11-10  0:49         ` Jim Blandy
  1 sibling, 1 reply; 23+ messages in thread
From: Daniel Jacobowitz @ 2005-11-07  0:02 UTC (permalink / raw)
  To: Jim Blandy; +Cc: Mark Kettenis, woodzltc, gdb, fortran

On Wed, Nov 02, 2005 at 11:42:36PM -0800, Jim Blandy wrote:
> The types in the debug information should not reflect the extra level
> of indirection; the fact that they're passed by reference is just part
> of the meaning of a Fortran function call.  But the location
> expression should encode the extra level of indirection.

This seems perfectly sensible to me.  But the example Wu posted earlier
does not agree: today gfortran apparently puts out the indirections
explicitly.

Paul Brook had this to say when I asked him:
  When a user says "p foo" they should get the value, not the address of
  the argument.

So it sounds like gfortran will need to be fixed.

-- 
Daniel Jacobowitz
CodeSourcery, LLC

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-11-04  3:15         ` Wu Zhou
  2005-11-04  3:52           ` Wu Zhou
@ 2005-11-07  0:09           ` Daniel Jacobowitz
  2005-11-07  4:49             ` Wu Zhou
  2005-11-10  0:55             ` Jim Blandy
  1 sibling, 2 replies; 23+ messages in thread
From: Daniel Jacobowitz @ 2005-11-07  0:09 UTC (permalink / raw)
  To: Wu Zhou; +Cc: Mark Kettenis, gdb

On Fri, Nov 04, 2005 at 11:18:00AM +0800, Wu Zhou wrote:
> > Allocating memory on the stack is actually quite eazy.  Just
> > substract/add the amount of space you need from/to the stack pointer,
> > and use the new/old stack pointer as the address for the memory.
> > Whether you should substract or add depends on whether the stack grows
> > downward or upward.  Use gdbarch_inner_than(gdbarch, 1, 2) to check.
> > There's quite a bit of code in infcall.c that uses this trick.
> > 
> 
> Thanks.  I did some tests following this way.  But didn't get any success. 
> So I had to post here again to see if anybody can help me out.  
> 
> My basic idea is to create a value which hold the address to the original 
> argument. This is done in valur_addr for these argument which is not lval 
> and whose type is TYPE_CODE_INT.  Then I use the above method to get a new 
> value which hold the address to the original address.  Although it doesn't 
> report SEGV or "can not access memory" message, it didn't ouptut the 
> correct result I expected.  I expect 4 (which is 2 * 2), but it return 
> different number for me every time I run it.
> 
> Following is the changed I made to valur_arg_coerce and value_addr.  Could 
> anyone help me pointed out what is the reason why it fail.  Thanks a lot!

It's not quite as simple as Mark makes it out to be - in concept, sure,
but not in execution.  You have to _allocate_ the space on the stack;
not just find empty space off the side of the stack and write the
argument there.

By the type that we're calling value_arg_coerce, we've already
allocated some space on the stack, and saved the old stack pointer. 
But we'll allocate more space on the stack below, when we push
arguments.  And you have to be careful to keep the stack aligned
properly through all of this.  Read through the surrounding bits of
infcall.c to see how this works for struct returns; that is the closest
analogue we have today.

Maybe if you pass the sp value by reference to value_arg_coerce and
adjust it there...


-- 
Daniel Jacobowitz
CodeSourcery, LLC

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-11-07  0:09           ` Daniel Jacobowitz
@ 2005-11-07  4:49             ` Wu Zhou
  2005-11-07  5:01               ` Daniel Jacobowitz
  2005-11-10  0:55             ` Jim Blandy
  1 sibling, 1 reply; 23+ messages in thread
From: Wu Zhou @ 2005-11-07  4:49 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: Mark Kettenis, gdb

Hi Daniel,

On Sun, 6 Nov 2005, Daniel Jacobowitz wrote:

> On Fri, Nov 04, 2005 at 11:18:00AM +0800, Wu Zhou wrote:
> > > Allocating memory on the stack is actually quite eazy.  Just
> > > substract/add the amount of space you need from/to the stack pointer,
> > > and use the new/old stack pointer as the address for the memory.
> > > Whether you should substract or add depends on whether the stack grows
> > > downward or upward.  Use gdbarch_inner_than(gdbarch, 1, 2) to check.
> > > There's quite a bit of code in infcall.c that uses this trick.
> > > 
> > 
> > Thanks.  I did some tests following this way.  But didn't get any success. 
> > So I had to post here again to see if anybody can help me out.  
> > 
> > My basic idea is to create a value which hold the address to the original 
> > argument. This is done in valur_addr for these argument which is not lval 
> > and whose type is TYPE_CODE_INT.  Then I use the above method to get a new 
> > value which hold the address to the original address.  Although it doesn't 
> > report SEGV or "can not access memory" message, it didn't ouptut the 
> > correct result I expected.  I expect 4 (which is 2 * 2), but it return 
> > different number for me every time I run it.
> > 
> > Following is the changed I made to valur_arg_coerce and value_addr.  Could 
> > anyone help me pointed out what is the reason why it fail.  Thanks a lot!
> 
> It's not quite as simple as Mark makes it out to be - in concept, sure,
> but not in execution.  You have to _allocate_ the space on the stack;
> not just find empty space off the side of the stack and write the
> argument there.
> 
> By the type that we're calling value_arg_coerce, we've already
> allocated some space on the stack, and saved the old stack pointer. 
> But we'll allocate more space on the stack below, when we push
> arguments.  And you have to be careful to keep the stack aligned
> properly through all of this.  Read through the surrounding bits of
> infcall.c to see how this works for struct returns; that is the closest
> analogue we have today.
> 
> Maybe if you pass the sp value by reference to value_arg_coerce and
> adjust it there...

You are quite right.  Following your pointer, I made another patch and it 
now passed with both g77 (3.4.4) and gfortran (4.0.1) on a x86 box.  I 
didn't consider the red zone in AMD64 architecture, so maybe it won't work 
on it.  I will try to find a chance to test it on other platform, such as 
ppc64 or any other platform I can get access to.

Appended is the patch.  Any comments and suggestion are highly 
appreciated!

Index: infcall.c
===================================================================
RCS file: /cvs/src/src/gdb/infcall.c,v
retrieving revision 1.73
diff -c -3 -p -r1.73 infcall.c
*** infcall.c	2 Sep 2005 19:02:44 -0000	1.73
--- infcall.c	7 Nov 2005 04:36:39 -0000
*************** Unwinding of stack if a signal is receiv
*** 100,106 ****
  
  static struct value *
  value_arg_coerce (struct value *arg, struct type *param_type,
! 		  int is_prototyped)
  {
    struct type *arg_type = check_typedef (value_type (arg));
    struct type *type
--- 100,106 ----
  
  static struct value *
  value_arg_coerce (struct value *arg, struct type *param_type,
! 		  int is_prototyped, CORE_ADDR *sp)
  {
    struct type *arg_type = check_typedef (value_type (arg));
    struct type *type
*************** value_arg_coerce (struct value *arg, str
*** 109,118 ****
    switch (TYPE_CODE (type))
      {
      case TYPE_CODE_REF:
        if (TYPE_CODE (arg_type) != TYPE_CODE_REF
  	  && TYPE_CODE (arg_type) != TYPE_CODE_PTR)
  	{
! 	  arg = value_addr (arg);
  	  deprecated_set_value_type (arg, param_type);
  	  return arg;
  	}
--- 109,119 ----
    switch (TYPE_CODE (type))
      {
      case TYPE_CODE_REF:
+     case TYPE_CODE_PTR:
        if (TYPE_CODE (arg_type) != TYPE_CODE_REF
  	  && TYPE_CODE (arg_type) != TYPE_CODE_PTR)
  	{
! 	  arg = value_addr_stack (arg, sp);
  	  deprecated_set_value_type (arg, param_type);
  	  return arg;
  	}
*************** value_arg_coerce (struct value *arg, str
*** 154,160 ****
  	  type = lookup_pointer_type (TYPE_TARGET_TYPE (type));
        break;
      case TYPE_CODE_UNDEF:
-     case TYPE_CODE_PTR:
      case TYPE_CODE_STRUCT:
      case TYPE_CODE_UNION:
      case TYPE_CODE_VOID:
--- 155,160 ----
*************** call_function_by_hand (struct value *fun
*** 528,534 ****
  	else
  	  param_type = NULL;
  	
! 	args[i] = value_arg_coerce (args[i], param_type, prototyped);
  
  	/* elz: this code is to handle the case in which the function
  	   to be called has a pointer to function as parameter and the
--- 528,534 ----
  	else
  	  param_type = NULL;
  	
! 	args[i] = value_arg_coerce (args[i], param_type, prototyped, &sp);
  
  	/* elz: this code is to handle the case in which the function
  	   to be called has a pointer to function as parameter and the
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.161
diff -c -3 -p -r1.161 valops.c
*** valops.c	27 May 2005 04:39:32 -0000	1.161
--- valops.c	7 Nov 2005 04:36:47 -0000
*************** value_addr (struct value *arg1)
*** 886,891 ****
--- 886,963 ----
    return arg2;
  }
  
+ /* Mostly the same as value_addr.  But when the argument passed is a constant
+    and the value is not a lval, we allocate a block of memory for that value
+    on the stack and return the value which contains that address.  This is 
+    only used for value_arg_coerce at this time.  */
+ 
+ struct value *
+ value_addr_stack (struct value *arg1, CORE_ADDR *sp)
+ {
+   struct value *arg2;
+ 
+   struct type *type = check_typedef (value_type (arg1));
+   if (TYPE_CODE (type) == TYPE_CODE_REF)
+     {
+       /* Copy the value, but change the type from (T&) to (T*).
+          We keep the same location information, which is efficient,
+          and allows &(&X) to get the location containing the reference. */
+       arg2 = value_copy (arg1);
+       deprecated_set_value_type (arg2, lookup_pointer_type (TYPE_TARGET_TYPE (type)));
+       return arg2;
+     }
+   if (TYPE_CODE (type) == TYPE_CODE_FUNC)
+     return value_coerce_function (arg1);
+ 
+   if (TYPE_CODE (type) == TYPE_CODE_INT  && VALUE_LVAL (arg1) == not_lval)
+     {
+       int len = TYPE_LENGTH (type);
+       CORE_ADDR addr;
+ 
+       if (gdbarch_frame_align_p (current_gdbarch))
+ 	*sp = gdbarch_frame_align (current_gdbarch, *sp);
+       if (INNER_THAN (1, 2))
+ 	{
+ 	  /* stack grows downward */
+ 	  if (gdbarch_frame_align_p (current_gdbarch))
+ 	    *sp = gdbarch_frame_align (current_gdbarch, *sp - len);
+ 	  else
+ 	    *sp -= len;
+ 	  /* ... so the address of the thing we push is the
+ 	     stack pointer after we push it.  */
+ 	  addr = *sp;
+ 	}
+       else
+ 	{
+ 	  /* The stack grows up, so the address of the thing
+ 	     we push is the stack pointer before we push it.  */
+ 	  addr = *sp;
+ 	  if (gdbarch_frame_align_p (current_gdbarch))
+ 	    *sp = gdbarch_frame_align (current_gdbarch, *sp + len);
+ 	  else
+ 	    *sp += len;
+ 	}
+ 
+       write_memory (addr, value_contents_all (arg1), len);
+       arg2 = value_from_pointer (lookup_pointer_type (type), addr);
+ 
+       return arg2;
+     }
+ 
+   /* Get target memory address */
+   arg2 = value_from_pointer (lookup_pointer_type (value_type (arg1)),
+ 			     (VALUE_ADDRESS (arg1)
+ 			      + value_offset (arg1)
+ 			      + value_embedded_offset (arg1)));
+ 
+   /* This may be a pointer to a base subobject; so remember the
+      full derived object's type ... */
+   arg2 = value_change_enclosing_type (arg2, lookup_pointer_type (value_enclosing_type (arg1)));
+   /* ... and also the relative position of the subobject in the full object */
+   set_value_pointed_to_offset (arg2, value_embedded_offset (arg1));
+   return arg2;
+ }
+ 
  /* Given a value of a pointer type, apply the C unary * operator to it.  */
  
  struct value *

Regards
- Wu Zhou

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-11-07  4:49             ` Wu Zhou
@ 2005-11-07  5:01               ` Daniel Jacobowitz
  2005-11-07  5:16                 ` Wu Zhou
  0 siblings, 1 reply; 23+ messages in thread
From: Daniel Jacobowitz @ 2005-11-07  5:01 UTC (permalink / raw)
  To: Wu Zhou; +Cc: Mark Kettenis, gdb

On Mon, Nov 07, 2005 at 12:51:59PM +0800, Wu Zhou wrote:
> You are quite right.  Following your pointer, I made another patch and it 
> now passed with both g77 (3.4.4) and gfortran (4.0.1) on a x86 box.  I 
> didn't consider the red zone in AMD64 architecture, so maybe it won't work 
> on it.  I will try to find a chance to test it on other platform, such as 
> ppc64 or any other platform I can get access to.
> 
> Appended is the patch.  Any comments and suggestion are highly 
> appreciated!

Just to be clear: the patch is _not_ acceptable as is.  We need to
decide what gfortran's debugging information should look like, and how
the transformation should be controlled by language.  Casting an
integer to a pointer by pushing it to the stack this way is not the
correct behavior for any other language.

But thanks for testing my suggestion; the general approach looks sound,
once we figure out how to integrate it.

-- 
Daniel Jacobowitz
CodeSourcery, LLC

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-11-07  5:01               ` Daniel Jacobowitz
@ 2005-11-07  5:16                 ` Wu Zhou
  0 siblings, 0 replies; 23+ messages in thread
From: Wu Zhou @ 2005-11-07  5:16 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: Mark Kettenis, gdb



On Mon, 7 Nov 2005, Daniel Jacobowitz wrote:

> On Mon, Nov 07, 2005 at 12:51:59PM +0800, Wu Zhou wrote:
> > You are quite right.  Following your pointer, I made another patch and it 
> > now passed with both g77 (3.4.4) and gfortran (4.0.1) on a x86 box.  I 
> > didn't consider the red zone in AMD64 architecture, so maybe it won't work 
> > on it.  I will try to find a chance to test it on other platform, such as 
> > ppc64 or any other platform I can get access to.
> > 
> > Appended is the patch.  Any comments and suggestion are highly 
> > appreciated!
> 
> Just to be clear: the patch is _not_ acceptable as is.  We need to
> decide what gfortran's debugging information should look like, and how
> the transformation should be controlled by language.  Casting an
> integer to a pointer by pushing it to the stack this way is not the
> correct behavior for any other language.

That is okay.  I am very happy to know how gfortran should handle this 
kind of case.  Will you talk with gfortran guys on this?  If possible, 
would you please include me in the cc-list of your correspondence?  That 
will be highly appreciated.
 
Regards
- Wu Zhou

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-11-07  0:02       ` Daniel Jacobowitz
@ 2005-11-10  0:49         ` Jim Blandy
  2005-11-10  1:00           ` Daniel Jacobowitz
  0 siblings, 1 reply; 23+ messages in thread
From: Jim Blandy @ 2005-11-10  0:49 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: woodzltc, gdb, fortran


Daniel Jacobowitz <drow@false.org> writes:
> On Wed, Nov 02, 2005 at 11:42:36PM -0800, Jim Blandy wrote:
>> The types in the debug information should not reflect the extra level
>> of indirection; the fact that they're passed by reference is just part
>> of the meaning of a Fortran function call.  But the location
>> expression should encode the extra level of indirection.
>
> This seems perfectly sensible to me.  But the example Wu posted earlier
> does not agree: today gfortran apparently puts out the indirections
> explicitly.

You're talking about this, where 'm' is declared as 'integer', right?

 <1><da>: Abbrev Number: 7 (DW_TAG_subprogram)
     DW_AT_sibling     : <10f>
     DW_AT_external    : 1
     DW_AT_name        : res_
     DW_AT_decl_file   : 1
     DW_AT_decl_line   : 23
     DW_AT_type        : <bb>
     DW_AT_low_pc      : 0x804863f
     DW_AT_high_pc     : 0x8048655
     DW_AT_frame_base  : 1 byte block: 55       (DW_OP_reg5)
 <2><f5>: Abbrev Number: 8 (DW_TAG_formal_parameter)
     DW_AT_name        : m
     DW_AT_type        : <10f>   =====> This is a const pointer to integer
     DW_AT_artificial  : 1
     DW_AT_location    : 2 byte block: 91 8     (DW_OP_fbreg: 8)

 <1><10f>: Abbrev Number: 9 (DW_TAG_const_type)
     DW_AT_type        : <114>
 <1><114>: Abbrev Number: 10 (DW_TAG_pointer_type)
     DW_AT_byte_size   : 4
     DW_AT_type        : <bb>
 <1><bb>: Abbrev Number: 6 (DW_TAG_base_type)
     DW_AT_name        : integer
     DW_AT_byte_size   : 4
     DW_AT_encoding    : 5      (signed)

> So it sounds like gfortran will need to be fixed.

Yep.  The types in the Dwarf information should match the types as
they appear in the source language.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-11-07  0:09           ` Daniel Jacobowitz
  2005-11-07  4:49             ` Wu Zhou
@ 2005-11-10  0:55             ` Jim Blandy
  2005-11-10  0:59               ` Daniel Jacobowitz
  1 sibling, 1 reply; 23+ messages in thread
From: Jim Blandy @ 2005-11-10  0:55 UTC (permalink / raw)
  To: Wu Zhou; +Cc: Mark Kettenis, gdb


Daniel Jacobowitz <drow@false.org> writes:
> Maybe if you pass the sp value by reference to value_arg_coerce and
> adjust it there...

Or you could pass a regcache.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-11-10  0:55             ` Jim Blandy
@ 2005-11-10  0:59               ` Daniel Jacobowitz
  2005-11-11  9:59                 ` Jim Blandy
  0 siblings, 1 reply; 23+ messages in thread
From: Daniel Jacobowitz @ 2005-11-10  0:59 UTC (permalink / raw)
  To: Jim Blandy; +Cc: Wu Zhou, Mark Kettenis, gdb

On Wed, Nov 09, 2005 at 04:55:27PM -0800, Jim Blandy wrote:
> 
> Daniel Jacobowitz <drow@false.org> writes:
> > Maybe if you pass the sp value by reference to value_arg_coerce and
> > adjust it there...
> 
> Or you could pass a regcache.

We're not trying to adjust the saved sp in the regcache, but the
interim SP being used in setting up the function - it's not in the
regcache until much later (after push_dummy_call).

-- 
Daniel Jacobowitz
CodeSourcery, LLC

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-11-10  0:49         ` Jim Blandy
@ 2005-11-10  1:00           ` Daniel Jacobowitz
  0 siblings, 0 replies; 23+ messages in thread
From: Daniel Jacobowitz @ 2005-11-10  1:00 UTC (permalink / raw)
  To: Jim Blandy; +Cc: Mark Kettenis, woodzltc, gdb, fortran

On Wed, Nov 09, 2005 at 04:49:09PM -0800, Jim Blandy wrote:
> 
> Daniel Jacobowitz <drow@false.org> writes:
> > On Wed, Nov 02, 2005 at 11:42:36PM -0800, Jim Blandy wrote:
> >> The types in the debug information should not reflect the extra level
> >> of indirection; the fact that they're passed by reference is just part
> >> of the meaning of a Fortran function call.  But the location
> >> expression should encode the extra level of indirection.
> >
> > This seems perfectly sensible to me.  But the example Wu posted earlier
> > does not agree: today gfortran apparently puts out the indirections
> > explicitly.
> 
> You're talking about this, where 'm' is declared as 'integer', right?

Yes, that's what I meant.

-- 
Daniel Jacobowitz
CodeSourcery, LLC

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion?
  2005-11-10  0:59               ` Daniel Jacobowitz
@ 2005-11-11  9:59                 ` Jim Blandy
  0 siblings, 0 replies; 23+ messages in thread
From: Jim Blandy @ 2005-11-11  9:59 UTC (permalink / raw)
  To: Wu Zhou; +Cc: Mark Kettenis, gdb


Daniel Jacobowitz <drow@false.org> writes:
> On Wed, Nov 09, 2005 at 04:55:27PM -0800, Jim Blandy wrote:
>> 
>> Daniel Jacobowitz <drow@false.org> writes:
>> > Maybe if you pass the sp value by reference to value_arg_coerce and
>> > adjust it there...
>> 
>> Or you could pass a regcache.
>
> We're not trying to adjust the saved sp in the regcache, but the
> interim SP being used in setting up the function - it's not in the
> regcache until much later (after push_dummy_call).

My thought was that a language-specific value_arg_coerce might need to
do all manner of strange things, perhaps affecting other registers.
It's really all of infcall.c that is C-specific.  But I may be getting
ahead of myself.

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2005-11-11  9:59 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-08-22 10:14 [GDB & Fortran] Anyone has success experience with printing the result of Fortran function calls? Wu Zhou
2005-11-02  2:39 ` The root cause for SEGV in evaluating fortran function call, any solution or suggestion? Wu Zhou
2005-11-02 14:53   ` Daniel Jacobowitz
2005-11-03  3:12     ` Wu Zhou
2005-11-03 21:34       ` Mark Kettenis
2005-11-04  3:15         ` Wu Zhou
2005-11-04  3:52           ` Wu Zhou
2005-11-07  0:09           ` Daniel Jacobowitz
2005-11-07  4:49             ` Wu Zhou
2005-11-07  5:01               ` Daniel Jacobowitz
2005-11-07  5:16                 ` Wu Zhou
2005-11-10  0:55             ` Jim Blandy
2005-11-10  0:59               ` Daniel Jacobowitz
2005-11-11  9:59                 ` Jim Blandy
2005-11-04 11:20         ` Dave Korn
2005-11-06 23:58           ` Daniel Jacobowitz
2005-11-02 15:51   ` Mark Kettenis
2005-11-03  2:50     ` Wu Zhou
2005-11-03  7:42     ` Jim Blandy
2005-11-03 10:16       ` Wu Zhou
2005-11-07  0:02       ` Daniel Jacobowitz
2005-11-10  0:49         ` Jim Blandy
2005-11-10  1:00           ` Daniel Jacobowitz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).