This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
semantic error: multiple addresses for ...
- From: Roland McGrath <roland at redhat dot com>
- To: systemtap at sources dot redhat dot com
- Date: Fri, 20 Aug 2010 13:39:45 -0700 (PDT)
- Subject: semantic error: multiple addresses for ...
This error seems inherently wrong to me. Multiple matches is a feature,
not an error.
Take the attached source and script. I'm using gcc-4.4.4-10.fc13.x86_64,
but it probably doesn't matter much.
$ gcc -g -O1 -o ip1 implicitptr.c
$ ./run-stap implicitptr.stp ./ip1 -c ./ip1
semantic error: multiple addresses for implicitptr.c:27 (try implicitptr.c:26 or implicitptr.c:28)
semantic error: no match while resolving probe point process("/tmp/implicitptr-O1").statement("bar@*+4")
semantic error: libdw failure (dwarf_entrypc): no matching address range
semantic error: no match while resolving probe point process("/tmp/implicitptr-O1").statement("add@*+4")
semantic error: no match while resolving probe point process("/tmp/implicitptr-O1").statement("add@*+7")
Pass 2: analysis failed. Try again with another '--vp 01' option.
The line in question is in an inlined function (add) that is inlined twice
into the same caller (bar). The correct result is two probe locations, one
in each inlined instance.
Frank tells me this error diagnosis was intended for a case where a single
source line got its code spread out throughout the function so that there
would appear to be multiple probe locations for one semantic event. I have
not seen an example of this. IMHO, breaking the valid situations of one
source line authentically generating multiple different compiled code
locations that should be probed is far worse than failing to diagnose that
weirder case.
One possibility could be to use the is_stmt state of the line records here.
But in the absence of any of the examples that motivated the current (IMHO
wrong) behavior, it's hard to get very concrete on that.
Thanks,
Roland
int
foo (int i)
{
int *j = &i;
int **k = &j;
int ***l = &k;
i++;
return i;
}
struct S
{
int *x, y;
};
int u[6];
static inline void
add (struct S *a, struct S *b, int c)
{
*a->x += *b->x;
a->y += b->y;
u[c + 0]++;
a = (struct S *) 0;
u[c + 1]++;
a = b;
u[c + 2]++;
}
int
bar (int i)
{
int j = i;
struct S p[2] = { { &i, i * 2 }, { &j, j * 2 } };
add (&p[0], &p[1], 0);
p[0].x = &j;
p[1].x = &i;
add (&p[0], &p[1], 3);
return i + j;
}
int x = 22;
int
main (void)
{
x = foo (x);
x = bar (x);
return 0;
}
probe process(@1).statement("foo@*:7") /* at i++; */
{
printf("foo: %d %d %d %d\n",
$i, $j[0], $k[0][0], $l[0][0][0]);
newval = 99;
$i = newval;
printf("changed foo (%d): %d %d %d %d\n", newval,
$i, $j[0], $k[0][0], $l[0][0][0]);
}
probe process(@1).statement("bar@*+3"), /* before first add */
process(@1).statement("bar@*+4"), /* after first add */
process(@1).statement("bar@*+6") /* at the return stmt */
{
printf("p = { { &%d, %d }, { &%d, %d } }\n",
$p[0]->x[0], $p[0]->y, $p[1]->x[0], $p[1]->y);
}
probe process(@1).statement("add@*+4"),/* before a = 0 */
process(@1).statement("add@*+7") /* after a = b */
{
printf("*a->x=%d, a->y=%d, *b->x=%d, b->y=%d\n",
$a->x[0], $a->y, $b->x[0], $b->y);
}