summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/9/pc/fns.h2
-rw-r--r--sys/src/9/pc/trap.c48
-rw-r--r--sys/src/9/port/devproc.c9
-rw-r--r--sys/src/9/port/portfns.h2
-rw-r--r--sys/src/9/port/proc.c11
-rw-r--r--sys/src/9/port/syscallfmt.c28
-rw-r--r--sys/src/9/port/sysproc.c2
7 files changed, 48 insertions, 54 deletions
diff --git a/sys/src/9/pc/fns.h b/sys/src/9/pc/fns.h
index 5024723b2..928267b34 100644
--- a/sys/src/9/pc/fns.h
+++ b/sys/src/9/pc/fns.h
@@ -161,8 +161,6 @@ void screeninit(void);
void (*screenputs)(char*, int);
void* sigsearch(char*);
void syncclock(void);
-void syscallfmt(int syscallno, ulong pc, va_list list);
-void sysretfmt(int syscallno, va_list list, long ret, uvlong start, uvlong stop);
void* tmpmap(Page*);
void tmpunmap(void*);
void touser(void*);
diff --git a/sys/src/9/pc/trap.c b/sys/src/9/pc/trap.c
index 871661a52..1746e963c 100644
--- a/sys/src/9/pc/trap.c
+++ b/sys/src/9/pc/trap.c
@@ -734,26 +734,6 @@ syscall(Ureg* ureg)
scallnr = ureg->ax;
up->scallnr = scallnr;
- if(up->procctl == Proc_tracesyscall){
- /*
- * Redundant validaddr. Do we care?
- * Tracing syscalls is not exactly a fast path...
- * Beware, validaddr currently does a pexit rather
- * than an error if there's a problem; that might
- * change in the future.
- */
- if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)-BY2WD))
- validaddr(sp, sizeof(Sargs)+BY2WD, 0);
-
- syscallfmt(scallnr, ureg->pc, (va_list)(sp+BY2WD));
- up->procctl = Proc_stopme;
- procctl(up);
- if(up->syscalltrace)
- free(up->syscalltrace);
- up->syscalltrace = nil;
- startns = todget(nil);
- }
-
if(scallnr == RFORK && up->fpstate == FPactive){
fpsave(&up->fpsave);
up->fpstate = FPinactive;
@@ -763,17 +743,26 @@ syscall(Ureg* ureg)
up->nerrlab = 0;
ret = -1;
if(!waserror()){
+ if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-sizeof(Sargs)-BY2WD))
+ validaddr(sp, sizeof(Sargs)+BY2WD, 0);
+
+ up->s = *((Sargs*)(sp+BY2WD));
+
+ if(up->procctl == Proc_tracesyscall){
+ syscallfmt(scallnr, ureg->pc, (va_list)up->s.args);
+ s = splhi();
+ up->procctl = Proc_stopme;
+ procctl(up);
+ splx(s);
+ startns = todget(nil);
+ }
+
if(scallnr >= nsyscall || systab[scallnr] == 0){
pprint("bad sys call number %lud pc %lux\n",
scallnr, ureg->pc);
postnote(up, 1, "sys: bad sys call", NDebug);
error(Ebadarg);
}
-
- if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-sizeof(Sargs)-BY2WD))
- validaddr(sp, sizeof(Sargs)+BY2WD, 0);
-
- up->s = *((Sargs*)(sp+BY2WD));
up->psstate = sysctab[scallnr];
ret = systab[scallnr](up->s.args);
@@ -804,21 +793,18 @@ syscall(Ureg* ureg)
if(up->procctl == Proc_tracesyscall){
stopns = todget(nil);
- up->procctl = Proc_stopme;
- sysretfmt(scallnr, (va_list)(sp+BY2WD), ret, startns, stopns);
+ sysretfmt(scallnr, (va_list)up->s.args, ret, startns, stopns);
s = splhi();
+ up->procctl = Proc_stopme;
procctl(up);
splx(s);
- if(up->syscalltrace)
- free(up->syscalltrace);
- up->syscalltrace = nil;
}
up->insyscall = 0;
up->psstate = 0;
if(scallnr == NOTED)
- noted(ureg, *(ulong*)(sp+BY2WD));
+ noted(ureg, up->s.args[0]);
if(scallnr!=RFORK && (up->procctl || up->nnote)){
splhi();
diff --git a/sys/src/9/port/devproc.c b/sys/src/9/port/devproc.c
index f963c779d..4b47b3035 100644
--- a/sys/src/9/port/devproc.c
+++ b/sys/src/9/port/devproc.c
@@ -737,9 +737,12 @@ procread(Chan *c, void *va, long n, vlong off)
memmove(a, &up->genbuf[offset], n);
return n;
case Qsyscall:
- if(!p->syscalltrace)
- return 0;
- n = readstr(offset, a, n, p->syscalltrace);
+ eqlock(&p->debug);
+ if(p->syscalltrace)
+ n = readstr(offset, a, n, p->syscalltrace);
+ else
+ n = 0;
+ qunlock(&p->debug);
return n;
case Qmem:
diff --git a/sys/src/9/port/portfns.h b/sys/src/9/port/portfns.h
index 135c8d0d3..897398dfa 100644
--- a/sys/src/9/port/portfns.h
+++ b/sys/src/9/port/portfns.h
@@ -326,6 +326,8 @@ void shrrenameuser(char*, char*);
int swapcount(ulong);
int swapfull(void);
void swapinit(void);
+void syscallfmt(ulong syscallno, ulong pc, va_list list);
+void sysretfmt(ulong syscallno, va_list list, long ret, uvlong start, uvlong stop);
void timeradd(Timer*);
void timerdel(Timer*);
void timersinit(void);
diff --git a/sys/src/9/port/proc.c b/sys/src/9/port/proc.c
index 06bdf474e..348ca1592 100644
--- a/sys/src/9/port/proc.c
+++ b/sys/src/9/port/proc.c
@@ -622,10 +622,7 @@ newproc(void)
p->pdbg = 0;
p->fpstate = FPinit;
p->kp = 0;
- if(up && up->procctl == Proc_tracesyscall)
- p->procctl = Proc_tracesyscall;
- else
- p->procctl = 0;
+ p->procctl = 0;
p->syscalltrace = 0;
p->notepending = 0;
p->ureg = 0;
@@ -1078,8 +1075,6 @@ pexit(char *exitstr, int freemem)
Chan *dot;
void (*pt)(Proc*, int, vlong);
- if(up->syscalltrace)
- free(up->syscalltrace);
up->alarm = 0;
if (up->tt)
timerdel(up);
@@ -1194,6 +1189,10 @@ pexit(char *exitstr, int freemem)
wakeup(&up->pdbg->sleep);
up->pdbg = 0;
}
+ if(up->syscalltrace) {
+ free(up->syscalltrace);
+ up->syscalltrace = 0;
+ }
qunlock(&up->debug);
/* Sched must not loop for these locks */
diff --git a/sys/src/9/port/syscallfmt.c b/sys/src/9/port/syscallfmt.c
index 8c13f6fed..23eba4e95 100644
--- a/sys/src/9/port/syscallfmt.c
+++ b/sys/src/9/port/syscallfmt.c
@@ -22,6 +22,7 @@ fmtrwdata(Fmt* f, char* a, int n, char* suffix)
}
validaddr((ulong)a, n, 0);
t = smalloc(n+1);
+ t[n] = 0;
for(i = 0; i < n; i++)
if(a[i] > 0x20 && a[i] < 0x7f) /* printable ascii? */
t[i] = a[i];
@@ -52,7 +53,7 @@ fmtuserstring(Fmt* f, char* a, char* suffix)
}
void
-syscallfmt(int syscallno, ulong pc, va_list list)
+syscallfmt(ulong syscallno, ulong pc, va_list list)
{
long l;
Fmt fmt;
@@ -65,16 +66,13 @@ syscallfmt(int syscallno, ulong pc, va_list list)
fmtstrinit(&fmt);
fmtprint(&fmt, "%uld %s ", up->pid, up->text);
- if(syscallno > nsyscall)
- fmtprint(&fmt, " %d ", syscallno);
+ if(syscallno >= nsyscall)
+ fmtprint(&fmt, " %uld ", syscallno);
else
fmtprint(&fmt, "%s ", sysctab[syscallno]?
sysctab[syscallno]: "huh?");
fmtprint(&fmt, "%ulx ", pc);
- if(up->syscalltrace != nil)
- free(up->syscalltrace);
-
switch(syscallno){
case SYSR1:
p = va_arg(list, uintptr);
@@ -301,11 +299,15 @@ syscallfmt(int syscallno, ulong pc, va_list list)
break;
}
- up->syscalltrace = fmtstrflush(&fmt);
+ a = fmtstrflush(&fmt);
+ qlock(&up->debug);
+ free(up->syscalltrace);
+ up->syscalltrace = a;
+ qunlock(&up->debug);
}
void
-sysretfmt(int syscallno, va_list list, long ret, uvlong start, uvlong stop)
+sysretfmt(ulong syscallno, va_list list, long ret, uvlong start, uvlong stop)
{
long l;
void* v;
@@ -316,9 +318,6 @@ sysretfmt(int syscallno, va_list list, long ret, uvlong start, uvlong stop)
fmtstrinit(&fmt);
- if(up->syscalltrace)
- free(up->syscalltrace);
-
errstr = "\"\"";
switch(syscallno){
default:
@@ -402,5 +401,10 @@ sysretfmt(int syscallno, va_list list, long ret, uvlong start, uvlong stop)
break;
}
fmtprint(&fmt, " %s %#llud %#llud\n", errstr, start, stop);
- up->syscalltrace = fmtstrflush(&fmt);
+
+ a = fmtstrflush(&fmt);
+ qlock(&up->debug);
+ free(up->syscalltrace);
+ up->syscalltrace = a;
+ qunlock(&up->debug);
}
diff --git a/sys/src/9/port/sysproc.c b/sys/src/9/port/sysproc.c
index 177c4a798..a94213138 100644
--- a/sys/src/9/port/sysproc.c
+++ b/sys/src/9/port/sysproc.c
@@ -162,6 +162,8 @@ sysrfork(ulong *arg)
}
p->hang = up->hang;
p->procmode = up->procmode;
+ if(up->procctl == Proc_tracesyscall)
+ p->procctl = Proc_tracesyscall;
/* Craft a return frame which will cause the child to pop out of
* the scheduler in user mode with the return register zero