|
From: Nicholas N. <nj...@ca...> - 2003-11-01 12:33:53
|
On Fri, 26 Sep 2003, Avery Pennarun wrote: > I have a fun problem with valgrind in the WvTask part of my WvStreams > library (http://open.nit.ca/wiki?WvStreams). I can make a minimal test case > for you if necessary, but the idea is this: > > setjmp(top); > alloca(1024*1024); // reserve space on stack for toplevel > setjmp(inside); > longjmp(top); > > This allows me to allocate "extra stacks" within my own primary stack, > rather than writing arch-specific stack changing code that uses malloc(). > Unfortunately, next time I longjmp(inside) and try to use one of my new > local variables, I get warnings like this: > > Conditional jump or move depends on uninitialised value(s) > Use of uninitialised value of size 4 > > etc. > > My favourite one is on the following assertion: > > assert(magic_number == -WVTASK_MAGIC); > > (where WVTASK_MAGIC is a constant). This code is from my pre-valgrind days, > and I used it to catch stack overflows. Entertainingly, the assertion > passes (exactly the right 32-bit number is where it should be), but valgrind > insists that I'm accessing uninitialized memory. > > I gather this is happening to me because of the following bit from the > manual: > > * When the stack pointer register (%esp) moves up or down, A bits > are set. The rule is that the area from %esp up to the base of the > stack is marked as accessible, and below %esp is inaccessible. > > But in my case, I need the area below %esp to not be marked inaccessible. I > really want only the memory below *the minimum historical value of %esp* to > be inaccessible. > > I've tried using VALGRIND_MAKE_READABLE, but that appears to not work on the > stack, or something. It doesn't seem to help, anyway. Firstly, sorry for taking so long to reply. What you are doing is certainly quite unusual, and hence doesn't conform to Valgrind's expectations of normal stack behaviour. When the stack grows, the memory from old_esp..new_esp is marked as accessible, but uninitialised. When the stack shrinks, the memory from old_esp..new_esp is marked as inaccessible, and uninitialised. I think this is why you're getting the uninitialised errors. Where did you insert the VALGRIND_MAKE_READABLE call? I'm pretty sure that macro will work on the stack. If I've understood your technique, I think you want to do this: remember esp alloc big new chunk on the stack restore esp call VALGRIND_MAKE_READABLE on the new chunk The critical thing being that you call the macro after you restore %esp. But I'm not sure I understand entirely. Also, it's possible that Valgrind thinks your program is switching stacks, which might be causing the confusion. N |