tTweaks to make libthread tell Valgrind about its stack limits, so that Valgrin… | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit a3785ca2cc1c8693d89ebe44216acf781a634718 | |
parent cdd61ab0aee825e93688ae5d2cfb86f14baad858 | |
Author: rsc <devnull@localhost> | |
Date: Wed, 21 Apr 2004 19:29:04 +0000 | |
Tweaks to make libthread tell Valgrind about its stack limits, | |
so that Valgrind can detect stack overflow for me. | |
Diffstat: | |
M src/libthread/386.c | 36 +++++++++++++++++++++++++++++… | |
M src/libthread/asm-FreeBSD-386.s | 8 +++++++- | |
M src/libthread/channel.c | 2 +- | |
M src/libthread/mkfile | 3 +++ | |
M src/libthread/sched.c | 5 +++-- | |
M src/libthread/threadimpl.h | 2 +- | |
M src/libthread/tprimes.c | 12 +++++++++--- | |
7 files changed, 60 insertions(+), 8 deletions(-) | |
--- | |
diff --git a/src/libthread/386.c b/src/libthread/386.c | |
t@@ -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); | |
} | |
t@@ -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 | |
t@@ -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 | |
t@@ -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 | |
t@@ -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… | |
+ fprint(2, "expected channel with elements of size %d, got size… | |
sz, c->e); | |
abort(); | |
} | |
diff --git a/src/libthread/mkfile b/src/libthread/mkfile | |
t@@ -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 | |
t@@ -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, (ul… | |
+ if((ulong)&p < (ulong)t->stk+512){ /* stack overflow wa… | |
+ fprint(2, "stack overflow: stack at %lux, limit at %lu… | |
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 | |
t@@ -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 | |
t@@ -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; | |
t@@ -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) | |
t@@ -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); | |
} |