summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-09-03 11:11:16 -0400
committerRuss Cox <rsc@golang.org>2014-09-03 11:11:16 -0400
commit020cb222b8907f8eb18453a59f691e568a35522a (patch)
tree23ab7545fc195a5f4fa00b7448d9983d7339ea30
parent772338a36fa4195ccd0fcf76fa0eb696d7c3dba0 (diff)
downloadgo-020cb222b8907f8eb18453a59f691e568a35522a.tar.gz
runtime: convert a few traceback-related functions from proc.c to traceback.go
They were in proc.c mainly because there was no portable traceback source file. As part of converting them to Go, move to traceback.go. In order to get access to the PC of _rt0_go, rename to runtime.rt0_go. LGTM=r R=golang-codereviews, r CC=dvyukov, golang-codereviews, iant, khr https://codereview.appspot.com/139110043
-rw-r--r--src/cmd/api/goapi.go12
-rw-r--r--src/pkg/runtime/asm_386.s2
-rw-r--r--src/pkg/runtime/asm_amd64.s2
-rw-r--r--src/pkg/runtime/asm_amd64p32.s2
-rw-r--r--src/pkg/runtime/asm_arm.s2
-rw-r--r--src/pkg/runtime/proc.c128
-rw-r--r--src/pkg/runtime/rt0_darwin_386.s2
-rw-r--r--src/pkg/runtime/rt0_darwin_amd64.s2
-rw-r--r--src/pkg/runtime/rt0_dragonfly_386.s2
-rw-r--r--src/pkg/runtime/rt0_dragonfly_amd64.s2
-rw-r--r--src/pkg/runtime/rt0_freebsd_386.s2
-rw-r--r--src/pkg/runtime/rt0_freebsd_amd64.s2
-rw-r--r--src/pkg/runtime/rt0_freebsd_arm.s4
-rw-r--r--src/pkg/runtime/rt0_linux_386.s2
-rw-r--r--src/pkg/runtime/rt0_linux_amd64.s2
-rw-r--r--src/pkg/runtime/rt0_linux_arm.s2
-rw-r--r--src/pkg/runtime/rt0_nacl_386.s2
-rw-r--r--src/pkg/runtime/rt0_nacl_amd64p32.s2
-rw-r--r--src/pkg/runtime/rt0_nacl_arm.s2
-rw-r--r--src/pkg/runtime/rt0_netbsd_386.s2
-rw-r--r--src/pkg/runtime/rt0_netbsd_amd64.s2
-rw-r--r--src/pkg/runtime/rt0_netbsd_arm.s2
-rw-r--r--src/pkg/runtime/rt0_openbsd_386.s2
-rw-r--r--src/pkg/runtime/rt0_openbsd_amd64.s2
-rw-r--r--src/pkg/runtime/rt0_plan9_386.s2
-rw-r--r--src/pkg/runtime/rt0_plan9_amd64.s2
-rw-r--r--src/pkg/runtime/rt0_solaris_amd64.s2
-rw-r--r--src/pkg/runtime/rt0_windows_386.s2
-rw-r--r--src/pkg/runtime/rt0_windows_amd64.s2
-rw-r--r--src/pkg/runtime/runtime.h1
-rw-r--r--src/pkg/runtime/stubs.go4
-rw-r--r--src/pkg/runtime/traceback.go121
-rw-r--r--src/pkg/runtime/traceback_windows.go3
33 files changed, 158 insertions, 167 deletions
diff --git a/src/cmd/api/goapi.go b/src/cmd/api/goapi.go
index 8dec9e2cc..7f7b389be 100644
--- a/src/cmd/api/goapi.go
+++ b/src/cmd/api/goapi.go
@@ -405,7 +405,17 @@ func (w *Walker) parseFile(dir, file string) (*ast.File, error) {
" wincallbackcontext struct{};" +
" _select struct{}; " +
"); " +
- "const ( cb_max = 2000 )"
+ "const (" +
+ " cb_max = 2000;" +
+ " _Gidle = 1;" +
+ " _Grunnable = 2;" +
+ " _Grunning = 3;" +
+ " _Gsyscall = 4;" +
+ " _Gwaiting = 5;" +
+ " _Gdead = 6;" +
+ " _Genqueue = 7;" +
+ " _Gcopystack = 8;" +
+ ")"
f, err = parser.ParseFile(fset, filename, src, 0)
if err != nil {
log.Fatalf("incorrect generated file: %s", err)
diff --git a/src/pkg/runtime/asm_386.s b/src/pkg/runtime/asm_386.s
index 681a1b681..e99c114ad 100644
--- a/src/pkg/runtime/asm_386.s
+++ b/src/pkg/runtime/asm_386.s
@@ -6,7 +6,7 @@
#include "funcdata.h"
#include "../../cmd/ld/textflag.h"
-TEXT _rt0_go(SB),NOSPLIT,$0
+TEXT runtime·rt0_go(SB),NOSPLIT,$0
// copy arguments forward on an even stack
MOVL argc+0(FP), AX
MOVL argv+4(FP), BX
diff --git a/src/pkg/runtime/asm_amd64.s b/src/pkg/runtime/asm_amd64.s
index 0121b7d86..0933fa92c 100644
--- a/src/pkg/runtime/asm_amd64.s
+++ b/src/pkg/runtime/asm_amd64.s
@@ -6,7 +6,7 @@
#include "funcdata.h"
#include "../../cmd/ld/textflag.h"
-TEXT _rt0_go(SB),NOSPLIT,$0
+TEXT runtime·rt0_go(SB),NOSPLIT,$0
// copy arguments forward on an even stack
MOVQ DI, AX // argc
MOVQ SI, BX // argv
diff --git a/src/pkg/runtime/asm_amd64p32.s b/src/pkg/runtime/asm_amd64p32.s
index 03cf9bd44..4a391033d 100644
--- a/src/pkg/runtime/asm_amd64p32.s
+++ b/src/pkg/runtime/asm_amd64p32.s
@@ -6,7 +6,7 @@
#include "funcdata.h"
#include "../../cmd/ld/textflag.h"
-TEXT _rt0_go(SB),NOSPLIT,$0
+TEXT runtime·rt0_go(SB),NOSPLIT,$0
// copy arguments forward on an even stack
MOVL argc+0(FP), AX
MOVL argv+4(FP), BX
diff --git a/src/pkg/runtime/asm_arm.s b/src/pkg/runtime/asm_arm.s
index 87ea97424..6954bb7c0 100644
--- a/src/pkg/runtime/asm_arm.s
+++ b/src/pkg/runtime/asm_arm.s
@@ -7,7 +7,7 @@
#include "../../cmd/ld/textflag.h"
// using frame size $-4 means do not save LR on stack.
-TEXT _rt0_go(SB),NOSPLIT,$-4
+TEXT runtime·rt0_go(SB),NOSPLIT,$-4
MOVW $0xcafebabe, R12
// copy arguments forward on an even stack
diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c
index 9229c53a8..b85baca14 100644
--- a/src/pkg/runtime/proc.c
+++ b/src/pkg/runtime/proc.c
@@ -185,8 +185,6 @@ runtime·schedinit(void)
if(p != nil && !runtime·strcmp(p, (byte*)"0"))
runtime·copystack = false;
- mstats.enablegc = 1;
-
if(runtime·buildVersion.str == nil) {
// Condition should never trigger. This code just serves
// to ensure runtime·buildVersion is kept in the resulting binary.
@@ -244,7 +242,10 @@ runtime·main(void)
if(g->m != &runtime·m0)
runtime·throw("runtime·main not on m0");
+
runtime·init();
+ mstats.enablegc = 1; // now that runtime is initialized, GC is okay
+
main·init();
if(g->defer != &d || d.fn != &initDone)
@@ -268,118 +269,12 @@ runtime·main(void)
*(int32*)runtime·main = 0;
}
-void
-runtime·goroutineheader(G *gp)
-{
- String status;
- int64 waitfor;
- uint32 gpstatus;
-
- gpstatus = runtime·readgstatus(gp);
- switch(gpstatus) {
- case Gidle:
- status = runtime·gostringnocopy((byte*)"idle");
- break;
- case Grunnable:
- status = runtime·gostringnocopy((byte*)"runnable");
- break;
- case Grunning:
- status = runtime·gostringnocopy((byte*)"running");
- break;
- case Gsyscall:
- status = runtime·gostringnocopy((byte*)"syscall");
- break;
- case Gwaiting:
- if(gp->waitreason.str != nil)
- status = gp->waitreason;
- else
- status = runtime·gostringnocopy((byte*)"waiting");
- break;
- case Gscan:
- status = runtime·gostringnocopy((byte*)"scan");
- break;
- case Gscanrunnable:
- status = runtime·gostringnocopy((byte*)"scanrunnable");
- break;
- case Gscanrunning:
- status = runtime·gostringnocopy((byte*)"scanrunning");
- break;
- case Gscansyscall:
- status = runtime·gostringnocopy((byte*)"scansyscall");
- break;
- case Gscanenqueue:
- status = runtime·gostringnocopy((byte*)"scanenqueue");
- break;
- case Gscanwaiting:
- if(gp->waitreason.str != nil)
- status = gp->waitreason;
- else
- status = runtime·gostringnocopy((byte*)"scanwaiting");
- break;
- case Gcopystack:
- status = runtime·gostringnocopy((byte*)"copystack");
- break;
- default:
- status = runtime·gostringnocopy((byte*)"???");
- break;
- }
-
- // approx time the G is blocked, in minutes
- waitfor = 0;
- gpstatus = gpstatus&~Gscan; // drop the scan bit
- if((gpstatus == Gwaiting || gpstatus == Gsyscall) && gp->waitsince != 0)
- waitfor = (runtime·nanotime() - gp->waitsince) / (60LL*1000*1000*1000);
-
- runtime·printf("goroutine %D [%S", gp->goid, status);
- if(waitfor >= 1)
- runtime·printf(", %D minutes", waitfor);
- if(gp->lockedm != nil)
- runtime·printf(", locked to thread");
- runtime·printf("]:\n");
-}
-
static void
dumpgstatus(G* gp)
{
runtime·printf("runtime: gp=%p, goid=%D, gp->atomicstatus=%d\n", gp, gp->goid, runtime·readgstatus(gp));
}
-void
-runtime·tracebackothers(G *me)
-{
- G *gp;
- int32 traceback;
- uintptr i;
- uint32 status;
-
- traceback = runtime·gotraceback(nil);
-
- // Show the current goroutine first, if we haven't already.
- if((gp = g->m->curg) != nil && gp != me) {
- runtime·printf("\n");
- runtime·goroutineheader(gp);
- runtime·traceback(~(uintptr)0, ~(uintptr)0, 0, gp);
- }
-
- runtime·lock(&allglock);
- for(i = 0; i < runtime·allglen; i++) {
- gp = runtime·allg[i];
- if(gp == me || gp == g->m->curg || runtime·readgstatus(gp) == Gdead)
- continue;
- if(gp->issystem && traceback < 2)
- continue;
- runtime·printf("\n");
- runtime·goroutineheader(gp);
- status = runtime·readgstatus(gp);
- if((status&~Gscan) == Grunning){
- runtime·printf("\tgoroutine running on other thread; stack unavailable\n");
- runtime·printcreatedby(gp);
- } else
- runtime·traceback(~(uintptr)0, ~(uintptr)0, 0, gp);
- }
- runtime·unlock(&allglock);
-}
-
static void
checkmcount(void)
{
@@ -3373,23 +3268,6 @@ runtime·testSchedLocalQueueSteal(void)
}
}
-extern void runtime·morestack(void);
-uintptr runtime·externalthreadhandlerp;
-
-// Does f mark the top of a goroutine stack?
-bool
-runtime·topofstack(Func *f)
-{
- return f->entry == (uintptr)runtime·goexit ||
- f->entry == (uintptr)runtime·mstart ||
- f->entry == (uintptr)runtime·mcall ||
- f->entry == (uintptr)runtime·onM ||
- f->entry == (uintptr)runtime·morestack ||
- f->entry == (uintptr)runtime·lessstack ||
- f->entry == (uintptr)_rt0_go ||
- (runtime·externalthreadhandlerp != 0 && f->entry == runtime·externalthreadhandlerp);
-}
-
void
runtime·setmaxthreads_m(void)
{
diff --git a/src/pkg/runtime/rt0_darwin_386.s b/src/pkg/runtime/rt0_darwin_386.s
index 4f85250c2..7fe1df4c9 100644
--- a/src/pkg/runtime/rt0_darwin_386.s
+++ b/src/pkg/runtime/rt0_darwin_386.s
@@ -13,4 +13,4 @@ TEXT _rt0_386_darwin(SB),NOSPLIT,$8
INT $3
TEXT main(SB),NOSPLIT,$0
- JMP _rt0_go(SB)
+ JMP runtime·rt0_go(SB)
diff --git a/src/pkg/runtime/rt0_darwin_amd64.s b/src/pkg/runtime/rt0_darwin_amd64.s
index 8d2962b03..ac323c83c 100644
--- a/src/pkg/runtime/rt0_darwin_amd64.s
+++ b/src/pkg/runtime/rt0_darwin_amd64.s
@@ -11,5 +11,5 @@ TEXT _rt0_amd64_darwin(SB),NOSPLIT,$-8
JMP AX
TEXT main(SB),NOSPLIT,$-8
- MOVQ $_rt0_go(SB), AX
+ MOVQ $runtime·rt0_go(SB), AX
JMP AX
diff --git a/src/pkg/runtime/rt0_dragonfly_386.s b/src/pkg/runtime/rt0_dragonfly_386.s
index b857f6039..9262a0f9e 100644
--- a/src/pkg/runtime/rt0_dragonfly_386.s
+++ b/src/pkg/runtime/rt0_dragonfly_386.s
@@ -13,4 +13,4 @@ TEXT _rt0_386_dragonfly(SB),NOSPLIT,$8
INT $3
TEXT main(SB),NOSPLIT,$0
- JMP _rt0_go(SB)
+ JMP runtime·rt0_go(SB)
diff --git a/src/pkg/runtime/rt0_dragonfly_amd64.s b/src/pkg/runtime/rt0_dragonfly_amd64.s
index fc7e74598..a83b20e22 100644
--- a/src/pkg/runtime/rt0_dragonfly_amd64.s
+++ b/src/pkg/runtime/rt0_dragonfly_amd64.s
@@ -11,5 +11,5 @@ TEXT _rt0_amd64_dragonfly(SB),NOSPLIT,$-8
JMP AX
TEXT main(SB),NOSPLIT,$-8
- MOVQ $_rt0_go(SB), AX
+ MOVQ $runtime·rt0_go(SB), AX
JMP AX
diff --git a/src/pkg/runtime/rt0_freebsd_386.s b/src/pkg/runtime/rt0_freebsd_386.s
index 758f7d268..242b67df5 100644
--- a/src/pkg/runtime/rt0_freebsd_386.s
+++ b/src/pkg/runtime/rt0_freebsd_386.s
@@ -13,4 +13,4 @@ TEXT _rt0_386_freebsd(SB),NOSPLIT,$8
INT $3
TEXT main(SB),NOSPLIT,$0
- JMP _rt0_go(SB)
+ JMP runtime·rt0_go(SB)
diff --git a/src/pkg/runtime/rt0_freebsd_amd64.s b/src/pkg/runtime/rt0_freebsd_amd64.s
index 3cf7163b5..729effbdb 100644
--- a/src/pkg/runtime/rt0_freebsd_amd64.s
+++ b/src/pkg/runtime/rt0_freebsd_amd64.s
@@ -11,5 +11,5 @@ TEXT _rt0_amd64_freebsd(SB),NOSPLIT,$-8
JMP AX
TEXT main(SB),NOSPLIT,$-8
- MOVQ $_rt0_go(SB), AX
+ MOVQ $runtime·rt0_go(SB), AX
JMP AX
diff --git a/src/pkg/runtime/rt0_freebsd_arm.s b/src/pkg/runtime/rt0_freebsd_arm.s
index 56219f899..d50c73c23 100644
--- a/src/pkg/runtime/rt0_freebsd_arm.s
+++ b/src/pkg/runtime/rt0_freebsd_arm.s
@@ -10,9 +10,9 @@ TEXT _rt0_arm_freebsd(SB),NOSPLIT,$-4
MOVW (R13), R0 // argc
MOVW $4(R13), R1 // argv
MOVM.DB.W [R0-R1], (R13)
- B _rt0_go(SB)
+ B runtime·rt0_go(SB)
TEXT main(SB),NOSPLIT,$-4
MOVM.DB.W [R0-R1], (R13)
- MOVW $_rt0_go(SB), R4
+ MOVW $runtime·rt0_go(SB), R4
B (R4)
diff --git a/src/pkg/runtime/rt0_linux_386.s b/src/pkg/runtime/rt0_linux_386.s
index c6f4159ce..285aeed73 100644
--- a/src/pkg/runtime/rt0_linux_386.s
+++ b/src/pkg/runtime/rt0_linux_386.s
@@ -14,7 +14,7 @@ TEXT _rt0_386_linux(SB),NOSPLIT,$8
INT $3
TEXT main(SB),NOSPLIT,$0
- JMP _rt0_go(SB)
+ JMP runtime·rt0_go(SB)
TEXT _fallback_vdso(SB),NOSPLIT,$0
INT $0x80
diff --git a/src/pkg/runtime/rt0_linux_amd64.s b/src/pkg/runtime/rt0_linux_amd64.s
index a887ced8f..7f8c79548 100644
--- a/src/pkg/runtime/rt0_linux_amd64.s
+++ b/src/pkg/runtime/rt0_linux_amd64.s
@@ -11,5 +11,5 @@ TEXT _rt0_amd64_linux(SB),NOSPLIT,$-8
JMP AX
TEXT main(SB),NOSPLIT,$-8
- MOVQ $_rt0_go(SB), AX
+ MOVQ $runtime·rt0_go(SB), AX
JMP AX
diff --git a/src/pkg/runtime/rt0_linux_arm.s b/src/pkg/runtime/rt0_linux_arm.s
index 309fa2f79..21391c730 100644
--- a/src/pkg/runtime/rt0_linux_arm.s
+++ b/src/pkg/runtime/rt0_linux_arm.s
@@ -56,7 +56,7 @@ TEXT _rt0_arm_linux1(SB),NOSPLIT,$-4
SUB $4, R13 // fake a stack frame for runtime·setup_auxv
BL runtime·setup_auxv(SB)
ADD $4, R13
- B _rt0_go(SB)
+ B runtime·rt0_go(SB)
TEXT bad_abi<>(SB),NOSPLIT,$-4
// give diagnosis and exit
diff --git a/src/pkg/runtime/rt0_nacl_386.s b/src/pkg/runtime/rt0_nacl_386.s
index 8b713548f..e374bf335 100644
--- a/src/pkg/runtime/rt0_nacl_386.s
+++ b/src/pkg/runtime/rt0_nacl_386.s
@@ -19,4 +19,4 @@ TEXT _rt0_386_nacl(SB),NOSPLIT,$8
INT $3
TEXT main(SB),NOSPLIT,$0
- JMP _rt0_go(SB)
+ JMP runtime·rt0_go(SB)
diff --git a/src/pkg/runtime/rt0_nacl_amd64p32.s b/src/pkg/runtime/rt0_nacl_amd64p32.s
index 502d2e2bf..de08618fc 100644
--- a/src/pkg/runtime/rt0_nacl_amd64p32.s
+++ b/src/pkg/runtime/rt0_nacl_amd64p32.s
@@ -27,4 +27,4 @@ TEXT main(SB),NOSPLIT,$0
// Uncomment for fake time like on Go Playground.
//MOVQ $1257894000000000000, AX
//MOVQ AX, runtime·timens(SB)
- JMP _rt0_go(SB)
+ JMP runtime·rt0_go(SB)
diff --git a/src/pkg/runtime/rt0_nacl_arm.s b/src/pkg/runtime/rt0_nacl_arm.s
index df84d5d02..243cb3375 100644
--- a/src/pkg/runtime/rt0_nacl_arm.s
+++ b/src/pkg/runtime/rt0_nacl_arm.s
@@ -17,4 +17,4 @@ TEXT _rt0_arm_nacl(SB),NOSPLIT,$-4
B main(SB)
TEXT main(SB),NOSPLIT,$0
- B _rt0_go(SB)
+ B runtime·rt0_go(SB)
diff --git a/src/pkg/runtime/rt0_netbsd_386.s b/src/pkg/runtime/rt0_netbsd_386.s
index eb348fcee..f4cc78a1b 100644
--- a/src/pkg/runtime/rt0_netbsd_386.s
+++ b/src/pkg/runtime/rt0_netbsd_386.s
@@ -13,4 +13,4 @@ TEXT _rt0_386_netbsd(SB),NOSPLIT,$8
INT $3
TEXT main(SB),NOSPLIT,$0
- JMP _rt0_go(SB)
+ JMP runtime·rt0_go(SB)
diff --git a/src/pkg/runtime/rt0_netbsd_amd64.s b/src/pkg/runtime/rt0_netbsd_amd64.s
index c8e3fb18c..e2288dbae 100644
--- a/src/pkg/runtime/rt0_netbsd_amd64.s
+++ b/src/pkg/runtime/rt0_netbsd_amd64.s
@@ -11,5 +11,5 @@ TEXT _rt0_amd64_netbsd(SB),NOSPLIT,$-8
JMP AX
TEXT main(SB),NOSPLIT,$-8
- MOVQ $_rt0_go(SB), AX
+ MOVQ $runtime·rt0_go(SB), AX
JMP AX
diff --git a/src/pkg/runtime/rt0_netbsd_arm.s b/src/pkg/runtime/rt0_netbsd_arm.s
index 36effc3c5..1f649d97c 100644
--- a/src/pkg/runtime/rt0_netbsd_arm.s
+++ b/src/pkg/runtime/rt0_netbsd_arm.s
@@ -10,4 +10,4 @@ TEXT _rt0_arm_netbsd(SB),NOSPLIT,$-4
MOVW (R13), R0 // argc
MOVW $4(R13), R1 // argv
MOVM.DB.W [R0-R1], (R13)
- B _rt0_go(SB)
+ B runtime·rt0_go(SB)
diff --git a/src/pkg/runtime/rt0_openbsd_386.s b/src/pkg/runtime/rt0_openbsd_386.s
index 9e80f69be..35439d0d5 100644
--- a/src/pkg/runtime/rt0_openbsd_386.s
+++ b/src/pkg/runtime/rt0_openbsd_386.s
@@ -13,4 +13,4 @@ TEXT _rt0_386_openbsd(SB),NOSPLIT,$8
INT $3
TEXT main(SB),NOSPLIT,$0
- JMP _rt0_go(SB)
+ JMP runtime·rt0_go(SB)
diff --git a/src/pkg/runtime/rt0_openbsd_amd64.s b/src/pkg/runtime/rt0_openbsd_amd64.s
index b1ad403b7..a394890f9 100644
--- a/src/pkg/runtime/rt0_openbsd_amd64.s
+++ b/src/pkg/runtime/rt0_openbsd_amd64.s
@@ -11,5 +11,5 @@ TEXT _rt0_amd64_openbsd(SB),NOSPLIT,$-8
JMP AX
TEXT main(SB),NOSPLIT,$-8
- MOVQ $_rt0_go(SB), AX
+ MOVQ $runtime·rt0_go(SB), AX
JMP AX
diff --git a/src/pkg/runtime/rt0_plan9_386.s b/src/pkg/runtime/rt0_plan9_386.s
index a8ae50841..4aaabfaa4 100644
--- a/src/pkg/runtime/rt0_plan9_386.s
+++ b/src/pkg/runtime/rt0_plan9_386.s
@@ -14,7 +14,7 @@ TEXT _rt0_386_plan9(SB),NOSPLIT,$12
MOVL AX, 0(SP)
LEAL inargv+0(FP), AX
MOVL AX, 4(SP)
- CALL _rt0_go(SB)
+ CALL runtime·rt0_go(SB)
DATA runtime·isplan9(SB)/4, $1
GLOBL runtime·isplan9(SB), $4
diff --git a/src/pkg/runtime/rt0_plan9_amd64.s b/src/pkg/runtime/rt0_plan9_amd64.s
index 96d00584d..9f20eef60 100644
--- a/src/pkg/runtime/rt0_plan9_amd64.s
+++ b/src/pkg/runtime/rt0_plan9_amd64.s
@@ -11,7 +11,7 @@ TEXT _rt0_amd64_plan9(SB),NOSPLIT,$24
MOVL $1, _nprivates(SB)
MOVL inargc-8(FP), DI
LEAQ inargv+0(FP), SI
- MOVQ $_rt0_go(SB), AX
+ MOVQ $runtime·rt0_go(SB), AX
JMP AX
DATA runtime·isplan9(SB)/4, $1
diff --git a/src/pkg/runtime/rt0_solaris_amd64.s b/src/pkg/runtime/rt0_solaris_amd64.s
index 4aca991f0..fd0a79cc9 100644
--- a/src/pkg/runtime/rt0_solaris_amd64.s
+++ b/src/pkg/runtime/rt0_solaris_amd64.s
@@ -11,7 +11,7 @@ TEXT _rt0_amd64_solaris(SB),NOSPLIT,$-8
JMP AX
TEXT main(SB),NOSPLIT,$-8
- MOVQ $_rt0_go(SB), AX
+ MOVQ $runtime·rt0_go(SB), AX
JMP AX
DATA runtime·issolaris(SB)/4, $1
diff --git a/src/pkg/runtime/rt0_windows_386.s b/src/pkg/runtime/rt0_windows_386.s
index 594e2cd34..d4008ad5d 100644
--- a/src/pkg/runtime/rt0_windows_386.s
+++ b/src/pkg/runtime/rt0_windows_386.s
@@ -13,7 +13,7 @@ TEXT _rt0_386_windows(SB),NOSPLIT,$12
JMP main(SB)
TEXT main(SB),NOSPLIT,$0
- JMP _rt0_go(SB)
+ JMP runtime·rt0_go(SB)
DATA runtime·iswindows(SB)/4, $1
diff --git a/src/pkg/runtime/rt0_windows_amd64.s b/src/pkg/runtime/rt0_windows_amd64.s
index 32e18b02b..0b144717b 100644
--- a/src/pkg/runtime/rt0_windows_amd64.s
+++ b/src/pkg/runtime/rt0_windows_amd64.s
@@ -12,7 +12,7 @@ TEXT _rt0_amd64_windows(SB),NOSPLIT,$-8
JMP AX
TEXT main(SB),NOSPLIT,$-8
- MOVQ $_rt0_go(SB), AX
+ MOVQ $runtime·rt0_go(SB), AX
JMP AX
DATA runtime·iswindows(SB)/4, $1
diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h
index f1b3ee83f..3cc6f9a81 100644
--- a/src/pkg/runtime/runtime.h
+++ b/src/pkg/runtime/runtime.h
@@ -882,7 +882,6 @@ void runtime·netpolllock(PollDesc*);
void runtime·netpollunlock(PollDesc*);
void runtime·crash(void);
void runtime·parsedebugvars(void);
-void _rt0_go(void);
void* runtime·funcdata(Func*, int32);
void runtime·setmaxthreads_m(void);
G* runtime·timejump(void);
diff --git a/src/pkg/runtime/stubs.go b/src/pkg/runtime/stubs.go
index cdcf4b367..86dc47f4a 100644
--- a/src/pkg/runtime/stubs.go
+++ b/src/pkg/runtime/stubs.go
@@ -138,9 +138,6 @@ func entersyscall()
func entersyscallblock()
func exitsyscall()
-func goroutineheader(gp *g)
-func tracebackothers(gp *g)
-
func cgocallback(fn, frame unsafe.Pointer, framesize uintptr)
func gogo(buf *gobuf)
func gosave(buf *gobuf)
@@ -260,4 +257,3 @@ var newproc, deferproc, lessstack struct{} // C/assembly functions
func funcspdelta(*_func, uintptr) int32 // symtab.c
func funcarglen(*_func, uintptr) int32 // symtab.c
const _ArgsSizeUnknown = -0x80000000 // funcdata.h
-func topofstack(*_func) bool // proc.c
diff --git a/src/pkg/runtime/traceback.go b/src/pkg/runtime/traceback.go
index c6a6c056c..26d0f5fc9 100644
--- a/src/pkg/runtime/traceback.go
+++ b/src/pkg/runtime/traceback.go
@@ -32,12 +32,7 @@ const usesLR = GOARCH != "amd64" && GOARCH != "amd64p32" && GOARCH != "386"
// jmpdeferPC is the PC at the beginning of the jmpdefer assembly function.
// The traceback needs to recognize it on link register architectures.
-var jmpdeferPC uintptr
-
-func init() {
- f := jmpdefer
- jmpdeferPC = **(**uintptr)(unsafe.Pointer(&f))
-}
+var jmpdeferPC = funcPC(jmpdefer)
// System-specific hook. See traceback_windows.go
var systraceback func(*_func, *stkframe, *g, bool, func(*stkframe, unsafe.Pointer) bool, unsafe.Pointer) (changed, aborted bool)
@@ -502,3 +497,117 @@ func callers(skip int, pcbuf *uintptr, m int) int {
func gcallers(gp *g, skip int, pcbuf *uintptr, m int) int {
return gentraceback(^uintptr(0), ^uintptr(0), 0, gp, skip, pcbuf, m, nil, nil, false)
}
+
+var gStatusStrings = [...]string{
+ _Gidle: "idle",
+ _Grunnable: "runnable",
+ _Grunning: "running",
+ _Gsyscall: "syscall",
+ _Gwaiting: "waiting",
+ _Gdead: "dead",
+ _Genqueue: "enqueue",
+ _Gcopystack: "copystack",
+}
+
+var gScanStatusStrings = [...]string{
+ 0: "scan",
+ _Grunnable: "scanrunnable",
+ _Grunning: "scanrunning",
+ _Gsyscall: "scansyscall",
+ _Gwaiting: "scanwaiting",
+ _Gdead: "scandead",
+ _Genqueue: "scanenqueue",
+}
+
+func goroutineheader(gp *g) {
+ gpstatus := readgstatus(gp)
+
+ // Basic string status
+ var status string
+ if 0 <= gpstatus && gpstatus < uint32(len(gStatusStrings)) {
+ status = gStatusStrings[gpstatus]
+ } else if gpstatus&_Gscan != 0 && 0 <= gpstatus&^_Gscan && gpstatus&^_Gscan < uint32(len(gStatusStrings)) {
+ status = gStatusStrings[gpstatus&^_Gscan]
+ } else {
+ status = "???"
+ }
+
+ // Override.
+ if (gpstatus == _Gwaiting || gpstatus == _Gscanwaiting) && gp.waitreason != "" {
+ status = gp.waitreason
+ }
+
+ // approx time the G is blocked, in minutes
+ var waitfor int64
+ gpstatus &^= _Gscan // drop the scan bit
+ if (gpstatus == _Gwaiting || gpstatus == _Gsyscall) && gp.waitsince != 0 {
+ waitfor = (nanotime() - gp.waitsince) / 60e9
+ }
+ print("goroutine ", gp.goid, " [", status)
+ if waitfor >= 1 {
+ print(", ", waitfor, " minutes")
+ }
+ if gp.lockedm != nil {
+ print(", locked to thread")
+ }
+ print("]:\n")
+}
+
+func tracebackothers(me *g) {
+ level := gotraceback(nil)
+
+ // Show the current goroutine first, if we haven't already.
+ g := getg()
+ gp := g.m.curg
+ if gp != nil && gp != me {
+ print("\n")
+ goroutineheader(gp)
+ traceback(^uintptr(0), ^uintptr(0), 0, gp)
+ }
+
+ lock(&allglock)
+ for _, gp := range allgs {
+ if gp == me || gp == g.m.curg || readgstatus(gp) == _Gdead || gp.issystem && level < 2 {
+ continue
+ }
+ print("\n")
+ goroutineheader(gp)
+ if readgstatus(gp)&^_Gscan == _Grunning {
+ print("\tgoroutine running on other thread; stack unavailable\n")
+ printcreatedby(gp)
+ } else {
+ traceback(^uintptr(0), ^uintptr(0), 0, gp)
+ }
+ }
+ unlock(&allglock)
+}
+
+func goexit()
+func mstart()
+func morestack()
+func rt0_go()
+
+var (
+ goexitPC = funcPC(goexit)
+ mstartPC = funcPC(mstart)
+ mcallPC = funcPC(mcall)
+ onMPC = funcPC(onM)
+ morestackPC = funcPC(morestack)
+ lessstackPC = funcPC(lessstack)
+ rt0_goPC = funcPC(rt0_go)
+
+ externalthreadhandlerp uintptr // initialized elsewhere
+)
+
+// Does f mark the top of a goroutine stack?
+func topofstack(f *_func) bool {
+ pc := f.entry
+ return pc == goexitPC ||
+ pc == mstartPC ||
+ pc == mcallPC ||
+ pc == onMPC ||
+ pc == morestackPC ||
+ pc == lessstackPC ||
+ pc == rt0_goPC ||
+ externalthreadhandlerp != 0 && pc == externalthreadhandlerp
+}
diff --git a/src/pkg/runtime/traceback_windows.go b/src/pkg/runtime/traceback_windows.go
index 206f93c46..892bed04c 100644
--- a/src/pkg/runtime/traceback_windows.go
+++ b/src/pkg/runtime/traceback_windows.go
@@ -13,8 +13,7 @@ var sigtrampPC uintptr
var sigtramp struct{} // assembly function
func init() {
- f := sigtramp
- sigtrampPC = **(**uintptr)(unsafe.Pointer(&f))
+ sigtrampPC = funcPC(sigtramp)
systraceback = traceback_windows
}