aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/ringlogger/global.go
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2020-12-03 13:40:02 +0100
committerJason A. Donenfeld <Jason@zx2c4.com>2020-12-09 16:01:47 +0100
commit450189162e15c813713b5c3a5208bdb6380c17f8 (patch)
tree40c4d93b70a705f50559a72aac135b6a6129336e /ringlogger/global.go
parentmanager: use service subscriptions on win 8+ (diff)
downloadwireguard-windows-450189162e15c813713b5c3a5208bdb6380c17f8.tar.xz
wireguard-windows-450189162e15c813713b5c3a5208bdb6380c17f8.zip
ringlogger: hook into global panic writer
This is a grotesque hack, and hopefully upstream Go will provide a nicer way of doing this, but already it seems quite adept at catching panics. See https://github.com/golang/go/issues/42888 for more info. This requires us to rewrite the ringlogger path to avoid all allocations. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'ringlogger/global.go')
-rw-r--r--ringlogger/global.go35
1 files changed, 35 insertions, 0 deletions
diff --git a/ringlogger/global.go b/ringlogger/global.go
index 0d99e5a0..6f4458ca 100644
--- a/ringlogger/global.go
+++ b/ringlogger/global.go
@@ -8,6 +8,7 @@ package ringlogger
import (
"log"
"path/filepath"
+ "unsafe"
"golang.zx2c4.com/wireguard/windows/conf"
)
@@ -28,5 +29,39 @@ func InitGlobalLogger(tag string) error {
}
log.SetOutput(Global)
log.SetFlags(0)
+ overrideWrite = globalWrite
return nil
}
+
+//go:linkname overrideWrite runtime.overrideWrite
+var overrideWrite func(fd uintptr, p unsafe.Pointer, n int32) int32
+
+var globalBuffer [maxLogLineLength - 1 - maxTagLength - 3]byte
+var globalBufferLocation int
+
+//go:nosplit
+func globalWrite(fd uintptr, p unsafe.Pointer, n int32) int32 {
+ b := (*[1 << 30]byte)(p)[:n]
+ for len(b) > 0 {
+ amountAvailable := len(globalBuffer) - globalBufferLocation
+ amountToCopy := len(b)
+ if amountToCopy > amountAvailable {
+ amountToCopy = amountAvailable
+ }
+ copy(globalBuffer[globalBufferLocation:], b[:amountToCopy])
+ b = b[amountToCopy:]
+ globalBufferLocation += amountToCopy
+ foundNl := false
+ for i := globalBufferLocation - amountToCopy; i < globalBufferLocation; i++ {
+ if globalBuffer[i] == '\n' {
+ foundNl = true
+ break
+ }
+ }
+ if foundNl || len(b) > 0 {
+ Global.Write(globalBuffer[:globalBufferLocation])
+ globalBufferLocation = 0
+ }
+ }
+ return n
+}