From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16126 invoked by alias); 23 Nov 2010 01:10:38 -0000 Received: (qmail 16117 invoked by uid 22791); 23 Nov 2010 01:10:37 -0000 X-SWARE-Spam-Status: No, hits=-2.1 required=5.0 tests=AWL,BAYES_00,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 23 Nov 2010 01:10:31 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 7E7832BABA5; Mon, 22 Nov 2010 20:10:29 -0500 (EST) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 3gnCOS2w0ZKJ; Mon, 22 Nov 2010 20:10:29 -0500 (EST) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 4A5EC2BABA4; Mon, 22 Nov 2010 20:10:29 -0500 (EST) Received: by joel.gnat.com (Postfix, from userid 1000) id 321F21457E1; Mon, 22 Nov 2010 17:10:26 -0800 (PST) From: Joel Brobecker To: gdb-patches@sourceware.org Cc: Joel Brobecker Subject: [RFA] unexpected multiple location for breakpoint Date: Tue, 23 Nov 2010 01:10:00 -0000 Message-Id: <1290474625-1582-1-git-send-email-brobecker@adacore.com> 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: 2010-11/txt/msg00333.txt.bz2 This is a proposed fix for the issue presented at: http://www.sourceware.org/ml/gdb/2010-11/msg00026.html. It changes the multiple-location filtering mechanism to use (block) contained_in rather than block equality to discard unwanted breakpoint locations. For instance, if the user tries to break on line "foo.adb:5" and the compiler generated 2 entries for that line, the second being inside a lexical block nested inside the lexical block associated to the first entry, then we should only break on the first line entry. gdb/ChangeLog: * symtab.c (expand_line_sal): Use contained_in rather than plain block equality to filter out duplicate sals. Tested on x86_64-linux. No regression. OK to commit? --- gdb/symtab.c | 22 +++++++++++++++++----- 1 files changed, 17 insertions(+), 5 deletions(-) diff --git a/gdb/symtab.c b/gdb/symtab.c index a6023b9..9eb3784 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -4633,7 +4633,8 @@ expand_line_sal (struct symtab_and_line sal) in two PC ranges. In this case, we don't want to set breakpoint on first PC of each range. To filter such cases, we use containing blocks -- for each PC found above we see if there are other PCs - that are in the same block. If yes, the other PCs are filtered out. */ + that are in the same or contained block. If yes, the other PCs + are filtered out. */ old_chain = save_current_program_space (); filter = alloca (ret.nelts * sizeof (int)); @@ -4648,12 +4649,23 @@ expand_line_sal (struct symtab_and_line sal) } do_cleanups (old_chain); - for (i = 0; i < ret.nelts; ++i) + /* To do the filtering of extraneous PCs, we go over all entries + in our list of PCs and see if its associated block is contained by + the block of another entry. If it is, then eliminate that contained + block. + + We start from last to first in our list of PCs, in order to take + care of the case where 2 entries are associated to the same block: + When we have one or more lines in the same block, we want to stop + at the first instruction of that line, hence we want to eliminate + the highest address. */ + + for (i = ret.nelts - 1; i >= 0; i--) if (blocks[i] != NULL) - for (j = i+1; j < ret.nelts; ++j) - if (blocks[j] == blocks[i]) + for (j = 0; j < ret.nelts; ++j) + if (j != i && filter[j] && contained_in (blocks[i], blocks[j])) { - filter[j] = 0; + filter[i] = 0; ++deleted; break; } -- 1.7.1