mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-24 11:41:58 +00:00
Tweaks to make libthread tell Valgrind about its stack limits,
so that Valgrind can detect stack overflow for me.
This commit is contained in:
parent
cdd61ab0ae
commit
a3785ca2cc
7 changed files with 60 additions and 8 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue