]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: invalid negative frequency while tracing
authorMeng Zhuo <mzh@golangcn.org>
Fri, 17 Dec 2021 06:15:42 +0000 (14:15 +0800)
committerZhuo Meng <mzh@golangcn.org>
Wed, 29 Dec 2021 01:44:55 +0000 (01:44 +0000)
The riscv64 Hifive Unmatched is the only platform that
failed on testcase TestAnalyzeAnnotations occasionally
after CL 332954 had merged. The failure happens when
ticks per second (freq) is over 1e12 which causing the timestamps
of two events are same.

There are 2 reasons causing big frequency:
1. RDCYCLE is HART based according to the riscv manual which makes
   negative ticks delta
2. negative float64 -> uint64 is undefined and "lucky" negative float
   is too big to handle for trace

For #46737

Change-Id: I1f3c1ac31aae249969000c719c32aaf5a66d29a5
Reviewed-on: https://go-review.googlesource.com/c/go/+/373034
Trust: Zhuo Meng <mzh@golangcn.org>
Run-TryBot: Zhuo Meng <mzh@golangcn.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
src/runtime/asm_riscv64.s
src/runtime/trace.go

index 0e813189d4d21b7b56076efb1c55b93dde865f36..2a4837b3991b5b7577548ca15f8f6a46b1c2196f 100644 (file)
@@ -81,7 +81,10 @@ TEXT setg_gcc<>(SB),NOSPLIT,$0-0
 
 // func cputicks() int64
 TEXT runtime·cputicks(SB),NOSPLIT,$0-8
-       RDCYCLE A0
+       // RDTIME to emulate cpu ticks
+       // RDCYCLE reads counter that is per HART(core) based
+       // according to the riscv manual, see issue 46737
+       RDTIME  A0
        MOV     A0, ret+0(FP)
        RET
 
index 5b14a5f553922526b1667c71e067cddec43dbbfc..71a29d4316ec8e14c1a83c9d357f17f08b7d49fc 100644 (file)
@@ -426,6 +426,9 @@ func ReadTrace() []byte {
                trace.footerWritten = true
                // Use float64 because (trace.ticksEnd - trace.ticksStart) * 1e9 can overflow int64.
                freq := float64(trace.ticksEnd-trace.ticksStart) * 1e9 / float64(trace.timeEnd-trace.timeStart) / traceTickDiv
+               if freq <= 0 {
+                       throw("trace: ReadTrace got invalid frequency")
+               }
                trace.lockOwner = nil
                unlock(&trace.lock)
                var data []byte