Source file 
src/runtime/traceruntime.go
     1  
     2  
     3  
     4  
     5  
     6  
     7  package runtime
     8  
     9  import (
    10  	"internal/runtime/atomic"
    11  	"internal/trace/tracev2"
    12  	_ "unsafe" 
    13  )
    14  
    15  
    16  type gTraceState struct {
    17  	traceSchedResourceState
    18  }
    19  
    20  
    21  func (s *gTraceState) reset() {
    22  	s.seq = [2]uint64{}
    23  	
    24  }
    25  
    26  
    27  type mTraceState struct {
    28  	seqlock       atomic.Uintptr                       
    29  	buf           [2][tracev2.NumExperiments]*traceBuf 
    30  	link          *m                                   
    31  	reentered     uint32                               
    32  	oldthrowsplit bool                                 
    33  }
    34  
    35  
    36  type pTraceState struct {
    37  	traceSchedResourceState
    38  
    39  	
    40  	mSyscallID int64
    41  
    42  	
    43  	
    44  	
    45  	maySweep bool
    46  
    47  	
    48  	inSweep bool
    49  
    50  	
    51  	
    52  	swept, reclaimed uintptr
    53  }
    54  
    55  
    56  func traceLockInit() {
    57  	
    58  	
    59  	lockInit(&trace.stringTab[0].lock, lockRankTraceStrings)
    60  	lockInit(&trace.stringTab[0].tab.mem.lock, lockRankTraceStrings)
    61  	lockInit(&trace.stringTab[1].lock, lockRankTraceStrings)
    62  	lockInit(&trace.stringTab[1].tab.mem.lock, lockRankTraceStrings)
    63  	lockInit(&trace.stackTab[0].tab.mem.lock, lockRankTraceStackTab)
    64  	lockInit(&trace.stackTab[1].tab.mem.lock, lockRankTraceStackTab)
    65  	lockInit(&trace.typeTab[0].tab.mem.lock, lockRankTraceTypeTab)
    66  	lockInit(&trace.typeTab[1].tab.mem.lock, lockRankTraceTypeTab)
    67  	lockInit(&trace.lock, lockRankTrace)
    68  }
    69  
    70  
    71  
    72  
    73  
    74  
    75  
    76  func lockRankMayTraceFlush() {
    77  	lockWithRankMayAcquire(&trace.lock, getLockRank(&trace.lock))
    78  }
    79  
    80  
    81  
    82  
    83  
    84  
    85  
    86  
    87  type traceBlockReason uint8
    88  
    89  const (
    90  	traceBlockGeneric traceBlockReason = iota
    91  	traceBlockForever
    92  	traceBlockNet
    93  	traceBlockSelect
    94  	traceBlockCondWait
    95  	traceBlockSync
    96  	traceBlockChanSend
    97  	traceBlockChanRecv
    98  	traceBlockGCMarkAssist
    99  	traceBlockGCSweep
   100  	traceBlockSystemGoroutine
   101  	traceBlockPreempted
   102  	traceBlockDebugCall
   103  	traceBlockUntilGCEnds
   104  	traceBlockSleep
   105  	traceBlockGCWeakToStrongWait
   106  	traceBlockSynctest
   107  )
   108  
   109  var traceBlockReasonStrings = [...]string{
   110  	traceBlockGeneric:            "unspecified",
   111  	traceBlockForever:            "forever",
   112  	traceBlockNet:                "network",
   113  	traceBlockSelect:             "select",
   114  	traceBlockCondWait:           "sync.(*Cond).Wait",
   115  	traceBlockSync:               "sync",
   116  	traceBlockChanSend:           "chan send",
   117  	traceBlockChanRecv:           "chan receive",
   118  	traceBlockGCMarkAssist:       "GC mark assist wait for work",
   119  	traceBlockGCSweep:            "GC background sweeper wait",
   120  	traceBlockSystemGoroutine:    "system goroutine wait",
   121  	traceBlockPreempted:          "preempted",
   122  	traceBlockDebugCall:          "wait for debug call",
   123  	traceBlockUntilGCEnds:        "wait until GC ends",
   124  	traceBlockSleep:              "sleep",
   125  	traceBlockGCWeakToStrongWait: "GC weak to strong wait",
   126  	traceBlockSynctest:           "synctest",
   127  }
   128  
   129  
   130  
   131  
   132  
   133  type traceGoStopReason uint8
   134  
   135  const (
   136  	traceGoStopGeneric traceGoStopReason = iota
   137  	traceGoStopGoSched
   138  	traceGoStopPreempted
   139  )
   140  
   141  var traceGoStopReasonStrings = [...]string{
   142  	traceGoStopGeneric:   "unspecified",
   143  	traceGoStopGoSched:   "runtime.Gosched",
   144  	traceGoStopPreempted: "preempted",
   145  }
   146  
   147  
   148  
   149  
   150  func traceEnabled() bool {
   151  	return trace.enabled
   152  }
   153  
   154  
   155  
   156  
   157  
   158  func traceAllocFreeEnabled() bool {
   159  	return trace.enabledWithAllocFree
   160  }
   161  
   162  
   163  func traceShuttingDown() bool {
   164  	return trace.shutdown.Load()
   165  }
   166  
   167  
   168  
   169  
   170  type traceLocker struct {
   171  	mp  *m
   172  	gen uintptr
   173  }
   174  
   175  
   176  
   177  
   178  
   179  
   180  const debugTraceReentrancy = false
   181  
   182  
   183  
   184  
   185  
   186  
   187  func traceAcquire() traceLocker {
   188  	if !traceEnabled() {
   189  		return traceLocker{}
   190  	}
   191  	return traceAcquireEnabled()
   192  }
   193  
   194  
   195  
   196  
   197  
   198  
   199  
   200  
   201  func traceAcquireEnabled() traceLocker {
   202  	
   203  	
   204  	
   205  	lockRankMayTraceFlush()
   206  
   207  	
   208  	mp := acquirem()
   209  
   210  	
   211  	
   212  	
   213  	if mp.trace.seqlock.Load()%2 == 1 {
   214  		mp.trace.reentered++
   215  		return traceLocker{mp, trace.gen.Load()}
   216  	}
   217  
   218  	
   219  	
   220  	
   221  	
   222  	
   223  	
   224  	seq := mp.trace.seqlock.Add(1)
   225  	if debugTraceReentrancy && seq%2 != 1 {
   226  		throw("bad use of trace.seqlock")
   227  	}
   228  
   229  	
   230  	
   231  	
   232  	
   233  	
   234  	
   235  	
   236  	
   237  	gen := trace.gen.Load()
   238  	if gen == 0 {
   239  		mp.trace.seqlock.Add(1)
   240  		releasem(mp)
   241  		return traceLocker{}
   242  	}
   243  	return traceLocker{mp, gen}
   244  }
   245  
   246  
   247  
   248  
   249  
   250  
   251  func (tl traceLocker) ok() bool {
   252  	return tl.gen != 0
   253  }
   254  
   255  
   256  
   257  
   258  
   259  
   260  func traceRelease(tl traceLocker) {
   261  	if tl.mp.trace.reentered > 0 {
   262  		tl.mp.trace.reentered--
   263  	} else {
   264  		seq := tl.mp.trace.seqlock.Add(1)
   265  		if debugTraceReentrancy && seq%2 != 0 {
   266  			print("runtime: seq=", seq, "\n")
   267  			throw("bad use of trace.seqlock")
   268  		}
   269  	}
   270  	releasem(tl.mp)
   271  }
   272  
   273  
   274  
   275  
   276  func traceExitingSyscall() {
   277  	trace.exitingSyscall.Add(1)
   278  }
   279  
   280  
   281  func traceExitedSyscall() {
   282  	trace.exitingSyscall.Add(-1)
   283  }
   284  
   285  
   286  func (tl traceLocker) Gomaxprocs(procs int32) {
   287  	tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(tracev2.EvProcsChange, traceArg(procs), tl.stack(1))
   288  }
   289  
   290  
   291  
   292  
   293  func (tl traceLocker) ProcStart() {
   294  	pp := tl.mp.p.ptr()
   295  	
   296  	
   297  	
   298  	tl.eventWriter(tracev2.GoSyscall, tracev2.ProcIdle).event(tracev2.EvProcStart, traceArg(pp.id), pp.trace.nextSeq(tl.gen))
   299  }
   300  
   301  
   302  func (tl traceLocker) ProcStop(pp *p) {
   303  	
   304  	
   305  	tl.eventWriter(tracev2.GoSyscall, tracev2.ProcRunning).event(tracev2.EvProcStop)
   306  }
   307  
   308  
   309  
   310  
   311  
   312  func (tl traceLocker) GCActive() {
   313  	tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(tracev2.EvGCActive, traceArg(trace.seqGC))
   314  	
   315  	
   316  	trace.seqGC++
   317  }
   318  
   319  
   320  
   321  
   322  
   323  func (tl traceLocker) GCStart() {
   324  	tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(tracev2.EvGCBegin, traceArg(trace.seqGC), tl.stack(3))
   325  	
   326  	
   327  	trace.seqGC++
   328  }
   329  
   330  
   331  
   332  
   333  
   334  func (tl traceLocker) GCDone() {
   335  	tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(tracev2.EvGCEnd, traceArg(trace.seqGC))
   336  	
   337  	
   338  	trace.seqGC++
   339  }
   340  
   341  
   342  func (tl traceLocker) STWStart(reason stwReason) {
   343  	
   344  	
   345  	tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(tracev2.EvSTWBegin, tl.string(reason.String()), tl.stack(2))
   346  }
   347  
   348  
   349  func (tl traceLocker) STWDone() {
   350  	
   351  	
   352  	tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(tracev2.EvSTWEnd)
   353  }
   354  
   355  
   356  
   357  
   358  
   359  
   360  
   361  
   362  func (tl traceLocker) GCSweepStart() {
   363  	
   364  	
   365  	pp := tl.mp.p.ptr()
   366  	if pp.trace.maySweep {
   367  		throw("double traceGCSweepStart")
   368  	}
   369  	pp.trace.maySweep, pp.trace.swept, pp.trace.reclaimed = true, 0, 0
   370  }
   371  
   372  
   373  
   374  
   375  
   376  
   377  
   378  
   379  
   380  func (tl traceLocker) GCSweepSpan(bytesSwept uintptr) {
   381  	pp := tl.mp.p.ptr()
   382  	if pp.trace.maySweep {
   383  		if pp.trace.swept == 0 {
   384  			tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(tracev2.EvGCSweepBegin, tl.stack(1))
   385  			pp.trace.inSweep = true
   386  		}
   387  		pp.trace.swept += bytesSwept
   388  	}
   389  }
   390  
   391  
   392  
   393  
   394  
   395  
   396  func (tl traceLocker) GCSweepDone() {
   397  	pp := tl.mp.p.ptr()
   398  	if !pp.trace.maySweep {
   399  		throw("missing traceGCSweepStart")
   400  	}
   401  	if pp.trace.inSweep {
   402  		tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(tracev2.EvGCSweepEnd, traceArg(pp.trace.swept), traceArg(pp.trace.reclaimed))
   403  		pp.trace.inSweep = false
   404  	}
   405  	pp.trace.maySweep = false
   406  }
   407  
   408  
   409  func (tl traceLocker) GCMarkAssistStart() {
   410  	tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(tracev2.EvGCMarkAssistBegin, tl.stack(1))
   411  }
   412  
   413  
   414  func (tl traceLocker) GCMarkAssistDone() {
   415  	tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(tracev2.EvGCMarkAssistEnd)
   416  }
   417  
   418  
   419  func (tl traceLocker) GoCreate(newg *g, pc uintptr, blocked bool) {
   420  	newg.trace.setStatusTraced(tl.gen)
   421  	ev := tracev2.EvGoCreate
   422  	if blocked {
   423  		ev = tracev2.EvGoCreateBlocked
   424  	}
   425  	tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(ev, traceArg(newg.goid), tl.startPC(pc), tl.stack(2))
   426  }
   427  
   428  
   429  
   430  
   431  func (tl traceLocker) GoStart() {
   432  	gp := getg().m.curg
   433  	pp := gp.m.p
   434  	w := tl.eventWriter(tracev2.GoRunnable, tracev2.ProcRunning)
   435  	w.event(tracev2.EvGoStart, traceArg(gp.goid), gp.trace.nextSeq(tl.gen))
   436  	if pp.ptr().gcMarkWorkerMode != gcMarkWorkerNotWorker {
   437  		w.event(tracev2.EvGoLabel, trace.markWorkerLabels[tl.gen%2][pp.ptr().gcMarkWorkerMode])
   438  	}
   439  }
   440  
   441  
   442  
   443  
   444  func (tl traceLocker) GoEnd() {
   445  	tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(tracev2.EvGoDestroy)
   446  }
   447  
   448  
   449  func (tl traceLocker) GoSched() {
   450  	tl.GoStop(traceGoStopGoSched)
   451  }
   452  
   453  
   454  func (tl traceLocker) GoPreempt() {
   455  	tl.GoStop(traceGoStopPreempted)
   456  }
   457  
   458  
   459  func (tl traceLocker) GoStop(reason traceGoStopReason) {
   460  	tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(tracev2.EvGoStop, traceArg(trace.goStopReasons[tl.gen%2][reason]), tl.stack(0))
   461  }
   462  
   463  
   464  
   465  
   466  
   467  func (tl traceLocker) GoPark(reason traceBlockReason, skip int) {
   468  	tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(tracev2.EvGoBlock, traceArg(trace.goBlockReasons[tl.gen%2][reason]), tl.stack(skip))
   469  }
   470  
   471  
   472  func (tl traceLocker) GoUnpark(gp *g, skip int) {
   473  	
   474  	tl.emitUnblockStatus(gp, tl.gen)
   475  	tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(tracev2.EvGoUnblock, traceArg(gp.goid), gp.trace.nextSeq(tl.gen), tl.stack(skip))
   476  }
   477  
   478  
   479  
   480  func (tl traceLocker) GoSwitch(nextg *g, destroy bool) {
   481  	
   482  	tl.emitUnblockStatus(nextg, tl.gen)
   483  	w := tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning)
   484  	ev := tracev2.EvGoSwitch
   485  	if destroy {
   486  		ev = tracev2.EvGoSwitchDestroy
   487  	}
   488  	w.event(ev, traceArg(nextg.goid), nextg.trace.nextSeq(tl.gen))
   489  }
   490  
   491  
   492  
   493  func (tl traceLocker) emitUnblockStatus(gp *g, gen uintptr) {
   494  	if !gp.trace.statusWasTraced(gen) && gp.trace.acquireStatus(gen) {
   495  		
   496  		
   497  		
   498  		tl.writer().writeGoStatus(gp.goid, -1, tracev2.GoWaiting, gp.inMarkAssist, 0).end()
   499  	}
   500  }
   501  
   502  
   503  
   504  
   505  func (tl traceLocker) GoSysCall() {
   506  	
   507  	pp := tl.mp.p.ptr()
   508  	pp.trace.mSyscallID = int64(tl.mp.procid)
   509  	tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(tracev2.EvGoSyscallBegin, pp.trace.nextSeq(tl.gen), tl.stack(1))
   510  }
   511  
   512  
   513  
   514  
   515  
   516  
   517  
   518  
   519  
   520  
   521  func (tl traceLocker) GoSysExit(lostP bool) {
   522  	ev := tracev2.EvGoSyscallEnd
   523  	procStatus := tracev2.ProcSyscall 
   524  	if lostP {
   525  		ev = tracev2.EvGoSyscallEndBlocked
   526  		procStatus = tracev2.ProcRunning 
   527  	} else {
   528  		tl.mp.p.ptr().trace.mSyscallID = -1
   529  	}
   530  	tl.eventWriter(tracev2.GoSyscall, procStatus).event(ev)
   531  }
   532  
   533  
   534  
   535  
   536  
   537  
   538  func (tl traceLocker) ProcSteal(pp *p, inSyscall bool) {
   539  	
   540  	mStolenFrom := pp.trace.mSyscallID
   541  	pp.trace.mSyscallID = -1
   542  
   543  	
   544  	
   545  	
   546  	
   547  	
   548  	if !pp.trace.statusWasTraced(tl.gen) && pp.trace.acquireStatus(tl.gen) {
   549  		
   550  		
   551  		tl.writer().writeProcStatus(uint64(pp.id), tracev2.ProcSyscallAbandoned, pp.trace.inSweep).end()
   552  	}
   553  
   554  	
   555  	
   556  	
   557  	
   558  	
   559  	
   560  	goStatus := tracev2.GoRunning
   561  	procStatus := tracev2.ProcRunning
   562  	if inSyscall {
   563  		goStatus = tracev2.GoSyscall
   564  		procStatus = tracev2.ProcSyscallAbandoned
   565  	}
   566  	tl.eventWriter(goStatus, procStatus).event(tracev2.EvProcSteal, traceArg(pp.id), pp.trace.nextSeq(tl.gen), traceArg(mStolenFrom))
   567  }
   568  
   569  
   570  func (tl traceLocker) HeapAlloc(live uint64) {
   571  	tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(tracev2.EvHeapAlloc, traceArg(live))
   572  }
   573  
   574  
   575  func (tl traceLocker) HeapGoal() {
   576  	heapGoal := gcController.heapGoal()
   577  	
   578  	
   579  	if heapGoal == ^uint64(0) || gcController.gcPercent.Load() < 0 {
   580  		
   581  		heapGoal = 0
   582  	}
   583  	tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(tracev2.EvHeapGoal, traceArg(heapGoal))
   584  }
   585  
   586  
   587  
   588  
   589  
   590  
   591  
   592  func (tl traceLocker) GoCreateSyscall(gp *g) {
   593  	
   594  	
   595  	gp.trace.setStatusTraced(tl.gen)
   596  	tl.eventWriter(tracev2.GoBad, tracev2.ProcBad).event(tracev2.EvGoCreateSyscall, traceArg(gp.goid))
   597  }
   598  
   599  
   600  
   601  
   602  
   603  
   604  
   605  func (tl traceLocker) GoDestroySyscall() {
   606  	
   607  	
   608  	tl.eventWriter(tracev2.GoSyscall, tracev2.ProcBad).event(tracev2.EvGoDestroySyscall)
   609  }
   610  
   611  
   612  
   613  
   614  
   615  
   616  
   617  func trace_userTaskCreate(id, parentID uint64, taskType string) {
   618  	tl := traceAcquire()
   619  	if !tl.ok() {
   620  		
   621  		return
   622  	}
   623  	tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(tracev2.EvUserTaskBegin, traceArg(id), traceArg(parentID), tl.string(taskType), tl.stack(3))
   624  	traceRelease(tl)
   625  }
   626  
   627  
   628  
   629  
   630  func trace_userTaskEnd(id uint64) {
   631  	tl := traceAcquire()
   632  	if !tl.ok() {
   633  		
   634  		return
   635  	}
   636  	tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(tracev2.EvUserTaskEnd, traceArg(id), tl.stack(2))
   637  	traceRelease(tl)
   638  }
   639  
   640  
   641  
   642  
   643  
   644  
   645  
   646  func trace_userRegion(id, mode uint64, name string) {
   647  	tl := traceAcquire()
   648  	if !tl.ok() {
   649  		
   650  		return
   651  	}
   652  	var ev tracev2.EventType
   653  	switch mode {
   654  	case 0:
   655  		ev = tracev2.EvUserRegionBegin
   656  	case 1:
   657  		ev = tracev2.EvUserRegionEnd
   658  	default:
   659  		return
   660  	}
   661  	tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(ev, traceArg(id), tl.string(name), tl.stack(3))
   662  	traceRelease(tl)
   663  }
   664  
   665  
   666  
   667  
   668  func trace_userLog(id uint64, category, message string) {
   669  	tl := traceAcquire()
   670  	if !tl.ok() {
   671  		
   672  		return
   673  	}
   674  	tl.eventWriter(tracev2.GoRunning, tracev2.ProcRunning).event(tracev2.EvUserLog, traceArg(id), tl.string(category), tl.uniqueString(message), tl.stack(3))
   675  	traceRelease(tl)
   676  }
   677  
   678  
   679  
   680  
   681  
   682  
   683  
   684  func traceThreadDestroy(mp *m) {
   685  	assertLockHeld(&sched.lock)
   686  
   687  	
   688  	
   689  	
   690  	
   691  	
   692  	
   693  	
   694  	seq := mp.trace.seqlock.Add(1)
   695  	if debugTraceReentrancy && seq%2 != 1 {
   696  		throw("bad use of trace.seqlock")
   697  	}
   698  	systemstack(func() {
   699  		lock(&trace.lock)
   700  		for i := range mp.trace.buf {
   701  			for exp, buf := range mp.trace.buf[i] {
   702  				if buf != nil {
   703  					
   704  					
   705  					traceBufFlush(buf, uintptr(i))
   706  					mp.trace.buf[i][exp] = nil
   707  				}
   708  			}
   709  		}
   710  		unlock(&trace.lock)
   711  	})
   712  	seq1 := mp.trace.seqlock.Add(1)
   713  	if seq1 != seq+1 {
   714  		print("runtime: seq1=", seq1, "\n")
   715  		throw("bad use of trace.seqlock")
   716  	}
   717  }
   718  
View as plain text