}
if docrash {
+ var crashSleepMicros uint32 = 5000
+ var watchdogTimeoutMicros uint32 = 2000 * crashSleepMicros
+
isCrashThread := false
if crashing.CompareAndSwap(0, 1) {
isCrashThread = true
// The faulting m is crashing first so it is the faulting thread in the core dump (see issue #63277):
// in expected operation, the first m will wait until the last m has received the SIGQUIT,
// and then run crash/exit and the process is gone.
- // However, if it spends more than 5 seconds to send SIGQUIT to all ms,
- // any of ms may crash/exit the process after waiting for 5 seconds.
+ // However, if it spends more than 10 seconds to send SIGQUIT to all ms,
+ // any of ms may crash/exit the process after waiting for 10 seconds.
print("\n-----\n\n")
raiseproc(_SIGQUIT)
}
if isCrashThread {
- i := 0
- for (crashing.Load() < mcount()-int32(extraMLength.Load())) && i < 10 {
- i++
- usleep(500 * 1000)
+ // Sleep for short intervals so that we can crash quickly after all ms have received SIGQUIT.
+ // Reset the timer whenever we see more ms received SIGQUIT
+ // to make it have enough time to crash (see issue #64752).
+ timeout := watchdogTimeoutMicros
+ maxCrashing := crashing.Load()
+ for timeout > 0 && (crashing.Load() < mcount()-int32(extraMLength.Load())) {
+ usleep(crashSleepMicros)
+ timeout -= crashSleepMicros
+
+ if c := crashing.Load(); c > maxCrashing {
+ // We make progress, so reset the watchdog timeout
+ maxCrashing = c
+ timeout = watchdogTimeoutMicros
+ }
}
} else {
- usleep(5 * 1000 * 1000)
+ maxCrashing := int32(0)
+ c := crashing.Load()
+ for c > maxCrashing {
+ maxCrashing = c
+ usleep(watchdogTimeoutMicros)
+ c = crashing.Load()
+ }
}
printDebugLog()
crash()