...

Source file src/runtime/mprof.go

Documentation: runtime

		 1  // Copyright 2009 The Go Authors. All rights reserved.
		 2  // Use of this source code is governed by a BSD-style
		 3  // license that can be found in the LICENSE file.
		 4  
		 5  // Malloc profiling.
		 6  // Patterned after tcmalloc's algorithms; shorter code.
		 7  
		 8  package runtime
		 9  
		10  import (
		11  	"runtime/internal/atomic"
		12  	"unsafe"
		13  )
		14  
		15  // NOTE(rsc): Everything here could use cas if contention became an issue.
		16  var proflock mutex
		17  
		18  // All memory allocations are local and do not escape outside of the profiler.
		19  // The profiler is forbidden from referring to garbage-collected memory.
		20  
		21  const (
		22  	// profile types
		23  	memProfile bucketType = 1 + iota
		24  	blockProfile
		25  	mutexProfile
		26  
		27  	// size of bucket hash table
		28  	buckHashSize = 179999
		29  
		30  	// max depth of stack to record in bucket
		31  	maxStack = 32
		32  )
		33  
		34  type bucketType int
		35  
		36  // A bucket holds per-call-stack profiling information.
		37  // The representation is a bit sleazy, inherited from C.
		38  // This struct defines the bucket header. It is followed in
		39  // memory by the stack words and then the actual record
		40  // data, either a memRecord or a blockRecord.
		41  //
		42  // Per-call-stack profiling information.
		43  // Lookup by hashing call stack into a linked-list hash table.
		44  //
		45  // No heap pointers.
		46  //
		47  //go:notinheap
		48  type bucket struct {
		49  	next		*bucket
		50  	allnext *bucket
		51  	typ		 bucketType // memBucket or blockBucket (includes mutexProfile)
		52  	hash		uintptr
		53  	size		uintptr
		54  	nstk		uintptr
		55  }
		56  
		57  // A memRecord is the bucket data for a bucket of type memProfile,
		58  // part of the memory profile.
		59  type memRecord struct {
		60  	// The following complex 3-stage scheme of stats accumulation
		61  	// is required to obtain a consistent picture of mallocs and frees
		62  	// for some point in time.
		63  	// The problem is that mallocs come in real time, while frees
		64  	// come only after a GC during concurrent sweeping. So if we would
		65  	// naively count them, we would get a skew toward mallocs.
		66  	//
		67  	// Hence, we delay information to get consistent snapshots as
		68  	// of mark termination. Allocations count toward the next mark
		69  	// termination's snapshot, while sweep frees count toward the
		70  	// previous mark termination's snapshot:
		71  	//
		72  	//							MT					MT					MT					MT
		73  	//						 .·|				 .·|				 .·|				 .·|
		74  	//					.·˙	|			.·˙	|			.·˙	|			.·˙	|
		75  	//			 .·˙		 |	 .·˙		 |	 .·˙		 |	 .·˙		 |
		76  	//		.·˙				|.·˙				|.·˙				|.·˙				|
		77  	//
		78  	//			 alloc → ▲ ← free
		79  	//							 ┠┅┅┅┅┅┅┅┅┅┅┅P
		80  	//			 C+2		 →		C+1		→	C
		81  	//
		82  	//									 alloc → ▲ ← free
		83  	//													 ┠┅┅┅┅┅┅┅┅┅┅┅P
		84  	//									 C+2		 →		C+1		→	C
		85  	//
		86  	// Since we can't publish a consistent snapshot until all of
		87  	// the sweep frees are accounted for, we wait until the next
		88  	// mark termination ("MT" above) to publish the previous mark
		89  	// termination's snapshot ("P" above). To do this, allocation
		90  	// and free events are accounted to *future* heap profile
		91  	// cycles ("C+n" above) and we only publish a cycle once all
		92  	// of the events from that cycle must be done. Specifically:
		93  	//
		94  	// Mallocs are accounted to cycle C+2.
		95  	// Explicit frees are accounted to cycle C+2.
		96  	// GC frees (done during sweeping) are accounted to cycle C+1.
		97  	//
		98  	// After mark termination, we increment the global heap
		99  	// profile cycle counter and accumulate the stats from cycle C
	 100  	// into the active profile.
	 101  
	 102  	// active is the currently published profile. A profiling
	 103  	// cycle can be accumulated into active once its complete.
	 104  	active memRecordCycle
	 105  
	 106  	// future records the profile events we're counting for cycles
	 107  	// that have not yet been published. This is ring buffer
	 108  	// indexed by the global heap profile cycle C and stores
	 109  	// cycles C, C+1, and C+2. Unlike active, these counts are
	 110  	// only for a single cycle; they are not cumulative across
	 111  	// cycles.
	 112  	//
	 113  	// We store cycle C here because there's a window between when
	 114  	// C becomes the active cycle and when we've flushed it to
	 115  	// active.
	 116  	future [3]memRecordCycle
	 117  }
	 118  
	 119  // memRecordCycle
	 120  type memRecordCycle struct {
	 121  	allocs, frees					 uintptr
	 122  	alloc_bytes, free_bytes uintptr
	 123  }
	 124  
	 125  // add accumulates b into a. It does not zero b.
	 126  func (a *memRecordCycle) add(b *memRecordCycle) {
	 127  	a.allocs += b.allocs
	 128  	a.frees += b.frees
	 129  	a.alloc_bytes += b.alloc_bytes
	 130  	a.free_bytes += b.free_bytes
	 131  }
	 132  
	 133  // A blockRecord is the bucket data for a bucket of type blockProfile,
	 134  // which is used in blocking and mutex profiles.
	 135  type blockRecord struct {
	 136  	count	float64
	 137  	cycles int64
	 138  }
	 139  
	 140  var (
	 141  	mbuckets	*bucket // memory profile buckets
	 142  	bbuckets	*bucket // blocking profile buckets
	 143  	xbuckets	*bucket // mutex profile buckets
	 144  	buckhash	*[179999]*bucket
	 145  	bucketmem uintptr
	 146  
	 147  	mProf struct {
	 148  		// All fields in mProf are protected by proflock.
	 149  
	 150  		// cycle is the global heap profile cycle. This wraps
	 151  		// at mProfCycleWrap.
	 152  		cycle uint32
	 153  		// flushed indicates that future[cycle] in all buckets
	 154  		// has been flushed to the active profile.
	 155  		flushed bool
	 156  	}
	 157  )
	 158  
	 159  const mProfCycleWrap = uint32(len(memRecord{}.future)) * (2 << 24)
	 160  
	 161  // newBucket allocates a bucket with the given type and number of stack entries.
	 162  func newBucket(typ bucketType, nstk int) *bucket {
	 163  	size := unsafe.Sizeof(bucket{}) + uintptr(nstk)*unsafe.Sizeof(uintptr(0))
	 164  	switch typ {
	 165  	default:
	 166  		throw("invalid profile bucket type")
	 167  	case memProfile:
	 168  		size += unsafe.Sizeof(memRecord{})
	 169  	case blockProfile, mutexProfile:
	 170  		size += unsafe.Sizeof(blockRecord{})
	 171  	}
	 172  
	 173  	b := (*bucket)(persistentalloc(size, 0, &memstats.buckhash_sys))
	 174  	bucketmem += size
	 175  	b.typ = typ
	 176  	b.nstk = uintptr(nstk)
	 177  	return b
	 178  }
	 179  
	 180  // stk returns the slice in b holding the stack.
	 181  func (b *bucket) stk() []uintptr {
	 182  	stk := (*[maxStack]uintptr)(add(unsafe.Pointer(b), unsafe.Sizeof(*b)))
	 183  	return stk[:b.nstk:b.nstk]
	 184  }
	 185  
	 186  // mp returns the memRecord associated with the memProfile bucket b.
	 187  func (b *bucket) mp() *memRecord {
	 188  	if b.typ != memProfile {
	 189  		throw("bad use of bucket.mp")
	 190  	}
	 191  	data := add(unsafe.Pointer(b), unsafe.Sizeof(*b)+b.nstk*unsafe.Sizeof(uintptr(0)))
	 192  	return (*memRecord)(data)
	 193  }
	 194  
	 195  // bp returns the blockRecord associated with the blockProfile bucket b.
	 196  func (b *bucket) bp() *blockRecord {
	 197  	if b.typ != blockProfile && b.typ != mutexProfile {
	 198  		throw("bad use of bucket.bp")
	 199  	}
	 200  	data := add(unsafe.Pointer(b), unsafe.Sizeof(*b)+b.nstk*unsafe.Sizeof(uintptr(0)))
	 201  	return (*blockRecord)(data)
	 202  }
	 203  
	 204  // Return the bucket for stk[0:nstk], allocating new bucket if needed.
	 205  func stkbucket(typ bucketType, size uintptr, stk []uintptr, alloc bool) *bucket {
	 206  	if buckhash == nil {
	 207  		buckhash = (*[buckHashSize]*bucket)(sysAlloc(unsafe.Sizeof(*buckhash), &memstats.buckhash_sys))
	 208  		if buckhash == nil {
	 209  			throw("runtime: cannot allocate memory")
	 210  		}
	 211  	}
	 212  
	 213  	// Hash stack.
	 214  	var h uintptr
	 215  	for _, pc := range stk {
	 216  		h += pc
	 217  		h += h << 10
	 218  		h ^= h >> 6
	 219  	}
	 220  	// hash in size
	 221  	h += size
	 222  	h += h << 10
	 223  	h ^= h >> 6
	 224  	// finalize
	 225  	h += h << 3
	 226  	h ^= h >> 11
	 227  
	 228  	i := int(h % buckHashSize)
	 229  	for b := buckhash[i]; b != nil; b = b.next {
	 230  		if b.typ == typ && b.hash == h && b.size == size && eqslice(b.stk(), stk) {
	 231  			return b
	 232  		}
	 233  	}
	 234  
	 235  	if !alloc {
	 236  		return nil
	 237  	}
	 238  
	 239  	// Create new bucket.
	 240  	b := newBucket(typ, len(stk))
	 241  	copy(b.stk(), stk)
	 242  	b.hash = h
	 243  	b.size = size
	 244  	b.next = buckhash[i]
	 245  	buckhash[i] = b
	 246  	if typ == memProfile {
	 247  		b.allnext = mbuckets
	 248  		mbuckets = b
	 249  	} else if typ == mutexProfile {
	 250  		b.allnext = xbuckets
	 251  		xbuckets = b
	 252  	} else {
	 253  		b.allnext = bbuckets
	 254  		bbuckets = b
	 255  	}
	 256  	return b
	 257  }
	 258  
	 259  func eqslice(x, y []uintptr) bool {
	 260  	if len(x) != len(y) {
	 261  		return false
	 262  	}
	 263  	for i, xi := range x {
	 264  		if xi != y[i] {
	 265  			return false
	 266  		}
	 267  	}
	 268  	return true
	 269  }
	 270  
	 271  // mProf_NextCycle publishes the next heap profile cycle and creates a
	 272  // fresh heap profile cycle. This operation is fast and can be done
	 273  // during STW. The caller must call mProf_Flush before calling
	 274  // mProf_NextCycle again.
	 275  //
	 276  // This is called by mark termination during STW so allocations and
	 277  // frees after the world is started again count towards a new heap
	 278  // profiling cycle.
	 279  func mProf_NextCycle() {
	 280  	lock(&proflock)
	 281  	// We explicitly wrap mProf.cycle rather than depending on
	 282  	// uint wraparound because the memRecord.future ring does not
	 283  	// itself wrap at a power of two.
	 284  	mProf.cycle = (mProf.cycle + 1) % mProfCycleWrap
	 285  	mProf.flushed = false
	 286  	unlock(&proflock)
	 287  }
	 288  
	 289  // mProf_Flush flushes the events from the current heap profiling
	 290  // cycle into the active profile. After this it is safe to start a new
	 291  // heap profiling cycle with mProf_NextCycle.
	 292  //
	 293  // This is called by GC after mark termination starts the world. In
	 294  // contrast with mProf_NextCycle, this is somewhat expensive, but safe
	 295  // to do concurrently.
	 296  func mProf_Flush() {
	 297  	lock(&proflock)
	 298  	if !mProf.flushed {
	 299  		mProf_FlushLocked()
	 300  		mProf.flushed = true
	 301  	}
	 302  	unlock(&proflock)
	 303  }
	 304  
	 305  func mProf_FlushLocked() {
	 306  	c := mProf.cycle
	 307  	for b := mbuckets; b != nil; b = b.allnext {
	 308  		mp := b.mp()
	 309  
	 310  		// Flush cycle C into the published profile and clear
	 311  		// it for reuse.
	 312  		mpc := &mp.future[c%uint32(len(mp.future))]
	 313  		mp.active.add(mpc)
	 314  		*mpc = memRecordCycle{}
	 315  	}
	 316  }
	 317  
	 318  // mProf_PostSweep records that all sweep frees for this GC cycle have
	 319  // completed. This has the effect of publishing the heap profile
	 320  // snapshot as of the last mark termination without advancing the heap
	 321  // profile cycle.
	 322  func mProf_PostSweep() {
	 323  	lock(&proflock)
	 324  	// Flush cycle C+1 to the active profile so everything as of
	 325  	// the last mark termination becomes visible. *Don't* advance
	 326  	// the cycle, since we're still accumulating allocs in cycle
	 327  	// C+2, which have to become C+1 in the next mark termination
	 328  	// and so on.
	 329  	c := mProf.cycle
	 330  	for b := mbuckets; b != nil; b = b.allnext {
	 331  		mp := b.mp()
	 332  		mpc := &mp.future[(c+1)%uint32(len(mp.future))]
	 333  		mp.active.add(mpc)
	 334  		*mpc = memRecordCycle{}
	 335  	}
	 336  	unlock(&proflock)
	 337  }
	 338  
	 339  // Called by malloc to record a profiled block.
	 340  func mProf_Malloc(p unsafe.Pointer, size uintptr) {
	 341  	var stk [maxStack]uintptr
	 342  	nstk := callers(4, stk[:])
	 343  	lock(&proflock)
	 344  	b := stkbucket(memProfile, size, stk[:nstk], true)
	 345  	c := mProf.cycle
	 346  	mp := b.mp()
	 347  	mpc := &mp.future[(c+2)%uint32(len(mp.future))]
	 348  	mpc.allocs++
	 349  	mpc.alloc_bytes += size
	 350  	unlock(&proflock)
	 351  
	 352  	// Setprofilebucket locks a bunch of other mutexes, so we call it outside of proflock.
	 353  	// This reduces potential contention and chances of deadlocks.
	 354  	// Since the object must be alive during call to mProf_Malloc,
	 355  	// it's fine to do this non-atomically.
	 356  	systemstack(func() {
	 357  		setprofilebucket(p, b)
	 358  	})
	 359  }
	 360  
	 361  // Called when freeing a profiled block.
	 362  func mProf_Free(b *bucket, size uintptr) {
	 363  	lock(&proflock)
	 364  	c := mProf.cycle
	 365  	mp := b.mp()
	 366  	mpc := &mp.future[(c+1)%uint32(len(mp.future))]
	 367  	mpc.frees++
	 368  	mpc.free_bytes += size
	 369  	unlock(&proflock)
	 370  }
	 371  
	 372  var blockprofilerate uint64 // in CPU ticks
	 373  
	 374  // SetBlockProfileRate controls the fraction of goroutine blocking events
	 375  // that are reported in the blocking profile. The profiler aims to sample
	 376  // an average of one blocking event per rate nanoseconds spent blocked.
	 377  //
	 378  // To include every blocking event in the profile, pass rate = 1.
	 379  // To turn off profiling entirely, pass rate <= 0.
	 380  func SetBlockProfileRate(rate int) {
	 381  	var r int64
	 382  	if rate <= 0 {
	 383  		r = 0 // disable profiling
	 384  	} else if rate == 1 {
	 385  		r = 1 // profile everything
	 386  	} else {
	 387  		// convert ns to cycles, use float64 to prevent overflow during multiplication
	 388  		r = int64(float64(rate) * float64(tickspersecond()) / (1000 * 1000 * 1000))
	 389  		if r == 0 {
	 390  			r = 1
	 391  		}
	 392  	}
	 393  
	 394  	atomic.Store64(&blockprofilerate, uint64(r))
	 395  }
	 396  
	 397  func blockevent(cycles int64, skip int) {
	 398  	if cycles <= 0 {
	 399  		cycles = 1
	 400  	}
	 401  
	 402  	rate := int64(atomic.Load64(&blockprofilerate))
	 403  	if blocksampled(cycles, rate) {
	 404  		saveblockevent(cycles, rate, skip+1, blockProfile)
	 405  	}
	 406  }
	 407  
	 408  // blocksampled returns true for all events where cycles >= rate. Shorter
	 409  // events have a cycles/rate random chance of returning true.
	 410  func blocksampled(cycles, rate int64) bool {
	 411  	if rate <= 0 || (rate > cycles && int64(fastrand())%rate > cycles) {
	 412  		return false
	 413  	}
	 414  	return true
	 415  }
	 416  
	 417  func saveblockevent(cycles, rate int64, skip int, which bucketType) {
	 418  	gp := getg()
	 419  	var nstk int
	 420  	var stk [maxStack]uintptr
	 421  	if gp.m.curg == nil || gp.m.curg == gp {
	 422  		nstk = callers(skip, stk[:])
	 423  	} else {
	 424  		nstk = gcallers(gp.m.curg, skip, stk[:])
	 425  	}
	 426  	lock(&proflock)
	 427  	b := stkbucket(which, 0, stk[:nstk], true)
	 428  
	 429  	if which == blockProfile && cycles < rate {
	 430  		// Remove sampling bias, see discussion on http://golang.org/cl/299991.
	 431  		b.bp().count += float64(rate) / float64(cycles)
	 432  		b.bp().cycles += rate
	 433  	} else {
	 434  		b.bp().count++
	 435  		b.bp().cycles += cycles
	 436  	}
	 437  	unlock(&proflock)
	 438  }
	 439  
	 440  var mutexprofilerate uint64 // fraction sampled
	 441  
	 442  // SetMutexProfileFraction controls the fraction of mutex contention events
	 443  // that are reported in the mutex profile. On average 1/rate events are
	 444  // reported. The previous rate is returned.
	 445  //
	 446  // To turn off profiling entirely, pass rate 0.
	 447  // To just read the current rate, pass rate < 0.
	 448  // (For n>1 the details of sampling may change.)
	 449  func SetMutexProfileFraction(rate int) int {
	 450  	if rate < 0 {
	 451  		return int(mutexprofilerate)
	 452  	}
	 453  	old := mutexprofilerate
	 454  	atomic.Store64(&mutexprofilerate, uint64(rate))
	 455  	return int(old)
	 456  }
	 457  
	 458  //go:linkname mutexevent sync.event
	 459  func mutexevent(cycles int64, skip int) {
	 460  	if cycles < 0 {
	 461  		cycles = 0
	 462  	}
	 463  	rate := int64(atomic.Load64(&mutexprofilerate))
	 464  	// TODO(pjw): measure impact of always calling fastrand vs using something
	 465  	// like malloc.go:nextSample()
	 466  	if rate > 0 && int64(fastrand())%rate == 0 {
	 467  		saveblockevent(cycles, rate, skip+1, mutexProfile)
	 468  	}
	 469  }
	 470  
	 471  // Go interface to profile data.
	 472  
	 473  // A StackRecord describes a single execution stack.
	 474  type StackRecord struct {
	 475  	Stack0 [32]uintptr // stack trace for this record; ends at first 0 entry
	 476  }
	 477  
	 478  // Stack returns the stack trace associated with the record,
	 479  // a prefix of r.Stack0.
	 480  func (r *StackRecord) Stack() []uintptr {
	 481  	for i, v := range r.Stack0 {
	 482  		if v == 0 {
	 483  			return r.Stack0[0:i]
	 484  		}
	 485  	}
	 486  	return r.Stack0[0:]
	 487  }
	 488  
	 489  // MemProfileRate controls the fraction of memory allocations
	 490  // that are recorded and reported in the memory profile.
	 491  // The profiler aims to sample an average of
	 492  // one allocation per MemProfileRate bytes allocated.
	 493  //
	 494  // To include every allocated block in the profile, set MemProfileRate to 1.
	 495  // To turn off profiling entirely, set MemProfileRate to 0.
	 496  //
	 497  // The tools that process the memory profiles assume that the
	 498  // profile rate is constant across the lifetime of the program
	 499  // and equal to the current value. Programs that change the
	 500  // memory profiling rate should do so just once, as early as
	 501  // possible in the execution of the program (for example,
	 502  // at the beginning of main).
	 503  var MemProfileRate int = defaultMemProfileRate(512 * 1024)
	 504  
	 505  // defaultMemProfileRate returns 0 if disableMemoryProfiling is set.
	 506  // It exists primarily for the godoc rendering of MemProfileRate
	 507  // above.
	 508  func defaultMemProfileRate(v int) int {
	 509  	if disableMemoryProfiling {
	 510  		return 0
	 511  	}
	 512  	return v
	 513  }
	 514  
	 515  // disableMemoryProfiling is set by the linker if runtime.MemProfile
	 516  // is not used and the link type guarantees nobody else could use it
	 517  // elsewhere.
	 518  var disableMemoryProfiling bool
	 519  
	 520  // A MemProfileRecord describes the live objects allocated
	 521  // by a particular call sequence (stack trace).
	 522  type MemProfileRecord struct {
	 523  	AllocBytes, FreeBytes		 int64			 // number of bytes allocated, freed
	 524  	AllocObjects, FreeObjects int64			 // number of objects allocated, freed
	 525  	Stack0										[32]uintptr // stack trace for this record; ends at first 0 entry
	 526  }
	 527  
	 528  // InUseBytes returns the number of bytes in use (AllocBytes - FreeBytes).
	 529  func (r *MemProfileRecord) InUseBytes() int64 { return r.AllocBytes - r.FreeBytes }
	 530  
	 531  // InUseObjects returns the number of objects in use (AllocObjects - FreeObjects).
	 532  func (r *MemProfileRecord) InUseObjects() int64 {
	 533  	return r.AllocObjects - r.FreeObjects
	 534  }
	 535  
	 536  // Stack returns the stack trace associated with the record,
	 537  // a prefix of r.Stack0.
	 538  func (r *MemProfileRecord) Stack() []uintptr {
	 539  	for i, v := range r.Stack0 {
	 540  		if v == 0 {
	 541  			return r.Stack0[0:i]
	 542  		}
	 543  	}
	 544  	return r.Stack0[0:]
	 545  }
	 546  
	 547  // MemProfile returns a profile of memory allocated and freed per allocation
	 548  // site.
	 549  //
	 550  // MemProfile returns n, the number of records in the current memory profile.
	 551  // If len(p) >= n, MemProfile copies the profile into p and returns n, true.
	 552  // If len(p) < n, MemProfile does not change p and returns n, false.
	 553  //
	 554  // If inuseZero is true, the profile includes allocation records
	 555  // where r.AllocBytes > 0 but r.AllocBytes == r.FreeBytes.
	 556  // These are sites where memory was allocated, but it has all
	 557  // been released back to the runtime.
	 558  //
	 559  // The returned profile may be up to two garbage collection cycles old.
	 560  // This is to avoid skewing the profile toward allocations; because
	 561  // allocations happen in real time but frees are delayed until the garbage
	 562  // collector performs sweeping, the profile only accounts for allocations
	 563  // that have had a chance to be freed by the garbage collector.
	 564  //
	 565  // Most clients should use the runtime/pprof package or
	 566  // the testing package's -test.memprofile flag instead
	 567  // of calling MemProfile directly.
	 568  func MemProfile(p []MemProfileRecord, inuseZero bool) (n int, ok bool) {
	 569  	lock(&proflock)
	 570  	// If we're between mProf_NextCycle and mProf_Flush, take care
	 571  	// of flushing to the active profile so we only have to look
	 572  	// at the active profile below.
	 573  	mProf_FlushLocked()
	 574  	clear := true
	 575  	for b := mbuckets; b != nil; b = b.allnext {
	 576  		mp := b.mp()
	 577  		if inuseZero || mp.active.alloc_bytes != mp.active.free_bytes {
	 578  			n++
	 579  		}
	 580  		if mp.active.allocs != 0 || mp.active.frees != 0 {
	 581  			clear = false
	 582  		}
	 583  	}
	 584  	if clear {
	 585  		// Absolutely no data, suggesting that a garbage collection
	 586  		// has not yet happened. In order to allow profiling when
	 587  		// garbage collection is disabled from the beginning of execution,
	 588  		// accumulate all of the cycles, and recount buckets.
	 589  		n = 0
	 590  		for b := mbuckets; b != nil; b = b.allnext {
	 591  			mp := b.mp()
	 592  			for c := range mp.future {
	 593  				mp.active.add(&mp.future[c])
	 594  				mp.future[c] = memRecordCycle{}
	 595  			}
	 596  			if inuseZero || mp.active.alloc_bytes != mp.active.free_bytes {
	 597  				n++
	 598  			}
	 599  		}
	 600  	}
	 601  	if n <= len(p) {
	 602  		ok = true
	 603  		idx := 0
	 604  		for b := mbuckets; b != nil; b = b.allnext {
	 605  			mp := b.mp()
	 606  			if inuseZero || mp.active.alloc_bytes != mp.active.free_bytes {
	 607  				record(&p[idx], b)
	 608  				idx++
	 609  			}
	 610  		}
	 611  	}
	 612  	unlock(&proflock)
	 613  	return
	 614  }
	 615  
	 616  // Write b's data to r.
	 617  func record(r *MemProfileRecord, b *bucket) {
	 618  	mp := b.mp()
	 619  	r.AllocBytes = int64(mp.active.alloc_bytes)
	 620  	r.FreeBytes = int64(mp.active.free_bytes)
	 621  	r.AllocObjects = int64(mp.active.allocs)
	 622  	r.FreeObjects = int64(mp.active.frees)
	 623  	if raceenabled {
	 624  		racewriterangepc(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0), getcallerpc(), funcPC(MemProfile))
	 625  	}
	 626  	if msanenabled {
	 627  		msanwrite(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0))
	 628  	}
	 629  	copy(r.Stack0[:], b.stk())
	 630  	for i := int(b.nstk); i < len(r.Stack0); i++ {
	 631  		r.Stack0[i] = 0
	 632  	}
	 633  }
	 634  
	 635  func iterate_memprof(fn func(*bucket, uintptr, *uintptr, uintptr, uintptr, uintptr)) {
	 636  	lock(&proflock)
	 637  	for b := mbuckets; b != nil; b = b.allnext {
	 638  		mp := b.mp()
	 639  		fn(b, b.nstk, &b.stk()[0], b.size, mp.active.allocs, mp.active.frees)
	 640  	}
	 641  	unlock(&proflock)
	 642  }
	 643  
	 644  // BlockProfileRecord describes blocking events originated
	 645  // at a particular call sequence (stack trace).
	 646  type BlockProfileRecord struct {
	 647  	Count	int64
	 648  	Cycles int64
	 649  	StackRecord
	 650  }
	 651  
	 652  // BlockProfile returns n, the number of records in the current blocking profile.
	 653  // If len(p) >= n, BlockProfile copies the profile into p and returns n, true.
	 654  // If len(p) < n, BlockProfile does not change p and returns n, false.
	 655  //
	 656  // Most clients should use the runtime/pprof package or
	 657  // the testing package's -test.blockprofile flag instead
	 658  // of calling BlockProfile directly.
	 659  func BlockProfile(p []BlockProfileRecord) (n int, ok bool) {
	 660  	lock(&proflock)
	 661  	for b := bbuckets; b != nil; b = b.allnext {
	 662  		n++
	 663  	}
	 664  	if n <= len(p) {
	 665  		ok = true
	 666  		for b := bbuckets; b != nil; b = b.allnext {
	 667  			bp := b.bp()
	 668  			r := &p[0]
	 669  			r.Count = int64(bp.count)
	 670  			// Prevent callers from having to worry about division by zero errors.
	 671  			// See discussion on http://golang.org/cl/299991.
	 672  			if r.Count == 0 {
	 673  				r.Count = 1
	 674  			}
	 675  			r.Cycles = bp.cycles
	 676  			if raceenabled {
	 677  				racewriterangepc(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0), getcallerpc(), funcPC(BlockProfile))
	 678  			}
	 679  			if msanenabled {
	 680  				msanwrite(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0))
	 681  			}
	 682  			i := copy(r.Stack0[:], b.stk())
	 683  			for ; i < len(r.Stack0); i++ {
	 684  				r.Stack0[i] = 0
	 685  			}
	 686  			p = p[1:]
	 687  		}
	 688  	}
	 689  	unlock(&proflock)
	 690  	return
	 691  }
	 692  
	 693  // MutexProfile returns n, the number of records in the current mutex profile.
	 694  // If len(p) >= n, MutexProfile copies the profile into p and returns n, true.
	 695  // Otherwise, MutexProfile does not change p, and returns n, false.
	 696  //
	 697  // Most clients should use the runtime/pprof package
	 698  // instead of calling MutexProfile directly.
	 699  func MutexProfile(p []BlockProfileRecord) (n int, ok bool) {
	 700  	lock(&proflock)
	 701  	for b := xbuckets; b != nil; b = b.allnext {
	 702  		n++
	 703  	}
	 704  	if n <= len(p) {
	 705  		ok = true
	 706  		for b := xbuckets; b != nil; b = b.allnext {
	 707  			bp := b.bp()
	 708  			r := &p[0]
	 709  			r.Count = int64(bp.count)
	 710  			r.Cycles = bp.cycles
	 711  			i := copy(r.Stack0[:], b.stk())
	 712  			for ; i < len(r.Stack0); i++ {
	 713  				r.Stack0[i] = 0
	 714  			}
	 715  			p = p[1:]
	 716  		}
	 717  	}
	 718  	unlock(&proflock)
	 719  	return
	 720  }
	 721  
	 722  // ThreadCreateProfile returns n, the number of records in the thread creation profile.
	 723  // If len(p) >= n, ThreadCreateProfile copies the profile into p and returns n, true.
	 724  // If len(p) < n, ThreadCreateProfile does not change p and returns n, false.
	 725  //
	 726  // Most clients should use the runtime/pprof package instead
	 727  // of calling ThreadCreateProfile directly.
	 728  func ThreadCreateProfile(p []StackRecord) (n int, ok bool) {
	 729  	first := (*m)(atomic.Loadp(unsafe.Pointer(&allm)))
	 730  	for mp := first; mp != nil; mp = mp.alllink {
	 731  		n++
	 732  	}
	 733  	if n <= len(p) {
	 734  		ok = true
	 735  		i := 0
	 736  		for mp := first; mp != nil; mp = mp.alllink {
	 737  			p[i].Stack0 = mp.createstack
	 738  			i++
	 739  		}
	 740  	}
	 741  	return
	 742  }
	 743  
	 744  //go:linkname runtime_goroutineProfileWithLabels runtime/pprof.runtime_goroutineProfileWithLabels
	 745  func runtime_goroutineProfileWithLabels(p []StackRecord, labels []unsafe.Pointer) (n int, ok bool) {
	 746  	return goroutineProfileWithLabels(p, labels)
	 747  }
	 748  
	 749  // labels may be nil. If labels is non-nil, it must have the same length as p.
	 750  func goroutineProfileWithLabels(p []StackRecord, labels []unsafe.Pointer) (n int, ok bool) {
	 751  	if labels != nil && len(labels) != len(p) {
	 752  		labels = nil
	 753  	}
	 754  	gp := getg()
	 755  
	 756  	isOK := func(gp1 *g) bool {
	 757  		// Checking isSystemGoroutine here makes GoroutineProfile
	 758  		// consistent with both NumGoroutine and Stack.
	 759  		return gp1 != gp && readgstatus(gp1) != _Gdead && !isSystemGoroutine(gp1, false)
	 760  	}
	 761  
	 762  	stopTheWorld("profile")
	 763  
	 764  	// World is stopped, no locking required.
	 765  	n = 1
	 766  	forEachGRace(func(gp1 *g) {
	 767  		if isOK(gp1) {
	 768  			n++
	 769  		}
	 770  	})
	 771  
	 772  	if n <= len(p) {
	 773  		ok = true
	 774  		r, lbl := p, labels
	 775  
	 776  		// Save current goroutine.
	 777  		sp := getcallersp()
	 778  		pc := getcallerpc()
	 779  		systemstack(func() {
	 780  			saveg(pc, sp, gp, &r[0])
	 781  		})
	 782  		r = r[1:]
	 783  
	 784  		// If we have a place to put our goroutine labelmap, insert it there.
	 785  		if labels != nil {
	 786  			lbl[0] = gp.labels
	 787  			lbl = lbl[1:]
	 788  		}
	 789  
	 790  		// Save other goroutines.
	 791  		forEachGRace(func(gp1 *g) {
	 792  			if !isOK(gp1) {
	 793  				return
	 794  			}
	 795  
	 796  			if len(r) == 0 {
	 797  				// Should be impossible, but better to return a
	 798  				// truncated profile than to crash the entire process.
	 799  				return
	 800  			}
	 801  			saveg(^uintptr(0), ^uintptr(0), gp1, &r[0])
	 802  			if labels != nil {
	 803  				lbl[0] = gp1.labels
	 804  				lbl = lbl[1:]
	 805  			}
	 806  			r = r[1:]
	 807  		})
	 808  	}
	 809  
	 810  	startTheWorld()
	 811  	return n, ok
	 812  }
	 813  
	 814  // GoroutineProfile returns n, the number of records in the active goroutine stack profile.
	 815  // If len(p) >= n, GoroutineProfile copies the profile into p and returns n, true.
	 816  // If len(p) < n, GoroutineProfile does not change p and returns n, false.
	 817  //
	 818  // Most clients should use the runtime/pprof package instead
	 819  // of calling GoroutineProfile directly.
	 820  func GoroutineProfile(p []StackRecord) (n int, ok bool) {
	 821  
	 822  	return goroutineProfileWithLabels(p, nil)
	 823  }
	 824  
	 825  func saveg(pc, sp uintptr, gp *g, r *StackRecord) {
	 826  	n := gentraceback(pc, sp, 0, gp, 0, &r.Stack0[0], len(r.Stack0), nil, nil, 0)
	 827  	if n < len(r.Stack0) {
	 828  		r.Stack0[n] = 0
	 829  	}
	 830  }
	 831  
	 832  // Stack formats a stack trace of the calling goroutine into buf
	 833  // and returns the number of bytes written to buf.
	 834  // If all is true, Stack formats stack traces of all other goroutines
	 835  // into buf after the trace for the current goroutine.
	 836  func Stack(buf []byte, all bool) int {
	 837  	if all {
	 838  		stopTheWorld("stack trace")
	 839  	}
	 840  
	 841  	n := 0
	 842  	if len(buf) > 0 {
	 843  		gp := getg()
	 844  		sp := getcallersp()
	 845  		pc := getcallerpc()
	 846  		systemstack(func() {
	 847  			g0 := getg()
	 848  			// Force traceback=1 to override GOTRACEBACK setting,
	 849  			// so that Stack's results are consistent.
	 850  			// GOTRACEBACK is only about crash dumps.
	 851  			g0.m.traceback = 1
	 852  			g0.writebuf = buf[0:0:len(buf)]
	 853  			goroutineheader(gp)
	 854  			traceback(pc, sp, 0, gp)
	 855  			if all {
	 856  				tracebackothers(gp)
	 857  			}
	 858  			g0.m.traceback = 0
	 859  			n = len(g0.writebuf)
	 860  			g0.writebuf = nil
	 861  		})
	 862  	}
	 863  
	 864  	if all {
	 865  		startTheWorld()
	 866  	}
	 867  	return n
	 868  }
	 869  
	 870  // Tracing of alloc/free/gc.
	 871  
	 872  var tracelock mutex
	 873  
	 874  func tracealloc(p unsafe.Pointer, size uintptr, typ *_type) {
	 875  	lock(&tracelock)
	 876  	gp := getg()
	 877  	gp.m.traceback = 2
	 878  	if typ == nil {
	 879  		print("tracealloc(", p, ", ", hex(size), ")\n")
	 880  	} else {
	 881  		print("tracealloc(", p, ", ", hex(size), ", ", typ.string(), ")\n")
	 882  	}
	 883  	if gp.m.curg == nil || gp == gp.m.curg {
	 884  		goroutineheader(gp)
	 885  		pc := getcallerpc()
	 886  		sp := getcallersp()
	 887  		systemstack(func() {
	 888  			traceback(pc, sp, 0, gp)
	 889  		})
	 890  	} else {
	 891  		goroutineheader(gp.m.curg)
	 892  		traceback(^uintptr(0), ^uintptr(0), 0, gp.m.curg)
	 893  	}
	 894  	print("\n")
	 895  	gp.m.traceback = 0
	 896  	unlock(&tracelock)
	 897  }
	 898  
	 899  func tracefree(p unsafe.Pointer, size uintptr) {
	 900  	lock(&tracelock)
	 901  	gp := getg()
	 902  	gp.m.traceback = 2
	 903  	print("tracefree(", p, ", ", hex(size), ")\n")
	 904  	goroutineheader(gp)
	 905  	pc := getcallerpc()
	 906  	sp := getcallersp()
	 907  	systemstack(func() {
	 908  		traceback(pc, sp, 0, gp)
	 909  	})
	 910  	print("\n")
	 911  	gp.m.traceback = 0
	 912  	unlock(&tracelock)
	 913  }
	 914  
	 915  func tracegc() {
	 916  	lock(&tracelock)
	 917  	gp := getg()
	 918  	gp.m.traceback = 2
	 919  	print("tracegc()\n")
	 920  	// running on m->g0 stack; show all non-g0 goroutines
	 921  	tracebackothers(gp)
	 922  	print("end tracegc\n")
	 923  	print("\n")
	 924  	gp.m.traceback = 0
	 925  	unlock(&tracelock)
	 926  }
	 927  

View as plain text