From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5366 invoked by alias); 25 Oct 2011 17:43:51 -0000 Received: (qmail 5354 invoked by uid 22791); 25 Oct 2011 17:43:48 -0000 X-SWARE-Spam-Status: No, hits=-0.8 required=5.0 tests=AWL,BAYES_00,KAM_STOCKGEN,RCVD_NUMERIC_HELO,RP_MATCHES_RCVD,SPF_HELO_PASS,TW_FN X-Spam-Check-By: sourceware.org Received: from lo.gmane.org (HELO lo.gmane.org) (80.91.229.12) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 25 Oct 2011 17:43:33 +0000 Received: from list by lo.gmane.org with local (Exim 4.69) (envelope-from ) id 1RIl2A-0004vk-Ml for gdb-patches@sources.redhat.com; Tue, 25 Oct 2011 19:43:30 +0200 Received: from 209.226.137.108 ([209.226.137.108]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Tue, 25 Oct 2011 19:43:30 +0200 Received: from aristovski by 209.226.137.108 with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Tue, 25 Oct 2011 19:43:30 +0200 To: gdb-patches@sources.redhat.com From: Aleksandar Ristovski Subject: [patch] Workaround gcc bug 49906 Date: Tue, 25 Oct 2011 18:12:00 -0000 Message-ID: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------050005010800010605000802" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:7.0.1) Gecko/20110929 Thunderbird/7.0.1 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-10/txt/msg00668.txt.bz2 This is a multi-part message in MIME format. --------------050005010800010605000802 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1490 Hello, Apparently gcc has quite a bit of issues generating proper line information. One of particularly harmful ones are described in gcc bug 49906. While on x86 they appear to be benign (save the odd line where breakpoint ends up being set), on arm it may cause gdb to not be able to step into such function (when software single stepping) or, worse even, breakpoint set on such function using "break " syntax may be set on non reachable instruction thus never being hit. The patch attached addresses this issue by performing further sanity checking and discarding results of skipping over prologue if there is any suspicion that the line information may be bogus/invalid/buggy. In addition to the patch, I'm attaching new test. Full regression test shows no regressions (that is, the new test FAILs on current code, and passes with the patch). Thanks, Aleksandar Ristovski QNX Software Systems gdb/ChangeLog: 2011-10-25 Aleksandar Ristovski * symtab.c (skip_prologue_sal): Introduced start_sal_orig to keep entry value. Added check for line after the prologue. If line information for the next line exists but appears to be before in the code, discard skip over prologue work and revert original sal. gdb/testsuite/ChangeLog: 2011-10-25 Aleksandar Ristovski * prologue-gccbug49906.exp: New test. * prologue.c (f_gccbuf49906): New function, call new function. --------------050005010800010605000802 Content-Type: text/x-patch; name="gccpr49906-workaround-lineinfo-HEAD-201110251328.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="gccpr49906-workaround-lineinfo-HEAD-201110251328.patch" Content-length: 2825 Index: gdb/symtab.c =================================================================== RCS file: /cvs/src/src/gdb/symtab.c,v retrieving revision 1.283 diff -u -p -r1.283 symtab.c --- gdb/symtab.c 21 Jul 2011 15:13:29 -0000 1.283 +++ gdb/symtab.c 25 Oct 2011 17:28:46 -0000 @@ -2474,6 +2474,7 @@ skip_prologue_sal (struct symtab_and_lin struct gdbarch *gdbarch; struct block *b, *function_block; int force_skip, skip; + const struct symtab_and_line start_sal_orig = *sal; /* Do not change the SAL is PC was specified explicitly. */ if (sal->explicit_pc) @@ -2627,6 +2628,29 @@ skip_prologue_sal (struct symtab_and_lin sal->line = SYMBOL_LINE (BLOCK_FUNCTION (function_block)); sal->symtab = SYMBOL_SYMTAB (BLOCK_FUNCTION (function_block)); } + else + { + /* Check if line number of apparent prologue end comes after + the next line information. If so, do not skip prologue + as something odd has happened. Probably gcc bug 49906. + Instead of giving awkward location for the function start, + give the previous good line (fuction start). */ + const struct symtab_and_line prologue_sal_next + = find_pc_line (sal->end, 0); + + if ((sym? (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= prologue_sal_next.end + && prologue_sal_next.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym))) + : (lookup_minimal_symbol_by_pc_section (prologue_sal_next.end, + section) + == lookup_minimal_symbol_by_pc_section (sal->pc, section))) + && prologue_sal_next.line != 0 + && prologue_sal_next.symtab == sal->symtab + && prologue_sal_next.line >= start_sal_orig.line + && prologue_sal_next.line < sal->line) + { + *sal = start_sal_orig; + } + } } /* If P is of the form "operator[ \t]+..." where `...' is @@ -4432,7 +4456,24 @@ skip_prologue_using_sal (struct gdbarch /* Assume that a consecutive SAL for the same (or larger) line mark the prologue -> body transition. */ if (sal.line >= prologue_sal.line) - break; + { + /* If the sal following SAL has line number lower than + SAL.LINE, then something is fishy. + Possibly gcc bug 49906 */ + const struct symtab_and_line prologue_sal_next + = find_pc_line (sal.end, 0); + + if (prologue_sal_next.end < end_pc + && prologue_sal_next.line != 0 + && prologue_sal_next.symtab == sal.symtab + && prologue_sal_next.line >= prologue_sal.line + && prologue_sal_next.line < sal.line) + /* Fishy: we have something past prologue that appears + in the source as before. Be conservative and return + start of the prologue. That's the best guess anyway. */ + prologue_sal.end = prologue_sal.pc; + break; + } /* The line number is smaller. Check that it's from the same function, not something inlined. If it's inlined, --------------050005010800010605000802 Content-Type: text/x-patch; name="gccpr49906-workaround-lineinfo-HEAD-test-201110251329.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="gccpr49906-workaround-lineinfo-HEAD-test-201110251329.patch" Content-length: 2817 Index: gdb/testsuite/gdb.base/prologue-gccbug49906.exp =================================================================== RCS file: gdb/testsuite/gdb.base/prologue-gccbug49906.exp diff -N gdb/testsuite/gdb.base/prologue-gccbug49906.exp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.base/prologue-gccbug49906.exp 25 Oct 2011 17:29:12 -0000 @@ -0,0 +1,45 @@ +# Test for prologue skipping in minimal symbols with line info when +# compiled with -O0. Test workaround gcc bug 49906. +# Copyright 2011 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 . + +set testfile "prologue" +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug optimize=-O0}] != "" } { + untested prologue.exp + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +if ![runto_main] then { + fail "Can't run to main" + return 0 +} + +set loc_end_of_prologue_workaround [gdb_get_line_number "end of prologue workaround"] +set loc_end_of_prologue_broken [gdb_get_line_number "end of prologue broken"] + +# Test less human-confusing breakpoint location in case weirdness is +# encountered. +gdb_test "break f_gccbug49906"\ + "Breakpoint.*at.*file.*$srcfile,.*line.*$loc_end_of_prologue_workaround\\."\ + "Workaround gcc bug 49906 worked" + Index: gdb/testsuite/gdb.base/prologue.c =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/prologue.c,v retrieving revision 1.6 diff -u -p -r1.6 prologue.c --- gdb/testsuite/gdb.base/prologue.c 1 Jan 2011 15:33:42 -0000 1.6 +++ gdb/testsuite/gdb.base/prologue.c 25 Oct 2011 17:29:12 -0000 @@ -16,6 +16,15 @@ along with this program. If not, see . */ + +static int i; +static void +f_gccbug49906 (void) +{ for (;;) /* end of prologue workaround - Weird style intended! */ + if (i++) + break; +} /* end of prologue broken */ + int leaf (void) { return 1; @@ -33,6 +42,7 @@ int main(void) { marker (0); marker (0); + f_gccbug49906 (); /* set breakpoint here */ return 0; } --------------050005010800010605000802--