Tweaks to make libthread tell Valgrind about its stack limits,

so that Valgrind can detect stack overflow for me.
This commit is contained in:
rsc 2004-04-21 19:29:04 +00:00
parent cdd61ab0ae
commit a3785ca2cc
7 changed files with 60 additions and 8 deletions

View file

@ -1,8 +1,23 @@
#include "threadimpl.h"
/*
* To use this you need some patches to Valgrind that
* let it help out with detecting stack overflow.
*/
#define USEVALGRIND 0
#ifdef USEVALGRIND
#include <valgrind/memcheck.h>
#endif
static void
launcher386(void (*f)(void *arg), void *arg)
{
Proc *p;
Thread *t;
p = _threadgetproc();
t = p->thread;
_threadstacklimit(t->stk);
(*f)(arg);
threadexits(nil);
}
@ -19,3 +34,24 @@ _threadinitstack(Thread *t, void (*f)(void*), void *arg)
t->sched.sp = (ulong)tos - 8; /* old PC and new PC */
}
void
_threadinswitch(int enter)
{
USED(enter);
#ifdef USEVALGRIND
if(enter)
VALGRIND_SET_STACK_LIMIT(0, 0, 1);
else
VALGRIND_SET_STACK_LIMIT(0, 0, 0);
#endif
}
void
_threadstacklimit(void *addr)
{
USED(addr);
#ifdef USEVALGRIND
VALGRIND_SET_STACK_LIMIT(1, addr, 0);
#endif
}

View file

@ -17,6 +17,9 @@ _setlabel:
.type _gotolabel,@function
_gotolabel:
pushl $1
call _threadinswitch
popl %eax
movl 4(%esp), %edx
movl 0(%edx), %ecx
movl 4(%edx), %ebx
@ -24,9 +27,12 @@ _gotolabel:
movl 12(%edx), %ebp
movl 16(%edx), %esi
movl 20(%edx), %edi
movl %ecx, 0(%esp)
pushl $0
call _threadinswitch
popl %eax
xorl %eax, %eax
incl %eax
movl %ecx, 0(%esp)
ret

View file

@ -277,7 +277,7 @@ static void
channelsize(Channel *c, int sz)
{
if(c->e != sz){
fprint(2, "expected channel with elements of size %d, got size %d",
fprint(2, "expected channel with elements of size %d, got size %d\n",
sz, c->e);
abort();
}

View file

@ -53,3 +53,6 @@ trend: trend.$O $PLAN9/lib/$LIB
CLEANFILES=$CLEANFILES tprimes texec
asm-Linux-386.$O: asm-FreeBSD-386.s
asm-NetBSD-386.$O: asm-FreeBSD-386.s
asm-OpenBSD-386.$O: asm-FreeBSD-386.s

View file

@ -166,14 +166,15 @@ Resched:
p = _threadgetproc();
//fprint(2, "p %p\n", p);
if((t = p->thread) != nil){
if((ulong)&p < (ulong)t->stk){ /* stack overflow */
fprint(2, "stack overflow %lux %lux\n", (ulong)&p, (ulong)t->stk);
if((ulong)&p < (ulong)t->stk+512){ /* stack overflow waiting to happen */
fprint(2, "stack overflow: stack at %lux, limit at %lux\n", (ulong)&p, (ulong)t->stk);
abort();
}
// _threaddebug(DBGSCHED, "pausing, state=%s set %p goto %p",
// psstate(t->state), &t->sched, &p->sched);
if(_setlabel(&t->sched)==0)
_gotolabel(&p->sched);
_threadstacklimit(t->stk);
return;
}else{
t = runthread(p);

View file

@ -219,4 +219,4 @@ extern int _threadgetpid(void);
extern void _threadmemset(void*, int, int);
extern void _threaddebugmemset(void*, int, int);
extern int _threadprocs;
extern void _threadstacklimit(void*);

View file

@ -1,6 +1,12 @@
#include <lib9.h>
#include <u.h>
#include <libc.h>
#include <thread.h>
enum
{
STACK = 8192
};
int quiet;
int goal;
int buffer;
@ -19,7 +25,7 @@ primethread(void *arg)
if(!quiet)
print("%d\n", p);
nc = chancreate(sizeof(ulong), buffer);
(*fn)(primethread, nc, 8192);
(*fn)(primethread, nc, STACK);
for(;;){
i = recvul(c);
if(i%p)
@ -56,7 +62,7 @@ threadmain(int argc, char **argv)
goal = 100;
c = chancreate(sizeof(ulong), buffer);
(*fn)(primethread, c, 8192);
(*fn)(primethread, c, STACK);
for(i=2;; i++)
sendul(c, i);
}