aboutsummaryrefslogtreecommitdiff
path: root/src/log
diff options
context:
space:
mode:
authorJonathan Amsterdam <jba@google.com>2023-07-28 10:35:10 -0400
committerJonathan Amsterdam <jba@google.com>2023-08-07 15:10:55 +0000
commitcf39736f87613195aa8a2d7304ee20d7d9eeaa47 (patch)
treedeb5b0a6e09993bdd8020d54a568343cc30343a0 /src/log
parent8a6acecfab2879ba4e26487c99f204ede8b3d935 (diff)
downloadgo-cf39736f87613195aa8a2d7304ee20d7d9eeaa47.tar.gz
go-cf39736f87613195aa8a2d7304ee20d7d9eeaa47.zip
log/slog: don't panic on aliased Record
If the shared slice in a copied is modified, make a copy of it and insert an attribute that warns of the bug. Previously, we panicked, and panics in logging code should be avoided. Change-Id: I24e9b0bf5c8cd09cf733e7dae8a82d025ef214e5 Reviewed-on: https://go-review.googlesource.com/c/go/+/513760 Run-TryBot: Jonathan Amsterdam <jba@google.com> Reviewed-by: Alan Donovan <adonovan@google.com> Reviewed-by: Ian Cottrell <iancottrell@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/log')
-rw-r--r--src/log/slog/record.go4
-rw-r--r--src/log/slog/record_test.go11
2 files changed, 10 insertions, 5 deletions
diff --git a/src/log/slog/record.go b/src/log/slog/record.go
index 67b76f34e1..82acc7ac7b 100644
--- a/src/log/slog/record.go
+++ b/src/log/slog/record.go
@@ -109,7 +109,9 @@ func (r *Record) AddAttrs(attrs ...Attr) {
if cap(r.back) > len(r.back) {
end := r.back[:len(r.back)+1][len(r.back)]
if !end.isEmpty() {
- panic("copies of a slog.Record were both modified")
+ // Don't panic; copy and muddle through.
+ r.back = slices.Clip(r.back)
+ r.back = append(r.back, String("!BUG", "AddAttrs unsafely called on copy of Record made without using Record.Clone"))
}
}
ne := countEmptyGroups(attrs[i:])
diff --git a/src/log/slog/record_test.go b/src/log/slog/record_test.go
index 15d9330a85..931ab66041 100644
--- a/src/log/slog/record_test.go
+++ b/src/log/slog/record_test.go
@@ -96,12 +96,15 @@ func TestAliasingAndClone(t *testing.T) {
r1.back = b
// Make a copy that shares state.
r2 := r1
- // Adding to both should panic.
+ // Adding to both should insert a special Attr in the second.
+ r1AttrsBefore := attrsSlice(r1)
r1.AddAttrs(Int("p", 0))
- if !panics(func() { r2.AddAttrs(Int("p", 1)) }) {
- t.Error("expected panic")
- }
+ r2.AddAttrs(Int("p", 1))
+ check(r1, append(slices.Clip(r1AttrsBefore), Int("p", 0)))
r1Attrs := attrsSlice(r1)
+ check(r2, append(slices.Clip(r1AttrsBefore),
+ String("!BUG", "AddAttrs unsafely called on copy of Record made without using Record.Clone"), Int("p", 1)))
+
// Adding to a clone is fine.
r2 = r1.Clone()
check(r2, r1Attrs)