|
From: Lee K. <lki...@cs...> - 2003-11-18 16:10:16
Attachments:
hmmlk.c
verbose.txt
|
Hi, The attached test case results in different output when run under Valgrind (version 2.0 & 1.9.6) compared to when it is run stand-alone. This source makes use of nested functions. The following is output when run normally: % ./hmmlk 1 2 bob is odd bob is NOT even and when run under Valgrind (I've also attached verbose output): % valgrind ./hmmlk 1 2 bob is odd bob is even This source was compiled with GGC 3.2: gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5) without optimisation. Has anyone else encountered this problem, or have any ideas on how to get Valgrind to report the same results? Or is this a GCC bug? Thanks in advance, Lee Kindness. |
|
From: Paul H. <pa...@ha...> - 2003-11-18 18:06:34
|
On Tue, 18 Nov 2003, Lee Kindness wrote: > Hi, > The attached test case results in different output when run under > Valgrind (version 2.0 & 1.9.6) compared to when it is run > stand-alone. This source makes use of nested functions. Most importantly, it makes use of 2 functions named "sel". And it is confusing them. Hmm, further experiments show that the bug persists if one of the sel()s is renamed. > The following is output when run normally: > % ./hmmlk 1 2 > bob is odd > bob is NOT even I added fprintf(stdout,"sel1\n"); to the first sel, and fprintf(stdout,"sel2\n"); to the second sel. Here is my output: sel1 bob is odd sel2 bob is NOT even > and when run under Valgrind (I've also attached verbose output): > > % valgrind ./hmmlk 1 2 > bob is odd > bob is even sel1 bob is odd sel1 bob is even > This source was compiled with GGC 3.2: > > gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5) > > without optimisation. > Has anyone else encountered this problem, or have any ideas on how to > get Valgrind to report the same results? Or is this a GCC bug? Don't nest the functions and it just works. > Thanks in advance, Lee Kindness. -- Paulh |
|
From: Lee K. <lki...@cs...> - 2003-11-19 12:41:58
|
Paul Haas writes: > Don't nest the functions and it just works. Granted, but that's not really a solution. Valgrind should handle nested function calls. Your added debug has shown that when run under Valgrind the program flow is altered - I'd say that's a Valgrind bug and to work around it isn't the best long-term solution, afterall who's to say the same bug does not affect "more normal" programing practices? Thanks, L. |
|
From: Paul H. <pa...@ha...> - 2003-11-19 13:54:00
|
On Wed, 19 Nov 2003, Lee Kindness wrote:
> Date: Wed, 19 Nov 2003 12:41:40 +0000
> From: Lee Kindness <lki...@cs...>
> To: pa...@ha...
> Cc: Lee Kindness <lki...@cs...>, val...@li...,
> Duncan Muirhead <du...@cs...>
> Subject: Re: [Valgrind-users] Nested functions
>
> Paul Haas writes:
> > Don't nest the functions and it just works.
Sorry about that comment. I realized the inappropriateness within seconds
of hitting the send button.
> Granted, but that's not really a solution. Valgrind should handle
> nested function calls. Your added debug has shown that when run under
> Valgrind the program flow is altered - I'd say that's a Valgrind bug
> and to work around it isn't the best long-term solution, afterall
> who's to say the same bug does not affect "more normal" programing
> practices?
>
> Thanks, L.
Here's a shorter program that demonstrates the same bug.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
static void CallViaP(void (*sel)(void)) {
sel();
}
int main(int argc, char** argv) {
static void MidFunc1(void) {
static void BottomFunc1(void) {
fprintf(stdout,"BottomFunc1\n");
}
CallViaP( BottomFunc1);
}
static void MidFunc2(void) {
static void BottomFunc2( void ) {
fprintf(stdout,"BottomFunc2\n");
}
CallViaP(BottomFunc2 );
}
MidFunc1();
MidFunc2();
return 0;
}
|
|
From: Lee K. <lki...@cs...> - 2003-11-19 12:45:17
|
Hi, some further info on this problem (see below), not necessarily a reply to Dennis. Dennis Lubert writes: > At 17:10 18.11.2003, you wrote: > >The attached test case results in different output when run under > >Valgrind (version 2.0 & 1.9.6) compared to when it is run > >stand-alone. This source makes use of nested functions. > > > >The following is output when run normally: > > > > % ./hmmlk 1 2 > > bob is odd > > bob is NOT even > > > >and when run under Valgrind (I've also attached verbose output): > > > > % valgrind ./hmmlk 1 2 > > bob is odd > > bob is even > > I can confirm this for gcc 3.3.1 and valgrind HEAD as well as 1.9.6 ... > Even the nul skin does produce this behaviour. > > A quick look at the generated assembly, looks as if it should work, but > obiously valgrind is confusing something. I would rather try to fix > valgrind, than simply not to use nested functions, since the bug might > affect other function pointer / nested function issues. > > gcc produces two symbols. One is sel.1 and the other is sel.3 ... I would > suspect that valgrind does not get the second symbol right, since it does > not even seem to pass the right function pointer to find_name ... Another > curious thing is, if you let the program display the pointers, they seem to > be the same, with and without valgrind... Its all just a rough guess, since > I don't know much about the internals, and how gcc handles function pointers... The double nesting is irrelevant; moving both is_even() and is_odd() to the outer scope doesn't change the behaviour. Both "hmmlk" and "hmmlk 0" (which use only is_odd()) work the same when run normally and when run under valgrind The order of definition of is_odd(), is_even() is irrelevant, but the order of calling is not: I tried changing main() to allow several calls, in various orders of test() and testw() and it seems that the second function called is always in error (ie differs under valgrind and normal running), however often it is called, while the first one is ok, however often called. Thanks, Lee. |
|
From: Crispin F. <val...@fl...> - 2003-11-19 14:00:18
Attachments:
hmmlk.c
|
I made a simpler test case while having a quick look at this, see the attached file. I couldn't simplify it any more than this. Hope it helps. Crispin On Wed, 2003-11-19 at 12:45, Lee Kindness wrote: > Hi, some further info on this problem (see below), not necessarily a > reply to Dennis. > > Dennis Lubert writes: > > At 17:10 18.11.2003, you wrote: > > >The attached test case results in different output when run under > > >Valgrind (version 2.0 & 1.9.6) compared to when it is run > > >stand-alone. This source makes use of nested functions. > > > > > >The following is output when run normally: > > > > > > % ./hmmlk 1 2 > > > bob is odd > > > bob is NOT even > > > > > >and when run under Valgrind (I've also attached verbose output): > > > > > > % valgrind ./hmmlk 1 2 > > > bob is odd > > > bob is even > > > > I can confirm this for gcc 3.3.1 and valgrind HEAD as well as 1.9.6 ... > > Even the nul skin does produce this behaviour. > > > > A quick look at the generated assembly, looks as if it should work, but > > obiously valgrind is confusing something. I would rather try to fix > > valgrind, than simply not to use nested functions, since the bug might > > affect other function pointer / nested function issues. > > > > gcc produces two symbols. One is sel.1 and the other is sel.3 ... I would > > suspect that valgrind does not get the second symbol right, since it does > > not even seem to pass the right function pointer to find_name ... Another > > curious thing is, if you let the program display the pointers, they seem to > > be the same, with and without valgrind... Its all just a rough guess, since > > I don't know much about the internals, and how gcc handles function pointers... > > > The double nesting is irrelevant; moving both is_even() and is_odd() > to the outer scope doesn't change the behaviour. > > Both "hmmlk" and "hmmlk 0" (which use only is_odd()) work the same > when run normally and when run under valgrind > > The order of definition of is_odd(), is_even() is irrelevant, but the > order of calling is not: I tried changing main() to allow several > calls, in various orders of test() and testw() and it seems that the > second function called is always in error (ie differs under valgrind > and normal running), however often it is called, while the first one > is ok, however often called. > > Thanks, Lee. > > > ------------------------------------------------------- > This SF.net email is sponsored by: SF.net Giveback Program. > Does SourceForge.net help you be more productive? Does it > help you create better code? SHARE THE LOVE, and help us help > YOU! Click Here: http://sourceforge.net/donate/ > _______________________________________________ > Valgrind-users mailing list > Val...@li... > https://lists.sourceforge.net/lists/listinfo/valgrind-users |
|
From: Josef W. <Jos...@gm...> - 2003-11-19 15:26:24
|
Hi,
just looked at this strange piece of code.
Now I know why Intel refuses to support nested functions in their
compilers ;-)
When GCC-compiled code needs a function pointer for a nested function, it
seems to produce dynamically some trampoline code on the stack, and uses the
start address of this piece of code as the function pointer (don't ask me
why).
Note that the function pointer for the nested function will point to the same
address of dynamically produced code. Valgrind's instrumentation engine
doesn't detect that the code on stack is changed inbetween, and uses
the same instrumented version both times.
The code works as expected if you change call_func() this way:
=============================================
#include <valgrind/valgrind.h>
...
static void call_func(void (*sel)(void))
{
sel();
VALGRIND_DISCARD_TRANSLATIONS(sel,20);
}
=============================================
Note that VG would be quite slow if it had to check if a write instruction
is about to change already instrumented code (Wasn't this the
case in the first days of VG?).
Josef
|