From: Kevin Buettner <kevinb@cygnus.com>
To: gdb-patches@sources.redhat.com
Subject: [PATCH RFA] symtab.c: Handle functions with multiple #line directives
Date: Mon, 12 Mar 2001 23:36:00 -0000 [thread overview]
Message-ID: <1010313073600.ZM15069@ocotillo.lan> (raw)
The patch (way) below fixes a bug in find_pc_sect_line() which is most
evident when debugging a function which switches between two (or more)
source files multiple times via #line directives in the source. In
order to trigger the bug, it is critical that there be at least two
such transitions in a given function.
Now for some background...
Perl's xsubpp script is used to transform a source (.xs) file
containing a mix of C code and other statements into pure C code. In
the resulting C source code, #line directives are used to indicate
where the original C code from the .xs file was. It is common for
there to be several transitions back and forth between
xsubpp-generated code and the code that appeared in the .xs file.
Here is a small snippet of code taken from the generated "perl.c" from
another project that I occasionally work on:
XS(XS_Vile__Window_window_count)
{
dXSARGS;
dXSI32;
if (items != 0)
Perl_croak(aTHX_ "Usage: %s()", GvNAME(CvGV(cv)));
{
#line 4370 "perl.xs"
int count;
WINDOW *wp;
#line 3616 "perl.c"
int RETVAL;
dXSTARG;
#line 4374 "perl.xs"
count = 0;
for_each_visible_window(wp)
count++;
RETVAL = count;
#line 3625 "perl.c"
XSprePUSH; PUSHi((IV)RETVAL);
}
XSRETURN(1);
}
Again, the thing to notice here is that the xsubpp tool intermixes code
that it has generated with code taken from the .xs file. It marks each
transition with a #line directive. When debugging this code, the
programmer should be able to step from one line to the next. However,
at the moment, GDB is not very accomodating:
Breakpoint 1, XS_Vile__Window_window_count (cv=0x82014f8) at perl.c:3606
3606 dXSARGS;
(gdb) n
3607 dXSI32;
(gdb) n
3608 if (items != 0)
(gdb) n
3617 dXSTARG;
(gdb) n
3625 XSprePUSH; PUSHi((IV)RETVAL);
(gdb) n
3627 XSRETURN(1);
Note that GDB simply skipped over all the following statements:
count = 0;
for_each_visible_window(wp)
count++;
RETVAL = count;
When we debug the same function with the above mentioned symtab.c
patch, we see the following (correct) behavior:
Breakpoint 1, XS_Vile__Window_window_count (cv=0x82014f8) at perl.c:3606
3606 dXSARGS;
(gdb) n
3607 dXSI32;
(gdb)
3608 if (items != 0)
(gdb)
3617 dXSTARG;
(gdb)
4374 count = 0;
(gdb)
4375 for_each_visible_window(wp)
(gdb)
4376 count++;
(gdb)
4375 for_each_visible_window(wp)
(gdb)
4376 count++;
(gdb)
4375 for_each_visible_window(wp)
(gdb)
4377 RETVAL = count;
(gdb)
3625 XSprePUSH; PUSHi((IV)RETVAL);
(gdb)
3627 XSRETURN(1);
I have constructed a new test which I am proposing be added to the
GDB testsuite to test for this bug. The proposal is at:
http://sources.redhat.com/ml/gdb-patches/2001-03/msg00185.html
This test causes 12 new FAILs when run against a current GDB and
no fails when patched with the patch below.
I have tested the patch below on i386-unknown-freebsd4.2 and
i686-pc-linux-gnu and see no regressions. Also, as shown above,
it certainly produces better results when debugging real code.
Okay to commit?
* symtab.c (find_pc_sect_line): Revise method used for finding
the ending pc.
Index: symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.32
diff -u -p -r1.32 symtab.c
--- symtab.c 2001/03/06 08:21:17 1.32
+++ symtab.c 2001/03/10 08:22:11
@@ -1759,11 +1759,18 @@ find_pc_sect_line (CORE_ADDR pc, struct
{
best = prev;
best_symtab = s;
- /* If another line is in the linetable, and its PC is closer
- than the best_end we currently have, take it as best_end. */
- if (i < len && (best_end == 0 || best_end > item->pc))
- best_end = item->pc;
+
+ /* Discard BEST_END if it's before the PC of the current BEST. */
+ if (best_end <= best->pc)
+ best_end = 0;
}
+
+ /* If another line (denoted by ITEM) is in the linetable and its
+ PC is after BEST's PC, but before the current BEST_END, then
+ use ITEM's PC as the new best_end. */
+ if (best && i < len && item->pc > best->pc
+ && (best_end == 0 || best_end > item->pc))
+ best_end = item->pc;
}
if (!best_symtab)
next reply other threads:[~2001-03-12 23:36 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-03-12 23:36 Kevin Buettner [this message]
[not found] ` <15039.40587.784495.491390@kwikemart.cygnus.com>
[not found] ` <ezannoni@cygnus.com>
2001-03-26 17:21 ` Kevin Buettner
2001-05-08 16:02 ` [MAINT] xcoffread.c Kevin Buettner
2001-05-08 14:37 Elena Zannoni
2001-05-10 14:10 ` Elena Zannoni
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1010313073600.ZM15069@ocotillo.lan \
--to=kevinb@cygnus.com \
--cc=gdb-patches@sources.redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox