1
0
mirror of https://github.com/golang/go synced 2024-11-19 00:54:42 -07:00

runtime: convert Stack to Go.

LGTM=khr
R=khr, josharian
CC=golang-codereviews
https://golang.org/cl/129510043
This commit is contained in:
Rémy Oudompheng 2014-08-26 08:34:46 +02:00
parent 0eaea6010a
commit 39ffa8be78
8 changed files with 72 additions and 39 deletions

View File

@ -860,6 +860,12 @@ TEXT runtime·getcallersp(SB), NOSPLIT, $0-4
MOVL sp+0(FP), AX
RET
// func gogetcallersp(p unsafe.Pointer) uintptr
TEXT runtime·gogetcallersp(SB),NOSPLIT,$0-8
MOVL p+0(FP),AX // addr of first arg
MOVL AX, ret+4(FP)
RET
// int64 runtime·cputicks(void), so really
// void runtime·cputicks(int64 *ticks)
TEXT runtime·cputicks(SB),NOSPLIT,$0-4

View File

@ -946,6 +946,12 @@ TEXT runtime·getcallersp(SB),NOSPLIT,$0-8
MOVQ sp+0(FP), AX
RET
// func gogetcallersp(p unsafe.Pointer) uintptr
TEXT runtime·gogetcallersp(SB),NOSPLIT,$0-16
MOVQ p+0(FP),AX // addr of first arg
MOVQ AX, ret+8(FP)
RET
// int64 runtime·cputicks(void)
TEXT runtime·cputicks(SB),NOSPLIT,$0-0
RDTSC

View File

@ -747,6 +747,12 @@ TEXT runtime·getcallersp(SB),NOSPLIT,$0-8
MOVL sp+0(FP), AX
RET
// func gogetcallersp(p unsafe.Pointer) uintptr
TEXT runtime·gogetcallersp(SB),NOSPLIT,$0-12
MOVL p+0(FP),AX // addr of first arg
MOVL AX, ret+8(FP)
RET
// int64 runtime·cputicks(void)
TEXT runtime·cputicks(SB),NOSPLIT,$0-0
RDTSC

View File

@ -644,6 +644,13 @@ TEXT runtime·getcallersp(SB),NOSPLIT,$-4-4
MOVW $-4(R0), R0
RET
// func gogetcallersp(p unsafe.Pointer) uintptr
TEXT runtime·gogetcallersp(SB),NOSPLIT,$-4-8
MOVW 0(FP), R0
MOVW $-4(R0), R0
MOVW R0, ret+4(FP)
RET
TEXT runtime·emptyfunc(SB),0,$0-0
RET

View File

@ -133,9 +133,3 @@ type BlockProfileRecord struct {
Cycles int64
StackRecord
}
// Stack formats a stack trace of the calling goroutine into buf
// and returns the number of bytes written to buf.
// If all is true, Stack formats stack traces of all other goroutines
// into buf after the trace for the current goroutine.
func Stack(buf []byte, all bool) int

View File

@ -141,6 +141,47 @@ func BlockProfile(p []BlockProfileRecord) (n int, ok bool) {
return
}
// Stack formats a stack trace of the calling goroutine into buf
// and returns the number of bytes written to buf.
// If all is true, Stack formats stack traces of all other goroutines
// into buf after the trace for the current goroutine.
func Stack(buf []byte, all bool) int {
sp := gogetcallersp(unsafe.Pointer(&buf))
pc := gogetcallerpc(unsafe.Pointer(&buf))
mp := acquirem()
gp := mp.curg
if all {
semacquire(&worldsema, false)
mp.gcing = 1
releasem(mp)
stoptheworld()
if mp != acquirem() {
gothrow("Stack: rescheduled")
}
}
n := 0
if len(buf) > 0 {
gp.writebuf = &buf[0]
gp.writenbuf = int32(len(buf))
traceback(pc, sp, 0, gp)
if all {
tracebackothers(gp)
}
n = len(buf) - int(gp.writenbuf)
gp.writebuf = nil
gp.writenbuf = 0
}
if all {
mp.gcing = 0
semrelease(&worldsema)
starttheworld()
}
releasem(mp)
return n
}
// ThreadCreateProfile returns n, the number of records in the thread creation profile.
// If len(p) >= n, ThreadCreateProfile copies the profile into p and returns n, true.
// If len(p) < n, ThreadCreateProfile does not change p and returns n, false.

View File

@ -256,39 +256,6 @@ struct TRecord {
uintptr stk[32];
};
func Stack(b Slice, all bool) (n int) {
uintptr pc, sp;
sp = runtime·getcallersp(&b);
pc = (uintptr)runtime·getcallerpc(&b);
if(all) {
runtime·semacquire(&runtime·worldsema, false);
g->m->gcing = 1;
runtime·stoptheworld();
}
if(b.len == 0)
n = 0;
else{
g->writebuf = (byte*)b.array;
g->writenbuf = b.len;
runtime·goroutineheader(g);
runtime·traceback(pc, sp, 0, g);
if(all)
runtime·tracebackothers(g);
n = b.len - g->writenbuf;
g->writebuf = nil;
g->writenbuf = 0;
}
if(all) {
g->m->gcing = 0;
runtime·semrelease(&runtime·worldsema);
runtime·starttheworld();
}
}
static void
saveg(uintptr pc, uintptr sp, G *gp, TRecord *r)
{

View File

@ -18,6 +18,9 @@ const (
//go:noescape
func gogetcallerpc(p unsafe.Pointer) uintptr
//go:noescape
func gogetcallersp(p unsafe.Pointer) uintptr
//go:noescape
func racereadpc(addr unsafe.Pointer, callpc, pc uintptr)
@ -212,3 +215,6 @@ func gonotetsleepg(n *note, t int64) {
}
func exitsyscall()
func traceback(pc, sp, lr uintptr, gp *g)
func tracebackothers(gp *g)