|
From: Doug R. <df...@nl...> - 2004-03-05 20:26:35
|
On Friday 05 March 2004 18:28, Jeremy Fitzhardinge wrote:
> On Fri, 2004-03-05 at 06:28, Doug Rabson wrote:
> > I've definately fixed this one - this is debug information for the
> > C++ 'member function pointer' type.
>
> Actually I think it's just pointer to member, not member function.
> Anyway, I checked in a fix last night, which probably looks a lot
> like yours.
>
> What are your other changes to vg_stabs/vg_symtab2?
I have three main changes in the stabs parser:
Templates which look like, e.g. "typedef MacFileName : public
FileName<':'>" confuse the type parser. It sees the colon and thinks
its at the end of the type. The fix was to keep track of quotes.
Some output from old binutils (mainly 2.11.2 which appears in FreeBSD
4.6.2) seems to have bogus address values for some N_FUN entries which
confuses things. I detect the broken N_FUN entries and look up the
symbol value manually.
When parsing the N_SOL stabs fields (debug record for start of include
file), queue the N_SOL filename until after emitting the already
pending N_SLINE so that we can get the right value for the end of the
N_SLINE. This improves the line number accuracy in some cases.
There are two changes to vg_symtab2.c. The first ignores negative size
scope entries (which also seem to appear with buggy old binutils). The
second tries to be smarter when two line ranges overlap by taking the
larger region, not just the last one. This helps to ensure that there
are no holes in the line number coverage.
Patch below:
Index: vg_stabs.c
===================================================================
--- vg_stabs.c (.../trunk/coregrind/vg_stabs.c) (revision 305)
+++ vg_stabs.c (.../branches/dfr-merge/coregrind/vg_stabs.c) (revision
305)
@@ -669,20 +669,25 @@
case 'x': { /* reference to undefined type */
/* 'x' ('s' | 'u' | 'e') NAME ':' */
Int brac = 0; /* < > brackets in type */
+ Bool quote = False; /* ' ' string in type */
Char kind = *p++; /* get kind */
Char *name = p;
/* name is delimited by : except for :: within <> */
for(;;) {
- if (*p == '<')
- brac++;
- if (*p == '>')
- brac--;
- if (*p == ':') {
- if (brac && p[1] == ':')
- p += 1;
- else
- break;
+ if (*p == '\'')
+ quote = !quote;
+ if (!quote) {
+ if (*p == '<')
+ brac++;
+ if (*p == '>')
+ brac--;
+ if (*p == ':') {
+ if (brac && p[1] == ':')
+ p += 1;
+ else
+ break;
+ }
}
p++;
}
@@ -1160,8 +1165,9 @@
} func = { 0, 0, NULL, NULL, -1 };
struct {
Char *name;
+ Char *next;
Bool same;
- } file = { NULL, True };
+ } file = { NULL, NULL, True };
struct {
Int prev; /* prev line */
Int no; /* current line */
@@ -1336,13 +1342,23 @@
break;
case N_SOL: /* sub-source (include) file */
+ {
+ UChar *nm = string;
+ UInt len = VG_(strlen)(nm);
if (line.ovf != 0)
VG_(message)(Vg_UserMsg,
"Warning: file %s is very big (> 65535
lines) "
"Line numbers and annotation for this file
might "
"be wrong. Sorry",
file.name);
- /* FALLTHROUGH */
+ if (len > 0 && nm[len-1] != '/') {
+ file.next = VG_(addStr)(si, nm, -1);
+ if (debug)
+ VG_(printf)("new source: %s\n", file.name);
+ } else if (len == 0)
+ file.next = VG_(addStr)(si, "?1\0", -1);
+ }
+ break;
case N_SO: { /* new source file */
UChar *nm = string;
@@ -1353,6 +1369,10 @@
/* finish off previous line */
VG_(addLineInfo)(si, file.name, line.addr,
addr, line.no + line.ovf * LINENO_OVERFLOW, i);
+ if(file.next) {
+ file.name = file.next;
+ file.next = (Char *)0;
+ }
}
/* reset line state */
@@ -1385,6 +1405,10 @@
/* there was a previous */
VG_(addLineInfo)(si, file.name, line.addr,
addr, line.no + line.ovf * LINENO_OVERFLOW, i);
+ if(file.next) {
+ file.name = file.next;
+ file.next = (Char *)0;
+ }
}
line.addr = addr;
@@ -1446,7 +1470,10 @@
line.first = False;
/* end line at end of function */
- addr = func.start + st->n_value;
+ if (st->n_value > 0)
+ addr = func.start + st->n_value;
+ else
+ addr = line.addr;
if (debug)
VG_(printf)("ending func %s at %p\n", func.name, addr);
@@ -1455,6 +1482,15 @@
func.name = no_fn_name;
func.start = 0;
+ if (line.addr) {
+ VG_(addLineInfo)(si, file.name, line.addr,
+ addr, line.no + line.ovf * LINENO_OVERFLOW, i);
+ if(file.next) {
+ file.name = file.next;
+ file.next = (Char *)0;
+ }
+ line.addr = 0;
+ }
if (scope.addr != 0) {
/* finish any previous scope range */
VG_(addScopeInfo)(si, scope.addr, addr, scope.scope);
@@ -1481,7 +1517,26 @@
line.first = True;
/* line ends at start of next function */
- addr = si->offset + st->n_value;
+ if (st->n_value == 0) {
+ UInt j;
+ Char *name, *p;
+ p = VG_(strchr)(string, ':');
+ name = VG_(arena_malloc)(VG_AR_SYMTAB, p - string + 1);
+ memcpy(name, string, p - string);
+ name[p - string] = 0;
+ addr = 0;
+ for (j = 0; j < si->symtab_used; j++) {
+ if (0)
+ VG_(printf)("%p %s\n", si->symtab[j].addr, si->symtab[j].name);
+ if (0 == VG_(strcmp)(name, si->symtab[j].name)) {
+ addr = si->symtab[j].addr;
+ break;
+ }
+ }
+ VG_(arena_free)(VG_AR_SYMTAB, name);
+ } else {
+ addr = si->offset + st->n_value;
+ }
func.start = addr;
func.name = string;
@@ -1494,6 +1549,10 @@
if (line.addr) {
VG_(addLineInfo)(si, file.name, line.addr,
addr, line.no + line.ovf * LINENO_OVERFLOW, i);
+ if(file.next) {
+ file.name = file.next;
+ file.next = (Char *)0;
+ }
line.addr = 0;
}
Index: vg_symtab2.c
===================================================================
--- vg_symtab2.c (.../trunk/coregrind/vg_symtab2.c) (revision 305)
+++ vg_symtab2.c (.../branches/dfr-merge/coregrind/vg_symtab2.c)
(revision 305)
@@ -308,6 +308,13 @@
return;
}
+ /* Ignore negative-sized scopes */
+ if (this > next) {
+ if (debug)
+ VG_(printf)("ignoring negative-sized range, scope %p at %p\n", scope,
this);
+ return;
+ }
+
if (debug)
VG_(printf)("adding scope range %p-%p (size=%d) scope %p
(%d)\n",
this, next, next-this, scope, scope->depth);
@@ -668,6 +675,10 @@
/* If two adjacent entries overlap, truncate the first. */
for (i = 0; i < ((Int)si->loctab_used)-1; i++) {
vg_assert(si->loctab[i].size < 10000);
+ if(si->loctab[i].addr == si->loctab[i+1].addr
+ && si->loctab[i].size > si->loctab[i+1].size) {
+ SWAP(RiLoc,si->loctab[i],si->loctab[i+1]);
+ }
if (si->loctab[i].addr + si->loctab[i].size >
si->loctab[i+1].addr) {
/* Do this in signed int32 because the actual .size fields
are unsigned 16s. */
--
Doug Rabson Mail: df...@nl...
Phone: +44 20 8340 9918
|