]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/runtime/trace.go
runtime: add execution tracer v2 behind GOEXPERIMENT=exectracer2
[gostls13.git] / src / runtime / trace.go
index a3bcdee010695eed1d3fd56ae75d1742ebb70106..48e939e38f5c5cdf09a7caa9dd6da4c9f3a73991 100644 (file)
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+//go:build !goexperiment.exectracer2
+
 // Go execution tracer.
 // The tracer captures a wide range of execution events like goroutine
 // creation/blocking/unblocking, syscall enter/exit/block, GC-related events,
@@ -198,6 +200,9 @@ type gTraceState struct {
        lastP              puintptr  // last P emitted an event for this goroutine
 }
 
+// Unused; for compatibility with the new tracer.
+func (s *gTraceState) reset() {}
+
 // mTraceState is per-M state for the tracer.
 type mTraceState struct {
        startingTrace  bool // this M is in TraceStart, potentially before traceEnabled is true
@@ -770,6 +775,13 @@ func traceProcFree(pp *p) {
        unlock(&trace.lock)
 }
 
+// ThreadDestroy is a no-op. It exists as a stub to support the new tracer.
+//
+// This must run on the system stack, just to match the new tracer.
+func traceThreadDestroy(_ *m) {
+       // No-op in old tracer.
+}
+
 // traceFullQueue queues buf into queue of full buffers.
 func traceFullQueue(buf traceBufPtr) {
        buf.ptr().link = 0
@@ -902,7 +914,7 @@ func traceEventLocked(extraBytes int, mp *m, pid int32, bufp *traceBufPtr, ev by
 // traceCPUSample writes a CPU profile sample stack to the execution tracer's
 // profiling buffer. It is called from a signal handler, so is limited in what
 // it can do.
-func traceCPUSample(gp *g, pp *p, stk []uintptr) {
+func traceCPUSample(gp *g, _ *m, pp *p, stk []uintptr) {
        if !traceEnabled() {
                // Tracing is usually turned off; don't spend time acquiring the signal
                // lock unless it's active.
@@ -1702,7 +1714,10 @@ func (_ traceLocker) GoSysCall() {
        traceEvent(traceEvGoSysCall, skip)
 }
 
-func (_ traceLocker) GoSysExit() {
+func (_ traceLocker) GoSysExit(lostP bool) {
+       if !lostP {
+               throw("lostP must always be true in the old tracer for GoSysExit")
+       }
        gp := getg().m.curg
        if !gp.trace.tracedSyscallEnter {
                // There was no syscall entry traced for us at all, so there's definitely
@@ -1729,6 +1744,22 @@ func (_ traceLocker) GoSysExit() {
        traceEvent(traceEvGoSysExit, -1, gp.goid, gp.trace.seq, uint64(ts))
 }
 
+// nosplit because it's called from exitsyscall without a P.
+//
+//go:nosplit
+func (_ traceLocker) RecordSyscallExitedTime(gp *g, oldp *p) {
+       // Wait till traceGoSysBlock event is emitted.
+       // This ensures consistency of the trace (the goroutine is started after it is blocked).
+       for oldp != nil && oldp.syscalltick == gp.m.syscalltick {
+               osyield()
+       }
+       // We can't trace syscall exit right now because we don't have a P.
+       // Tracing code can invoke write barriers that cannot run without a P.
+       // So instead we remember the syscall exit time and emit the event
+       // in execute when we have a P.
+       gp.trace.sysExitTime = traceClockNow()
+}
+
 func (_ traceLocker) GoSysBlock(pp *p) {
        // Sysmon and stopTheWorld can declare syscalls running on remote Ps as blocked,
        // to handle this we temporary employ the P.
@@ -1740,6 +1771,10 @@ func (_ traceLocker) GoSysBlock(pp *p) {
        releasem(mp)
 }
 
+func (t traceLocker) ProcSteal(pp *p, forMe bool) {
+       t.ProcStop(pp)
+}
+
 func (_ traceLocker) HeapAlloc(live uint64) {
        traceEvent(traceEvHeapAlloc, -1, live)
 }
@@ -1858,6 +1893,14 @@ func (tl traceLocker) OneNewExtraM(gp *g) {
        traceEvent(traceEvGoInSyscall, -1, gp.goid)
 }
 
+// Used only in the new tracer.
+func (tl traceLocker) GoCreateSyscall(gp *g) {
+}
+
+// Used only in the new tracer.
+func (tl traceLocker) GoDestroySyscall() {
+}
+
 // traceTime represents a timestamp for the trace.
 type traceTime uint64
 
@@ -1871,3 +1914,12 @@ type traceTime uint64
 func traceClockNow() traceTime {
        return traceTime(cputicks() / traceTimeDiv)
 }
+
+func traceExitingSyscall() {
+}
+
+func traceExitedSyscall() {
+}
+
+// Not used in the old tracer. Defined for compatibility.
+const defaultTraceAdvancePeriod = 0