goroutineDeep(t, depth-4) // -4 for produceProfileEvents, **, chanrecv1, chanrev, gopark
}
-func getProfileStacks(collect func([]runtime.BlockProfileRecord) (int, bool), fileLine bool) []string {
+func getProfileStacks(collect func([]runtime.BlockProfileRecord) (int, bool), fileLine bool, pcs bool) []string {
var n int
var ok bool
var p []runtime.BlockProfileRecord
if i > 0 {
stack.WriteByte('\n')
}
+ if pcs {
+ fmt.Fprintf(&stack, "%x ", pc)
+ }
// Use FuncForPC instead of CallersFrames,
// because we want to see the info for exactly
// the PCs returned by the mutex profile to
wg := sync.WaitGroup{}
wg.Add(workers)
- for j := 0; j < workers; j++ {
+ for range workers {
go func() {
- for i := 0; i < iters; i++ {
+ for range iters {
m.Lock()
// Wait at least 1 millisecond to pass the
// starvation threshold for the mutex
wg.Wait()
assertNoDuplicates := func(name string, collect func([]runtime.BlockProfileRecord) (int, bool)) {
- stacks := getProfileStacks(collect, true)
+ stacks := getProfileStacks(collect, true, true)
seen := make(map[string]struct{})
for _, s := range stacks {
if _, ok := seen[s]; ok {
for _, tc := range tcs {
t.Run(tc.Name, func(t *testing.T) {
- stacks := getProfileStacks(tc.Collect, false)
+ stacks := getProfileStacks(tc.Collect, false, false)
for _, s := range stacks {
if strings.Contains(s, tc.SubStack) {
return