From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31584 invoked by alias); 2 Dec 2004 05:24:30 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 31528 invoked from network); 2 Dec 2004 05:24:21 -0000 Received: from unknown (HELO arwen.tausq.org) (64.81.244.109) by sourceware.org with SMTP; 2 Dec 2004 05:24:21 -0000 Received: by arwen.tausq.org (Postfix, from userid 1000) id 2F87643810; Wed, 1 Dec 2004 21:24:18 -0800 (PST) Date: Thu, 02 Dec 2004 05:24:00 -0000 From: Randolph Chung To: Andrew Cagney Cc: gdb-patches@sources.redhat.com Subject: Re: [patch/RFA] multiarch INSTRUCTION_NULLIFIED Message-ID: <20041202052417.GM6359@tausq.org> Reply-To: Randolph Chung References: <20041129033013.GJ6359@tausq.org> <41AB3C1D.80509@gnu.org> <20041130065620.GT6359@tausq.org> <41AC88B2.5070501@gnu.org> <20041130164401.GV6359@tausq.org> <41ACA6BE.5080603@gnu.org> <20041130173841.GW6359@tausq.org> <41AE3759.3030503@gnu.org> <20041201223243.GK6359@tausq.org> <41AE5434.9050901@gnu.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <41AE5434.9050901@gnu.org> X-GPG: for GPG key, see http://www.tausq.org/gpg.txt User-Agent: Mutt/1.5.6+20040722i X-SW-Source: 2004-12/txt/msg00037.txt.bz2 > PPS: A gdb.arch/ addition to tickle the basic edge case would be a > helpful way of capturing this knowledge. how about this... my first gdb testcase, so hopefully i didn't do anything too wrong :) 74 PASSes, 3 FAILs with the old code (assuming the instruction_nullified logic is removed). 77 PASSes with my previous patch. randolph 2004-12-01 Randolph Chung * gdb.arch/pa-nullify.exp: New file. * gdb.arch/pa-nullify.c: New file. --- /dev/null 2004-08-25 14:59:25.000000000 -0700 +++ pa-nullify.exp 2004-12-01 21:21:13.451861856 -0800 @@ -0,0 +1,217 @@ +# Copyright 2004 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 is part of the gdb testsuite. + +# NOTE: this test is specific to how gcc generates code. In particular, we +# are testing for the case where the last insn of a function is a "bv,n r0(%rp)" +# and the insn in the delay slot of that branch belongs to the next function. + +if $tracelevel { + strace $tracelevel +} + +set prms_id 0 +set bug_id 0 + +# Test handling of nullified instructions for the pa target. + +if ![istarget "hppa*-*-*"] then { + verbose "Skipping hppa nullification tests." + return +} + +set testfile "pa-nullify" +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} +set gcorefile ${objdir}/${subdir}/${testfile}.gcore + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + unsupported "Testcase compile failed." + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +# In the first test, we do a "step" on a function whose last instruction +# contains a branch-with-nullify. The instruction in the delay slot belongs +# to the next function. We verify that when we step off the first function +# that we end up back at the caller and not at the second instruction. + +gdb_breakpoint foo +gdb_test "run" ".*Breakpoint 1, foo \\(x=1\\).*" "Breakpoint at foo" +gdb_test "step" ".*main \\(.*\\) at .*pa-nullify.c:30.*" "step back to main" + +# In the second test, we do a single step through each instruction of a function +# and verify that we get a proper backtrace, even when we are in a nullified +# instruction that belongs to the next function. We also verify that when +# stepping over a branch-with-nullify insn that we stay on the same insn for +# two steps. + +if { ! [ runto main ] } then { gdb_suppress_tests; } + +send_gdb "print foo\n" +gdb_expect { + -re ".* = {int \\(int\\)} ($hex) .*$gdb_prompt $" { + set baddr $expect_out(1,string) + verbose "Breakpoint address at $baddr" + pass "print foo = $baddr" + } + default { + fail "print foo" + gdb_suppress_tests + } timeout { + fail "cannot get address of foo (timed out)." + gdb_suppress_tests + } +} + +gdb_breakpoint "*$baddr" + +gdb_test "display /i \$pc" "1: x/i +\\\$pc.*" "display /i \$pc" +gdb_test "continue" ".*Breakpoint \[0-9\], foo \\(x=1\\) at .*pa-nullify.c:23.*" "break at first insn of foo" + +set done 0 +set iter 0 +while { $done == 0 && $iter < 20 } { + send_gdb "backtrace\n" + gdb_expect { + -re ".*foo \\(x=.*\\).* main \\(.*\\).*$gdb_prompt $" { + pass "backtrace from foo" + } + -re "$gdb_prompt $" { + fail "backtrace from foo" + gdb_suppress_tests + } + timeout { + fail "(timeout) backtrace from foo" + gdb_suppress_tests + } + } + + send_gdb "stepi\n" + gdb_expect { + -re ".*: x/i +\\\$pc.*:\[ \t\]+(.*)\r.*$gdb_prompt $" { + set insn $expect_out(1,string) + pass "x/i \$pc = $insn" + } timeout { + fail "(timeout) x/i \$pc" + gdb_suppress_tests + break + } + } + + incr iter + + if { $insn == "bv,n r0(rp)" } { + pass "found bv,n insn" + set done 1 + } +} + +send_gdb "stepi\n" +gdb_expect { + -re ".*bv,n r0\\(rp\\)\r.*$gdb_prompt $" { + pass "restep on nullified instruction" + } + -re ".*bar.*\r.*x/i.*bar.*\r.*$gdb_prompt $" { + fail "step on nullification instruction ended in next function" + } + timeout { + fail "(timeout) restep on nullified instruction" + } +} +incr iter + +# Lastly, we do a single step through each instruction and generate a core file. +# Then, load the core file and verify that we can get a proper backtrace. + +if ![isnative] then { + verbose "skipping core file tests on non-native configuration" + return +} + +send_gdb "undisplay 1\n" + +proc do_core_test { count } { + global gcorefile + global gdb_prompt + global hex + + if { ! [ runto_main ] } then { gdb_suppress_tests; } + + set baddr "0" + send_gdb "print foo\n" + gdb_expect { + -re ".* = {int \\(int\\)} ($hex) .*$gdb_prompt $" { + set baddr $expect_out(1,string) + verbose "Breakpoint address at $baddr" + pass "print foo = $baddr #$count" + } + default { + fail "print foo #$count" + gdb_suppress_tests + } + timeout { + fail "cannot get address of foo (timed out). #$count" + gdb_suppress_tests + } + } + gdb_breakpoint "*$baddr" + + gdb_test "continue" ".*Breakpoint \[0-9\]*, foo \\(x=1\\) at .*pa-nullify.c:23.*" "break at first insn of foo #$count" + + gdb_test "si $count" + + set gcore_works 0 + set escapedfilename [string_to_regexp $gcorefile] + gdb_test_multiple "gcore $gcorefile" "gcore" { + -re "Saved corefile ${escapedfilename}\[\r\n\]+$gdb_prompt $" { + pass "gcore #$count" + set gcore_works 1 + } + -re "Can't create a corefile\[\r\n\]+$gdb_prompt $" { + unsupported "gcore" + } + } + + if { $gcore_works } { + gdb_test "core $gcorefile" "Core was generated by.*" \ + "load core file #$count" "A program is being debugged already.*" "y" + + send_gdb "backtrace\n" + gdb_expect { + -re ".*foo \\(x=.*\\).* main \\(.*\\).*$gdb_prompt $" { + pass "backtrace from foo #$count" + } + -re "$gdb_prompt $" { + fail "backtrace from foo #$count" + gdb_suppress_tests + } + timeout { + fail "(timeout) backtrace from foo in gcore #$count" + gdb_suppress_tests + } + } + } +} + +for { set i 1 } { $i <= $iter } {incr i} { + do_core_test $i +} --- /dev/null 2004-08-25 14:59:25.000000000 -0700 +++ pa-nullify.c 2004-12-01 21:19:51.324347136 -0800 @@ -0,0 +1,30 @@ +/* PA nullification test program. + + Copyright 2004 Free Software Foundation, Inc. + + This file is part of GDB. + + 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. */ + +int foo(int x) +{ return x; } + +void bar(void) { } + +int main(int argc, char **argv) +{ + return foo(argc); +} -- Randolph Chung Debian GNU/Linux Developer, hppa/ia64 ports http://www.tausq.org/