From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20260 invoked by alias); 9 Mar 2009 22:12:28 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 20205 invoked by uid 9674); 9 Mar 2009 22:12:27 -0000 Date: Mon, 09 Mar 2009 22:12:00 -0000 Message-ID: <20090309221227.20190.qmail@sourceware.org> From: jkratoch@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] archer: Merge commit 'origin/archer-jankratochvil-misc' into archer X-Git-Refname: refs/heads/archer X-Git-Reftype: branch X-Git-Oldrev: ec29855686f2a78d90ebcc63765681249bbbe808 X-Git-Newrev: a99e30d08ade4a2df0f943b036cd653bcd12b04d X-SW-Source: 2009-q1/txt/msg00293.txt.bz2 List-Id: The branch, archer has been updated via a99e30d08ade4a2df0f943b036cd653bcd12b04d (commit) via 6d9d76db272654e4d50af4f2403dfba0c2df7c19 (commit) from ec29855686f2a78d90ebcc63765681249bbbe808 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit a99e30d08ade4a2df0f943b036cd653bcd12b04d Merge: ec29855686f2a78d90ebcc63765681249bbbe808 6d9d76db272654e4d50af4f2403dfba0c2df7c19 Author: Jan Kratochvil Date: Mon Mar 9 23:11:43 2009 +0100 Merge commit 'origin/archer-jankratochvil-misc' into archer ----------------------------------------------------------------------- Summary of changes: gdb/breakpoint.c | 43 ++++++++++++--- gdb/testsuite/gdb.cp/expand-sals.cc | 53 ++++++++++++++++++ gdb/testsuite/gdb.cp/expand-sals.exp | 100 ++++++++++++++++++++++++++++++++++ 3 files changed, 188 insertions(+), 8 deletions(-) create mode 100644 gdb/testsuite/gdb.cp/expand-sals.cc create mode 100644 gdb/testsuite/gdb.cp/expand-sals.exp First 500 lines of diff: diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 38a17a1..531c43d 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -5482,7 +5482,6 @@ expand_line_sal_maybe (struct symtab_and_line sal) struct symtabs_and_lines expanded; CORE_ADDR original_pc = sal.pc; char *original_function = NULL; - int found; int i; /* If we have explicit pc, don't expand. @@ -5558,14 +5557,42 @@ expand_line_sal_maybe (struct symtab_and_line sal) if (original_pc) { - found = 0; + /* Find all the other PCs for a line of code with multiple instances + (locations). If the instruction is in the middle of an instruction + block for source line GDB cannot safely find the same instruction in + the other compiled instances of the same source line because the other + instances may have been compiled completely differently. + + The testcase gdb.cp/expand-sals.exp shows that breaking at the return + address in a caller of the current frame works for the current + instance but the breakpoint cannot catch the point (instruction) where + the callee returns in the other compiled instances of this source line. + + The current implementation will place the breakpoint at the expected + returning address of the current instance of the caller. But the + other instances will get the breakpoint at the first instruction of + the source line - therefore before the call would be made. Another + possibility would be to place the breakpoint in the other instances at + the start of the next source line. + + A possible heuristics would compare the instructions length of each of + the instances of the current source line and if it matches it would + place the breakpoint at the same offset. Unfortunately a mistaken + guess would possibly crash the inferior. */ + + CORE_ADDR best = -1; + + /* Find the nearest preceding PC and set it to ORIGINAL_PC. */ for (i = 0; i < expanded.nelts; ++i) - if (expanded.sals[i].pc == original_pc) - { - found = 1; - break; - } - gdb_assert (found); + if (expanded.sals[i].pc <= original_pc + && (best == -1 || expanded.sals[best].pc < expanded.sals[i].pc)) + best = i; + + if (best == -1) + error (_("Cannot find the best address for %s out of the %d locations"), + paddr (original_pc), expanded.nelts); + + expanded.sals[best].pc = original_pc; } return expanded; diff --git a/gdb/testsuite/gdb.cp/expand-sals.cc b/gdb/testsuite/gdb.cp/expand-sals.cc new file mode 100644 index 0000000..6169a05 --- /dev/null +++ b/gdb/testsuite/gdb.cp/expand-sals.cc @@ -0,0 +1,53 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright (C) 2009 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 3 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, see . */ + +int +func () +{ + return 42; /* func-line */ +} + +volatile int global_x; + +class A +{ +public: + A () + { + global_x = func (); /* caller-line */ + } +}; + +/* class B is here just to make the `func' calling line above having multiple + instances - multiple locations. Template cannot be used as its instances + would have different function names which get discarded by GDB + expand_line_sal_maybe. */ + +class B : public A +{ +}; + +int +main (void) +{ + A a; + B b; + + return 0; /* exit-line */ +} diff --git a/gdb/testsuite/gdb.cp/expand-sals.exp b/gdb/testsuite/gdb.cp/expand-sals.exp new file mode 100644 index 0000000..a2631fb --- /dev/null +++ b/gdb/testsuite/gdb.cp/expand-sals.exp @@ -0,0 +1,100 @@ +# Copyright 2009 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 3 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, see . + +if { [skip_cplus_tests] } { continue } + +set srcfile expand-sals.cc +if { [prepare_for_testing expand-sals.exp expand-sals $srcfile {debug c++}] } { + return -1 +} +if ![runto_main] { + return -1 +} + +gdb_breakpoint [gdb_get_line_number "exit-line"] + +gdb_breakpoint [gdb_get_line_number "func-line"] +gdb_continue_to_breakpoint "func" ".*func-line.*" + +gdb_test "up" "caller-line.*" + +# PC should not be at the boundary of source lines to make the original bug +# exploitable. + +set test "p/x \$pc" +set pc {} +gdb_test_multiple $test $test { + -re "\\$\[0-9\]+ = (0x\[0-9a-f\]+)\r\n$gdb_prompt $" { + set pc $expect_out(1,string) + pass $test + } +} + +set test "info line" +set end {} +gdb_test_multiple $test $test { + -re "Line \[0-9\]+ of .* starts at address 0x\[0-9a-f\]+.* and ends at (0x\[0-9a-f\]+).*\\.\r\n$gdb_prompt $" { + set end $expect_out(1,string) + pass $test + } +} + +set test "caller line has trailing code" +if {$pc != $end} { + pass $test +} else { + fail $test +} + +# Original problem was an internal error here. Still sanity multiple locations +# were found at this code place as otherwise this test would not test anything. +set test "break" +gdb_test_multiple $test $test { + -re "Breakpoint \[0-9\]+ at .*, line \[0-9\]+\\. \\(\[2-9\] locations\\)\r\n$gdb_prompt $" { + pass $test + } + -re "Breakpoint \[0-9\]+ at .*, line \[0-9\]+\\.\r\n$gdb_prompt $" { + # It just could not be decided if GDB is OK by this testcase. + setup_xfail *-*-* + fail $test + return 0 + } +} + +gdb_continue_to_breakpoint "caller" ".*caller-line.*" + +# Test GDB caught this return call and not the next one through B::B() +gdb_test "bt" \ + "#0 \[^\r\n\]* A \[^\r\n\]*\r\n#1 \[^\r\n\]* main \[^\r\n\]*" \ + "bt from A" + +gdb_continue_to_breakpoint "next caller instance" ".*caller-line.*" + +# Test that GDB caught now already A through B::B() in the other instance. +# As discussed in GDB expand_line_sal_maybe it would more match the original +# instance behavior to catch here the `func' breakpoint and catch the +# multiple-locations breakpoint only during the call return. This is not the +# case, expecting here to catch the breakpoint before the call happens. + +gdb_test "bt" \ + "#0 \[^\r\n\]* A \[^\r\n\]*\r\n#1 \[^\r\n\]* B \[^\r\n\]*\r\n#2 \[^\r\n\]* main \[^\r\n\]*" \ + "bt from B before the call" + +gdb_continue_to_breakpoint "next caller func" ".*func-line.*" + +# Verify GDB really could not catch the originally intended point of the return +# from func. + +gdb_continue_to_breakpoint "uncaught return" ".*exit-line.*" hooks/post-receive -- Repository for Project Archer.