|
From: Nathan N. <nn...@um...> - 2003-04-13 20:43:55
|
First off, openafs is doing some user-space threading using setjmp/etc.
There seems to be a mention in the valgrind docs about maybe having
trouble with this, if this is the problem, is there any workaround?
First, what is the problem here:
==26290== Invalid write of size 4
==26290== at 0x8097889: rxi_AllocPacketNoLock
(/umr/s/openafs/openafs/src/rx/rx_packet.c:637)
==26290== by 0x8097927: rxi_AllocSendPacket
(/umr/s/openafs/openafs/src/rx/rx_packet.c:674)
==26290== by 0x809B463: rxi_WriteProc
(/umr/s/openafs/openafs/src/rx/rx_rdwr.c:731)
==26290== by 0x809B963: rx_WriteProc32
(/umr/s/openafs/openafs/src/rx/rx_rdwr.c:909)
==26290== Address 0x4106C444 is 16552 bytes inside a block of size
80752 alloc'd
==26290== at 0x40166741: malloc (vg_clientfuncs.c:103)
==26290== by 0x80972F2: rxi_MorePackets
(/umr/s/openafs/openafs/src/rx/rx_packet.c:366)
==26290== by 0x808BA70: rx_Init
(/umr/s/openafs/openafs/src/rx/rx.c:458)
==26290== by 0x806A7A1: vsu_ClientInit
(/umr/s/openafs/openafs/src/volser/vsutils.c:425)
Why is the read invalid if it's a 4 byte read 16552 bytes inside a block
of size 80752?
Second, how can this code:
afs_int32 savecontext(ep, savearea, sp)
char (*ep)();
struct lwp_context *savearea;
char* sp;
{
int code;
PRE_Block = 1;
EP = ep;
code = setjmp(savearea->setjmp_buffer);
jmpBuffer = (jmp_buf_type *)savearea->setjmp_buffer;
savearea->topstack = (char*)jmpBuffer[LWP_SP];
#if defined(DEBUG)
{
int i, *ptr = (int*)savearea->setjmp_buffer;
printf("savecontext\n");
for ( i=0; i < 5; i++)
printf("(%d) 0x%x ",i, ptr[i]);
printf("\n");
for ( i=5; i < 10; i++)
printf("(%d) 0x%x ",i, ptr[i]);
printf("\n");
}
#endif
switch ( code )
{
case 0: if ( !sp )
(*EP)();
else
generate a unitialized error on the "switch ( code )" line? That doesn't
seem to be possible unless the setjmp is returning an unitialized value
as it's result.
-- Nathan
------------------------------------------------------------
Nathan Neulinger EMail: nn...@um...
University of Missouri - Rolla Phone: (573) 341-4841
Computing Services Fax: (573) 341-4216
|
|
From: Jeremy F. <je...@go...> - 2003-04-14 11:10:42
|
Quoting Nathan Neulinger <nn...@um...>:
> First off, openafs is doing some user-space threading using
> setjmp/etc.
> There seems to be a mention in the valgrind docs about maybe having
> trouble with this, if this is the problem, is there any workaround?
The big question is how large are the thread stacks, and how far apart are they
in memory? Valgrind's only heuristic for distinguishing between longjmp within
a stack vs. longjmp between stacks is looking at the size of the esp movement;
if it is large, it is a stack switch, and if small it is within one stack.
This heuristic is horribly broken if you have relatively small stacks closely
spaced. Normally, when %esp moves to a lower address, Valgrind considers the
stack to be extended, which means the memory becomes available for use.
Conversely, when %esp goes up, the memory under %esp is considered non-valid.
Now, if Valgrind sees %esp move up, and assumes it is within one stack, then all
the memory between the old value and the new value is invalidated. If it was,
in fact, a stack switch, it has probably completely invalidated one or more of
your stacks, and therefore their local variables, return address, etc. This can
cause massive numbers of spurious errors (including errors at the end of a
function caused by a return to an undefined return address).
There is no good workaround for this at the moment, except by changing the
heuristic threshhold constant (in vg_memory.c from memory, but I don't have the
source with me at the moment).
I have a better solution in mind, but the first implementation didn't work; I
need to think about it more.
J
|