Skip to content

Commit a042989

Browse files
committed
all: start/stop flight recorder conditionally
1 parent 14f8f41 commit a042989

4 files changed

Lines changed: 45 additions & 13 deletions

File tree

intra/core/dontpanic.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func RecoverFn(aux string, fn Finally) (didpanic bool) {
6565
msg := fmt.Sprintf("%s [%d] %v\n", aux, DontExit, recovered)
6666
log.E2(parentCallerDepthAt+1, msg)
6767

68-
runtimelog()
68+
recorderToConsole()
6969
applog(DontExit, msg)
7070
return didpanic
7171
}
@@ -86,8 +86,12 @@ func Record(start bool) (recording bool, err error) {
8686
return
8787
}
8888

89+
func recorderToConsole() (logged bool) {
90+
return DumpRecorder(true /* onConsole */)
91+
}
92+
8993
// Logs Cmsg using recoder.WriteTo
90-
func runtimelog() (logged bool) {
94+
func DumpRecorder(onConsole bool) (logged bool) {
9195
if !recorder.Enabled() {
9296
return
9397
}
@@ -104,10 +108,14 @@ func runtimelog() (logged bool) {
104108
}()
105109

106110
r := bytes.NewBuffer(lob)
107-
n, err := recorder.WriteTo(r)
111+
n, _ := recorder.WriteTo(r)
108112

109113
if logged = n > 0; logged {
110-
log.Cmsg("%s\n%v", r.String(), err)
114+
if onConsole {
115+
log.Cmsg(r.String())
116+
} else {
117+
log.TALL(r.String(), nil /* no-stacktrace*/)
118+
}
111119
}
112120

113121
return
@@ -125,7 +133,7 @@ func Recover(code ExitCode, aux any) (didpanic bool) {
125133
msg := fmt.Sprintf("%s [%d] %v [%s]\n", aux, code, recovered, stamp())
126134
log.E2(parentCallerDepthAt, msg)
127135

128-
runtimelog()
136+
recorderToConsole()
129137
applog(code, msg)
130138
return didpanic
131139
}

intra/log/log.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ func T(msg string, args ...any) {
190190
// TALL logs the stack trace of all active goroutines.
191191
func TALL(msg string, atleast64k []byte) {
192192
E2(callerat, "----START----")
193-
Glogger.Stack(callerat, msg, atleast64k)
193+
Glogger.Stack(callerat, msg, atleast64k /*may be nil*/)
194194
E2(callerat, "----STOPP----")
195195
}
196196

intra/log/logger.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ package log
3434
import (
3535
"context"
3636
"fmt"
37+
"hash/fnv"
3738
golog "log"
3839
"os"
3940
"reflect"
@@ -73,7 +74,7 @@ type simpleLogger struct {
7374
cskips atomic.Uint32 // number of dropped console msgs
7475

7576
stmu sync.Mutex // guards stcount
76-
stcount map[string]uint32 // stack trace counter for identical traces
77+
stcount map[uint64]uint32 // stack trace counter for identical traces
7778

7879
o *golog.Logger
7980
e *golog.Logger
@@ -241,7 +242,7 @@ func defaultLogger() *simpleLogger {
241242
level: defaultLevel,
242243
clevel: defaultClevel,
243244
cmsgC: make(chan *conMsg, consoleChSize),
244-
stcount: make(map[string]uint32),
245+
stcount: make(map[uint64]uint32),
245246
// gomobile pipes stderr & stdout to logcat
246247
// github.com/golang/mobile/blob/fa72addaaa/internal/mobileinit/mobileinit_android.go#L74-L92
247248
e: golog.New(os.Stderr, "", defaultFlags),
@@ -291,12 +292,23 @@ func (l *simpleLogger) clearStCounts() {
291292
clear(l.stcount)
292293
}
293294

295+
// xor fold fnv to 48 bits: www.isthe.com/chongo/tech/comp/fnv
296+
func fhash(b []byte) uint64 {
297+
h := fnv.New64a()
298+
_, _ = h.Write(b)
299+
return h.Sum64()
300+
}
301+
294302
func (l *simpleLogger) incrStCount(id string) (c uint32) {
295303
l.stmu.Lock()
296304
defer l.stmu.Unlock()
297305

298-
c = l.stcount[id]
299-
l.stcount[id]++
306+
if len(id) > 500 {
307+
id = id[:500]
308+
}
309+
loc := fhash([]byte(id))
310+
c = l.stcount[loc]
311+
l.stcount[loc]++
300312
return c
301313
}
302314

intra/tun2socks.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,15 @@ func LogLevel(gologLevel, consolelogLevel int32) {
116116
debug.SetTraceback(one.s())
117117
}
118118

119-
recording, recerr := core.Record(dbg)
119+
log.I("tun: new levels; golog: %d, consolelog: %d; debug? %t",
120+
dlvl, clvl, dbg)
121+
}
120122

121-
log.I("tun: new levels; golog: %d, consolelog: %d; debug? %t, recording? %t, recorder error: %v",
122-
dlvl, clvl, dbg, recording, recerr)
123+
// FlightRecorder starts Go runtime's flight recorder if y is true,
124+
// and stops it if y is false. The contents of the flight recorder
125+
// (limited to 15s) is written to log.Console on panics.
126+
func FlightRecorder(y bool) (bool, error) {
127+
return core.Record(y)
123128
}
124129

125130
// LowMem triggers garbage collection cycle & allows for
@@ -202,6 +207,13 @@ func PrintStack(onConsole bool) {
202207
}
203208
}
204209

210+
// PrintFlightRecord dumps the contents of the flight recorder
211+
// to stdout if onConsole is false, otherwise to Console.
212+
// For testing only.
213+
func PrintFlightRecord(onConsole bool) (logged bool) {
214+
return core.DumpRecorder(onConsole)
215+
}
216+
205217
// PanicAtRandom instruct portions under test of the network engine
206218
// to panic at random.
207219
func PanicAtRandom(y bool) {

0 commit comments

Comments
 (0)