From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10701 invoked by alias); 17 Mar 2009 10:24:46 -0000 Received: (qmail 10689 invoked by uid 22791); 17 Mar 2009 10:24:44 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_45 X-Spam-Check-By: sourceware.org Received: from outdoor.onevision.de (HELO outdoor.onevision.de) (212.77.172.51) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 17 Mar 2009 10:24:38 +0000 Received: from sanders.onevision.de (moonrace [212.77.172.62]) by outdoor.onevision.de (8.14.3/8.13.7/ROSCH/DDB) with ESMTP id n2HAOUEc026521 for ; Tue, 17 Mar 2009 11:24:35 +0100 In-Reply-To: <49B67300.1020503@onevision.de> To: gdb Cc: Roland Schwingel Subject: Re: gdb_assert when resetting breakpoints MIME-Version: 1.0 Message-ID: From: Kai Tietz Date: Tue, 17 Mar 2009 10:24:00 -0000 Content-Type: text/plain; charset="US-ASCII" X-IsSubscribed: yes Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2009-03/txt/msg00099.txt.bz2 gdb-owner@sourceware.org wrote on 10.03.2009 15:02:40: > Hi... > > When using current gdb cvs head sources I encounter a gdb_assert() in > breakpoint.c line 7451. > This is in function breakpoint_re_set_one(). > Let me tell you what I am doing to get it (reproduceably). I am not a > guru to gdb's internals so > please forgive me if I conclude something wrong. > > I am having a mixed C and Objective C application. I am running on > windows using GNUstep > for my ObjC Foundation classes. GNUstep-base is a shared library loaded > lazy. > Due to the nature of this bug I assume that this will also appear on > other platforms like linux > (according to my analysis). So it is not windows specific. > > I start gdb and set a breakpoint to main() using "b main". Then I run my > app using "r". > A few seconds later I get the assert in breakpoint.c:7451 > gdb_assert(sals.nelts==1). > When I debug into it sals.nelts == 2. The assert happens when the > gnustep-base shared > library was loaded. > > What has happenend: In breakpoint.c line 7417 you find: > sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0, (char ***) > NULL,not_found_ptr); > s points to "main" at that moment as found in the breakpoint structure > supplied to breakpoint_re_set_one(). > > sals (returned from decode_line_1) contains 2 entries. > Sals entry 0 points to the ObjectiveC METHOD main of the foundation base > class NSThread > (written in ObjC notation -[NSThread main]). This is a real ObjC > baseclass not something > from my own code. It has also nothing to do with an application's > entrypoint. It also perfectly > legal in ObjectiveC to name methods like C functions. They do not collide. > Sals entry 1 points to the function "main()" of my application. This is > the entry which I think is > the correct one to use here. > > Obviously decode_line_1 returns every symbol matching a certain string > independant of > its language. As far as I understand gdb at the moment this appears to > be ok. > > So what is the correct behaviour here to fix this problem? I assume that > there might be more > areas of symbol duplicates that can occur not only main() vs -[NSThread > main]. > > Maybe the assert should be replaced by a loop over the sals entries > matching the infos from the > breakpoint structure passed to breakpoint_re_set_one() and the > individual symtab entry of one > sals entry by filename(?) matching? > > Thanks in advance for your help, > > Roland > > Hi, I prepared a patch for this issue, which should solve the described problem of Roland. Changelog: 2009-03-17 Kai Tietz * breakpoint.c: take care about multiple breakpoints possibilities when resetting breakpoints. Is this patch ok for apply? Cheers, Kai | (\_/) This is Bunny. Copy and paste Bunny | (='.'=) into your signature to help him gain | (")_(") world domination. Patch: Index: src/gdb/breakpoint.c =================================================================== --- src.orig/gdb/breakpoint.c 2009-03-17 11:10:45.000000000 +0100 +++ src/gdb/breakpoint.c 2009-03-17 11:19:01.890880000 +0100 @@ -57,6 +57,7 @@ #include "top.h" #include "wrapper.h" #include "valprint.h" +#include "filenames.h" #include "mi/mi-common.h" @@ -7392,6 +7393,7 @@ struct breakpoint *b = (struct breakpoint *) bint; struct value *mark; int i; + int sals_index = -1; int not_found = 0; int *not_found_ptr = ¬_found; struct symtabs_and_lines sals = {}; @@ -7455,20 +7457,59 @@ if (not_found) break; - gdb_assert (sals.nelts == 1); - resolve_sal_pc (&sals.sals[0]); - if (b->condition_not_parsed && s && s[0]) + /* If only one sals entry is found use it directly + elsewise cycle over all sals and match breakpoint + against all returned sals by checking filenames and + linenumbers. */ + if (sals.nelts == 1) + sals_index = 0; + else + { + for (i=0;(i < sals.nelts) && (sals_index == -1);i++) + { + int symtab_linenum = sals.sals[i].line; + int bpoint_linenum = b->line_number; + + if (symtab_linenum == bpoint_linenum) + { + struct symtab *s = sals.sals[i].symtab; + + if (s) + { + const char *symtab_filename = s->filename; + const char *bpoint_filename = b->source_file; + + if (symtab_filename) + symtab_filename = lbasename(symtab_filename); + + if (bpoint_filename) + bpoint_filename = lbasename(bpoint_filename); + + if (bpoint_filename && symtab_filename + && (FILENAME_CMP(bpoint_filename,symtab_filename) + == 0)) + sals_index = i; + } + } + } + } + gdb_assert(sals_index != -1); + if (sals_index == -1) + break; + + resolve_sal_pc (&sals.sals[sals_index]); + if (b->condition_not_parsed && s && s[sals_index]) { char *cond_string = 0; int thread = -1; - find_condition_and_thread (s, sals.sals[0].pc, + find_condition_and_thread (s, sals.sals[sals_index].pc, &cond_string, &thread); if (cond_string) b->cond_string = cond_string; b->thread = thread; b->condition_not_parsed = 0; } - expanded = expand_line_sal_maybe (sals.sals[0]); + expanded = expand_line_sal_maybe (sals.sals[sals_index]); cleanups = make_cleanup (xfree, sals.sals); update_breakpoint_locations (b, expanded); do_cleanups (cleanups);