Skip to content

Commit 6840773

Browse files
committed
dump on timeout
1 parent 6aa0f66 commit 6840773

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

pkg/testkit/testkit.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ package testkit
1919
import (
2020
"context"
2121
"fmt"
22+
"log"
23+
"os"
24+
"runtime/pprof"
2225
"strings"
2326
"sync"
2427
"testing"
@@ -684,3 +687,34 @@ func buildRowsRecordSet(ctx context.Context, rs sqlexec.RecordSet) sqlexec.Recor
684687
idx: 0,
685688
}
686689
}
690+
691+
// DebugDumpOnTimeout will dump stack traces and possible blockers after given timeout.
692+
// wg is the WaitGroup to mark as done when finished (to avoid runaway goroutines)
693+
// c is the channel that will signal or close to cancel the timeout.
694+
func DebugDumpOnTimeout(wg *sync.WaitGroup, c chan struct{}, d time.Duration) {
695+
select {
696+
case <-time.After(d):
697+
log.Print("Injected timeout, dumping all goroutines:")
698+
_ = pprof.Lookup("goroutine").WriteTo(os.Stdout, 2)
699+
log.Print("dumping all stack traces led to possible block:")
700+
_ = pprof.Lookup("block").WriteTo(os.Stdout, 2)
701+
log.Print("dumping all stack traces holding mutexes:")
702+
_ = pprof.Lookup("mutex").WriteTo(os.Stdout, 2)
703+
log.Print("dumping all stack traces led to creation of new OS threads:")
704+
_ = pprof.Lookup("threadcreate").WriteTo(os.Stdout, 2)
705+
log.Print("Waiting 2 seconds and to see if things changed...")
706+
time.Sleep(2 * time.Second)
707+
log.Print("Injected timeout, dumping all goroutines:")
708+
_ = pprof.Lookup("goroutine").WriteTo(os.Stdout, 2)
709+
log.Print("dumping all stack traces led to possible block:")
710+
_ = pprof.Lookup("block").WriteTo(os.Stdout, 2)
711+
log.Print("dumping all stack traces holding mutexes:")
712+
_ = pprof.Lookup("mutex").WriteTo(os.Stdout, 2)
713+
log.Print("dumping all stack traces led to creation of new OS threads:")
714+
_ = pprof.Lookup("threadcreate").WriteTo(os.Stdout, 2)
715+
panic("Injected timeout")
716+
case <-c:
717+
// Test finished
718+
}
719+
wg.Done()
720+
}

tests/realtikvtest/addindextest1/disttask_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ package addindextest
1717
import (
1818
"context"
1919
"fmt"
20+
"sync"
2021
"testing"
22+
"time"
2123

2224
"github.com/pingcap/failpoint"
2325
"github.com/pingcap/tidb/pkg/config"
@@ -46,6 +48,15 @@ func init() {
4648
}
4749

4850
func TestAddIndexDistBasic(t *testing.T) {
51+
var wg sync.WaitGroup
52+
wg.Add(1)
53+
dumpChan := make(chan struct{})
54+
defer func() {
55+
close(dumpChan)
56+
wg.Wait()
57+
}()
58+
go testkit.DebugDumpOnTimeout(&wg, dumpChan, 7*time.Minute)
59+
4960
// mock that we only have 1 cpu, add-index task can be scheduled as usual
5061
require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/pkg/util/cpu/mockNumCpu", `return(1)`))
5162
require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/pkg/disttask/framework/storage/testSetLastTaskID", `return(true)`))

0 commit comments

Comments
 (0)