From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30176 invoked by alias); 19 Jan 2011 23:26:44 -0000 Received: (qmail 30162 invoked by uid 22791); 19 Jan 2011 23:26:43 -0000 X-SWARE-Spam-Status: No, hits=-6.8 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 19 Jan 2011 23:26:39 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id p0JNQbaX008537 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 19 Jan 2011 18:26:37 -0500 Received: from mesquite.lan (ovpn-113-42.phx2.redhat.com [10.3.113.42]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p0JNQaxi021089 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for ; Wed, 19 Jan 2011 18:26:37 -0500 Date: Wed, 19 Jan 2011 23:56:00 -0000 From: Kevin Buettner To: gdb-patches@sourceware.org Subject: [RFC] Fix variable lifetime related problem in gdb.base/store.exp Message-ID: <20110119162636.092db33a@mesquite.lan> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-01/txt/msg00421.txt.bz2 I'm seeing some interesting failures in gdb.base/store.exp for mips64vrel-elf with --target_board set to vr4300-sim. (The exact target_board setting isn't all that critical; vr4300-sim is but one example where things go awry.) Here is relevant log file output showing the problem: tbreak add_float Temporary breakpoint 15 at 0xa0100414: file /ironwood1/sourceware-clean/mips64vrel-elf/../src/gdb/testsuite/gdb.base/store.c, line 47. (gdb) PASS: gdb.base/store.exp: tbreak add_float continue Continuing. Temporary breakpoint 15, add_float (u=-1, v=-2) at /ironwood1/sourceware-clean/mips64vrel-elf/../src/gdb/testsuite/gdb.base/store.c:47 47 return u + v; (gdb) PASS: gdb.base/store.exp: continue to add_float up #1 0xa010072c in wack_float (u=-1, v=-2) at /ironwood1/sourceware-clean/mips64vrel-elf/../src/gdb/testsuite/gdb.base/store.c:110 110 l = add_float (l, r); (gdb) PASS: gdb.base/store.exp: upvar float l; up print l $48 = -1.21996474e-19 (gdb) FAIL: gdb.base/store.exp: upvar float l; print old l, expecting -1 print r $49 = -2 (gdb) PASS: gdb.base/store.exp: upvar float l; print old r, expecting -2 set variable l = 4 (gdb) PASS: gdb.base/store.exp: upvar float l; set l to 4 print l No symbol "l" in current context. (gdb) FAIL: gdb.base/store.exp: upvar float l; print new l, expecting 4 tbreak add_double Temporary breakpoint 16 at 0xa0100454: file /ironwood1/sourceware-clean/mips64vrel-elf/../src/gdb/testsuite/gdb.base/store.c, line 53. (gdb) PASS: gdb.base/store.exp: tbreak add_double continue Continuing. mips-core: 4 byte read to unmapped address 0x40800000 at 0x40800000 Program received signal SIGBUS, Bus error. 0x40800000 in ?? () (gdb) FAIL: gdb.base/store.exp: continue to add_double These failures occur due to `l' in wack_float() being assigned (for this particular MIPS toolchain) to the `ra' (return address) register. The function wack_float() is defined as follows: float wack_float (register float u, register float v) { register float l = u, r = v; l = add_float (l, r); return l + r; } The test case places a breakpoint in add_float(), runs to that breakpoint, and then goes up a frame to examine and modify certain variables. The lifetime of `l' with value obtained from `u' ends with invocation of add_float(). (More precisely, it ends as soon as l's value is copied to the argument register for the call to add_float().) The result of the add_float() call is placed in `l' when the call is finished. Thus it's perfectly acceptable (though a bit perverse) to put l's value in the ra register. (However, given that this is occurring at -O0, it is also very annoying that the user is unable to inspect l's pre-call value.) In any case, due to the fact that the lifetime of l-with-the-value-of-u ends once the call to add_float() is set up, the compiler is then free to use ra for other purposes which, of course, during a call, is used to temporarily hold the return address. This is why the test fails to print the old value of 'l'; the register to which it was assigned is now being used for another purpose, i.e, holding the return address. And, moreover, it explains the BUS error after the assignment: add_float() is a leaf function and, therefore, does not need to save ra on the stack. So it simply uses it as is not expecting it to be changed upon return. That BUS error is reponsible for many cascade failures later on. My fix, below, is to assign (via GDB's "set variable" command) to `r' instead of `l' since the lifetime of r's value set at the beginning of the function extends beyond the call to add_float(). The patch also causes 'r', instead of 'l', to be examined immediately after the assignment. It won't fix the initial failure with `l' apparently having the wrong value. I think this test ought to be preserved to remind us - should it fail - that although GCC's generated code might be correct, it is not as useful as it should be for debugging purposes. This fix does prevent the BUS error and the resulting cascade failures. Stopping the cascade failures is important because we can then determine if there are any real failures amidst the cascade. Comments? * gdb.base/store.exp (proc up_set): Set, and check, the variable `r' rather than `l' due to the fact that the lifetime for the pre-call value for `l' need not extend beyond the call of add_. Index: testsuite/gdb.base/store.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/store.exp,v retrieving revision 1.17 diff -u -p -r1.17 store.exp --- testsuite/gdb.base/store.exp 1 Jan 2011 15:33:43 -0000 1.17 +++ testsuite/gdb.base/store.exp 19 Jan 2011 22:22:38 -0000 @@ -95,10 +95,10 @@ proc up_set { t l r new } { "${prefix}; print old l, expecting ${l}" gdb_test "print r" " = ${r}" \ "${prefix}; print old r, expecting ${r}" - gdb_test_no_output "set variable l = 4" \ - "${prefix}; set l to 4" - gdb_test "print l" " = ${new}" \ - "${prefix}; print new l, expecting ${new}" + gdb_test_no_output "set variable r = 4" \ + "${prefix}; set r to 4" + gdb_test "print r" " = ${new}" \ + "${prefix}; print new r, expecting ${new}" } up_set "charest" "-1 .*" "-2 .*" "4 ..004."