aboutsummaryrefslogtreecommitdiff
path: root/src/libthread
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2004-04-21 19:29:04 +0000
committerrsc <devnull@localhost>2004-04-21 19:29:04 +0000
commita3785ca2cc1c8693d89ebe44216acf781a634718 (patch)
tree2ae82a3a7c462e670e8b0d6e234e301cfd317987 /src/libthread
parentcdd61ab0aee825e93688ae5d2cfb86f14baad858 (diff)
downloadplan9port-a3785ca2cc1c8693d89ebe44216acf781a634718.tar.gz
plan9port-a3785ca2cc1c8693d89ebe44216acf781a634718.tar.bz2
plan9port-a3785ca2cc1c8693d89ebe44216acf781a634718.zip
Tweaks to make libthread tell Valgrind about its stack limits,
so that Valgrind can detect stack overflow for me.
Diffstat (limited to 'src/libthread')
-rw-r--r--src/libthread/386.c36
-rw-r--r--src/libthread/asm-FreeBSD-386.s8
-rw-r--r--src/libthread/channel.c2
-rw-r--r--src/libthread/mkfile3
-rw-r--r--src/libthread/sched.c5
-rw-r--r--src/libthread/threadimpl.h2
-rw-r--r--src/libthread/tprimes.c12
7 files changed, 60 insertions, 8 deletions
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 <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
+}
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 <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);
}