From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3255 invoked by alias); 4 Nov 2005 03:52:09 -0000 Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org Received: (qmail 3226 invoked by uid 22791); 4 Nov 2005 03:52:03 -0000 Received: from ausmtp01.au.ibm.com (HELO ausmtp01.au.ibm.com) (202.81.18.186) by sourceware.org (qpsmtpd/0.30-dev) with ESMTP; Fri, 04 Nov 2005 03:52:03 +0000 Received: from sd0208e0.au.ibm.com (d23rh904.au.ibm.com [202.81.18.202]) by ausmtp01.au.ibm.com (8.12.10/8.12.10) with ESMTP id jA43tBug156582 for ; Fri, 4 Nov 2005 14:55:11 +1100 Received: from d23av03.au.ibm.com (d23av03.au.ibm.com [9.190.250.244]) by sd0208e0.au.ibm.com (8.12.10/NCO/VERS6.7) with ESMTP id jA43t0bK176054 for ; Fri, 4 Nov 2005 14:55:00 +1100 Received: from d23av03.au.ibm.com (loopback [127.0.0.1]) by d23av03.au.ibm.com (8.12.11/8.13.3) with ESMTP id jA43pwvo032347 for ; Fri, 4 Nov 2005 14:51:59 +1100 Received: from [9.181.133.252] ([9.181.133.252]) by d23av03.au.ibm.com (8.12.11/8.12.11) with ESMTP id jA43pt7b032304; Fri, 4 Nov 2005 14:51:56 +1100 Date: Fri, 04 Nov 2005 03:52:00 -0000 From: Wu Zhou To: Mark Kettenis cc: drow@false.org, gdb@sources.redhat.com Subject: Re: The root cause for SEGV in evaluating fortran function call, any solution or suggestion? In-Reply-To: Message-ID: References: <20051102145258.GA28372@nevyn.them.org> <200511032134.jA3LYDsT017248@elgar.sibelius.xs4all.nl> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-SW-Source: 2005-11/txt/msg00088.txt.bz2 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 > > > > > > 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