]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix windows cpu profiler
authorDmitriy Vyukov <dvyukov@google.com>
Fri, 14 Feb 2014 05:20:51 +0000 (09:20 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Fri, 14 Feb 2014 05:20:51 +0000 (09:20 +0400)
Currently it periodically fails with the following message.
The immediate cause is the wrong base register when obtaining g
in sys_windows_amd64/386.s.
But there are several secondary problems as well.

runtime: unknown pc 0x0 after stack split
panic: invalid memory address or nil pointer dereference
fatal error: panic during malloc
[signal 0xc0000005 code=0x0 addr=0x60 pc=0x42267a]

runtime stack:
runtime.panic(0x7914c0, 0xc862af)
        c:/src/perfer/work/windows-amd64-a15f344a9efa/go/src/pkg/runtime/panic.c:217 +0x2c
runtime: unexpected return pc for runtime.externalthreadhandler called from 0x0

R=rsc, alex.brainman
CC=golang-codereviews
https://golang.org/cl/63310043

src/pkg/runtime/os_windows.c
src/pkg/runtime/proc.c
src/pkg/runtime/sys_windows_386.s
src/pkg/runtime/sys_windows_amd64.s

index 6c9d687b7018a372230457ad333f74f39d652e23..8815aee9f94c54c39cb1dddf1a54730e178e6964 100644 (file)
@@ -71,6 +71,9 @@ extern void *runtime·WriteFile;
 
 void *runtime·GetQueuedCompletionStatusEx;
 
+extern uintptr runtime·externalthreadhandlerp;
+void runtime·externalthreadhandler(void);
+
 static int32
 getproccount(void)
 {
@@ -86,6 +89,8 @@ runtime·osinit(void)
        void *kernel32;
        void *SetProcessPriorityBoost;
 
+       runtime·externalthreadhandlerp = (uintptr)runtime·externalthreadhandler;
+
        runtime·stdcall(runtime·SetConsoleCtrlHandler, 2, runtime·ctrlhandler, (uintptr)1);
        runtime·stdcall(runtime·timeBeginPeriod, 1, (uintptr)1);
        runtime·ncpu = getproccount();
@@ -293,9 +298,11 @@ runtime·stdcall(void *fn, int32 count, ...)
        m->libcall.args = (uintptr*)&count + 1;
        if(m->profilehz != 0) {
                // leave pc/sp for cpu profiler
+               m->libcallg = g;
                m->libcallpc = (uintptr)runtime·getcallerpc(&fn);
+               // sp must be the last, because once async cpu profiler finds
+               // all three values to be non-zero, it will use them
                m->libcallsp = (uintptr)runtime·getcallersp(&fn);
-               m->libcallg = g;
        }
        runtime·asmcgocall(runtime·asmstdcall, &m->libcall);
        m->libcallsp = 0;
index 88d6acead3c0da68c0f63c989c4a890b568d7163..47cb30408375dba407771ea5dbc17e723d889870 100644 (file)
@@ -3029,6 +3029,7 @@ runtime·testSchedLocalQueueSteal(void)
 }
 
 extern void runtime·morestack(void);
+uintptr runtime·externalthreadhandlerp;
 
 // Does f mark the top of a goroutine stack?
 bool
@@ -3039,7 +3040,8 @@ runtime·topofstack(Func *f)
                f->entry == (uintptr)runtime·mcall ||
                f->entry == (uintptr)runtime·morestack ||
                f->entry == (uintptr)runtime·lessstack ||
-               f->entry == (uintptr)_rt0_go;
+               f->entry == (uintptr)_rt0_go ||
+               (runtime·externalthreadhandlerp != 0 && f->entry == runtime·externalthreadhandlerp);
 }
 
 void
index af10ca8644bc959401dc2d26920c32d8487bd0a2..2755d5001cce12a68fe69bacc2d0e99955ab95ae 100644 (file)
@@ -347,10 +347,12 @@ TEXT runtime·usleep1(SB),NOSPLIT,$0
        // leave pc/sp for cpu profiler
        MOVL    (SP), SI
        MOVL    SI, m_libcallpc(BP)
+       MOVL    g(CX), SI
+       MOVL    SI, m_libcallg(BP)
+       // sp must be the last, because once async cpu profiler finds
+       // all three values to be non-zero, it will use them
        LEAL    4(SP), SI
        MOVL    SI, m_libcallsp(BP)
-       MOVL    g(BP), SI
-       MOVL    SI, m_libcallg(BP)
 
        MOVL    m_g0(BP), SI
        CMPL    g(CX), SI
index 6576c4283ca2960fa11fce95ecf939ae56909aee..288cd7748fd03855a3910a16c40cf08d434c62dc 100644 (file)
@@ -342,10 +342,12 @@ TEXT runtime·usleep1(SB),NOSPLIT,$0
        // leave pc/sp for cpu profiler
        MOVQ    (SP), R12
        MOVQ    R12, m_libcallpc(R13)
+       MOVQ    g(R15), R12
+       MOVQ    R12, m_libcallg(R13)
+       // sp must be the last, because once async cpu profiler finds
+       // all three values to be non-zero, it will use them
        LEAQ    8(SP), R12
        MOVQ    R12, m_libcallsp(R13)
-       MOVQ    g(R13), R12
-       MOVQ    R12, m_libcallg(R13)
 
        MOVQ    m_g0(R13), R14
        CMPQ    g(R15), R14