|
From: Barrie W. <bw...@cs...> - 2004-01-16 17:57:38
|
Hi,
I wonder if anyone can shed some light on this for me.
I'm having problem whereby a program I have crashes when run under valgrind.
It has nested functions and it seems that the wrong function is being
called. I remember seeing in the archive that using
VALGRIND_DISCARD_TRANSLATIONS would help but, as I recall, it didn't seem to
say what the parameters should be or where in the code it should be placed,
and nothing I can seem to find tells me.
So that's the question: where does the VALGRIND_DISCARD_TRANSLATIONS go and
what are its parameters?
My program is very long but part of it looks vaguely like what's below.
Thanks
Barrie Walker
int fn_a()
{
GList *somelist = something();
// etc
void fn_aa()
{
// accesses fn_a's variables
}
void fn_ab()
{
// also accesses fn_a's variables and calls
fn_aa();
}
g_list_foreach(somelist, fn_ab, NULL);
}
int fn_b()
{
GList *somelist = something();
// etc
void fn_ba()
{
// accesses fn_b's variables
}
void fn_bb()
{
// also accesses fn_b's variables and calls
fn_ba();
}
g_list_foreach(somelist, fn_bb, NULL);
}
|
|
From: Jeremy F. <je...@go...> - 2004-01-16 18:53:48
|
On Fri, 2004-01-16 at 09:58, Barrie Walker wrote:
> Hi,
>
> I wonder if anyone can shed some light on this for me.
>
> I'm having problem whereby a program I have crashes when run under valgrind.
> It has nested functions and it seems that the wrong function is being
> called. I remember seeing in the archive that using
> VALGRIND_DISCARD_TRANSLATIONS would help but, as I recall, it didn't seem to
> say what the parameters should be or where in the code it should be placed,
> and nothing I can seem to find tells me.
>
> So that's the question: where does the VALGRIND_DISCARD_TRANSLATIONS go and
> what are its parameters?
It's tricky - it isn't the proper solution, but more a hack to get you
going. The trouble is that gcc generates a piece of code dynamically on
the stack when you call a nested function; for each call, it generates a
different piece of code. Valgrind sees this the first time, and
generates its own instrumented code, but if gcc later uses the same
stack location to generate code for a new call to a different function,
Valgrind won't notice, and use the old cached code.
Therefore, to use VALGRIND_DISCARD_TRANSLATIONS you need to guess the
location and size of the code which gcc is generating. Something like
this (before each call to a nested function) might work:
int myfunc()
{
int mynestedfunc() {
}
char local;
VALGRIND_DISCARD_TRANSLATIONS(&local-32, 128); // guessing
mynestedfunc();
}
It gets more complex if you're passing a pointer to mynestedfunc
elsewhere, and/or you use dynamically sized arrays or alloca(). &local
is basically a guess at the value of %esp - you could also use:
unsigned int esp;
asm volatile("mov %%esp,%0" : "=r" (esp));
VALGRIND_DISCARD_TRANSLATIONS(esp-32, 128); // guessing
The real fix is for Valgrind to cope with this automatically (bug
http://bugs.kde.org/show_bug.cgi?id=69511).
J
|