From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8216 invoked by alias); 16 May 2009 11:18:58 -0000 Received: (qmail 8207 invoked by uid 22791); 16 May 2009 11:18:57 -0000 X-SWARE-Spam-Status: No, hits=-0.3 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_32,J_CHICKENPOX_36,KAM_STOCKGEN,SPF_SOFTFAIL X-Spam-Check-By: sourceware.org Received: from mtaout7.012.net.il (HELO mtaout7.012.net.il) (84.95.2.19) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 16 May 2009 11:18:50 +0000 Received: from conversion-daemon.i-mtaout7.012.net.il by i-mtaout7.012.net.il (HyperSendmail v2007.08) id <0KJQ00K00HS3HO00@i-mtaout7.012.net.il> for gdb-patches@sourceware.org; Sat, 16 May 2009 14:18:38 +0300 (IDT) Received: from HOME-C4E4A596F7 ([84.228.73.80]) by i-mtaout7.012.net.il (HyperSendmail v2007.08) with ESMTPA id <0KJQ008J9I2YTPA0@i-mtaout7.012.net.il>; Sat, 16 May 2009 14:18:35 +0300 (IDT) Date: Sat, 16 May 2009 11:18:00 -0000 From: Eli Zaretskii Subject: Re: [RFA] Fix "break foo" when `foo's prologue ends before line table In-reply-to: <83tz3rxt4p.fsf@gnu.org> To: Joel Brobecker , Daniel Jacobowitz Cc: gdb-patches@sourceware.org Reply-to: Eli Zaretskii Message-id: <83eiupqos5.fsf@gnu.org> References: <83skjebbef.fsf@gnu.org> <20090511125644.GD14773@adacore.com> <83zldjxzzr.fsf@gnu.org> <20090511192709.GG14773@adacore.com> <83tz3rxt4p.fsf@gnu.org> 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: 2009-05/txt/msg00339.txt.bz2 > Date: Mon, 11 May 2009 23:49:10 +0300 > From: Eli Zaretskii > Cc: gdb-patches@sourceware.org > > > Date: Mon, 11 May 2009 21:27:09 +0200 > > From: Joel Brobecker > > Cc: gdb-patches@sourceware.org > > > > I'm always reluctant to introduce code I don't understand, and usually > > leave it out until I see a bug - that's why I was asking. Have you > > tried without this part? > > No, but I will. OK, I tried it, and it does work, at least in the 2 test cases I could try. Here's an updated patch, which incorporates the comments in this thread: . It uses a single symtab for the function's symbol . It stops looking as soon as it finds the first linetable entry whose PC is in the range of the function's PC values OK to commit? 2009-05-09 Eli Zaretskii * symtab.c (skip_prologue_using_lineinfo): New function. (find_function_start_sal): Use it to get to the first line of function's body that has an entry in the lineinfo table. --- symtab.c~0 2009-04-01 02:21:07.000000000 +0300 +++ symtab.c 2009-05-16 13:49:42.296906500 +0300 @@ -2599,6 +2599,46 @@ return pc; } +/* Given a function start address FUNC_ADDR and SYMTAB, find the first + address for that function that has an entry in SYMTAB's line info + table. If such an entry cannot be found, return FUNC_ADDR + unaltered. */ +CORE_ADDR +skip_prologue_using_lineinfo (CORE_ADDR func_addr, struct symtab *symtab) +{ + CORE_ADDR func_start, func_end; + struct linetable *l; + int ind, i, len; + int best_lineno = 0; + CORE_ADDR best_pc = func_addr; + + /* Get the range for the function's PC values, or give up if we + cannot, for some reason. */ + if (!find_pc_partial_function (func_addr, NULL, &func_start, &func_end)) + return func_addr; + + l = LINETABLE (symtab); + if (l == NULL) + return func_addr; + + /* Linetable entries are ordered by PC values, see the commentary in + symtab.h where `struct linetable' is defined. Thus, the first + entry whose PC is in the range [FUNC_START..FUNC_END] is the + address we are looking for. */ + for (i = 0; i < l->nitems; i++) + { + struct linetable_entry *item = &(l->item[i]); + + /* Don't use line numbers of zero, they mark special entries in + the table. See the commentary on symtab.h before the + definition of struct linetable. */ + if (item->line > 0 && func_start <= item->pc && item->pc <= func_end) + return item->pc; + } + + return func_addr; +} + /* Given a function symbol SYM, find the symtab and line for the start of the function. If the argument FUNFIRSTLINE is nonzero, we want the first line @@ -2649,6 +2689,15 @@ sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0); } + /* If we still don't have a valid source line, try to find the first + PC in the lineinfo table that belongs to the same function. */ + if (funfirstline && sal.symtab == NULL) + { + pc = skip_prologue_using_lineinfo (pc, SYMBOL_SYMTAB (sym)); + /* Recalculate the line number. */ + sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0); + } + sal.pc = pc; return sal;