From a3785ca2cc1c8693d89ebe44216acf781a634718 Mon Sep 17 00:00:00 2001 From: rsc Date: Wed, 21 Apr 2004 19:29:04 +0000 Subject: Tweaks to make libthread tell Valgrind about its stack limits, so that Valgrind can detect stack overflow for me. --- src/libthread/386.c | 36 ++++++++++++++++++++++++++++++++++++ src/libthread/asm-FreeBSD-386.s | 8 +++++++- src/libthread/channel.c | 2 +- src/libthread/mkfile | 3 +++ src/libthread/sched.c | 5 +++-- src/libthread/threadimpl.h | 2 +- src/libthread/tprimes.c | 12 +++++++++--- 7 files changed, 60 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/libthread/386.c b/src/libthread/386.c index 2f391bff..3fbf0afe 100644 --- a/src/libthread/386.c +++ b/src/libthread/386.c @@ -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 +#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 +} diff --git a/src/libthread/asm-FreeBSD-386.s b/src/libthread/asm-FreeBSD-386.s index 35e2ab6f..c815ac58 100644 --- a/src/libthread/asm-FreeBSD-386.s +++ b/src/libthread/asm-FreeBSD-386.s @@ -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 diff --git a/src/libthread/channel.c b/src/libthread/channel.c index 48fe78c7..ce27896b 100644 --- a/src/libthread/channel.c +++ b/src/libthread/channel.c @@ -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(); } diff --git a/src/libthread/mkfile b/src/libthread/mkfile index 20ab5a8d..a76682b2 100644 --- a/src/libthread/mkfile +++ b/src/libthread/mkfile @@ -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 diff --git a/src/libthread/sched.c b/src/libthread/sched.c index d193d6ce..57d597ba 100644 --- a/src/libthread/sched.c +++ b/src/libthread/sched.c @@ -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); diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h index 06ed671d..373164ad 100644 --- a/src/libthread/threadimpl.h +++ b/src/libthread/threadimpl.h @@ -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*); diff --git a/src/libthread/tprimes.c b/src/libthread/tprimes.c index 9426bdfa..e028f982 100644 --- a/src/libthread/tprimes.c +++ b/src/libthread/tprimes.c @@ -1,6 +1,12 @@ -#include +#include +#include #include +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); } -- cgit v1.2.3