Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segfault when using zap logging #1639

Open
pvbouwel opened this issue May 31, 2024 · 4 comments
Open

Segfault when using zap logging #1639

pvbouwel opened this issue May 31, 2024 · 4 comments

Comments

@pvbouwel
Copy link

pvbouwel commented May 31, 2024

The following program uber.go triggers an unexpected result

package main

import (
	"fmt"
	"time"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

func NewLogger(logLevel string) (*zap.Logger, error) {
	config := zap.Config{
		Encoding:         "json",
		OutputPaths:      []string{"stdout"},
		ErrorOutputPaths: []string{"stdout"},
		EncoderConfig: zapcore.EncoderConfig{
			TimeKey: "time",
			EncodeTime: func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
				enc.AppendString(t.UTC().Format("2006-01-02T15:04:05Z"))
			},
			NameKey:       "logger",
			MessageKey:    "message",
			LevelKey:      "level",
			EncodeLevel:   zapcore.LowercaseLevelEncoder,
		},
	}

	var level zapcore.Level
	err := level.UnmarshalText([]byte(logLevel))
	if err != nil {
		panic(err)
	}
	config.Level = zap.NewAtomicLevelAt(level)
	return config.Build()
}

func main() {
  l, err := NewLogger("INFO")
  if err != nil {
	fmt.Print("Creating logger failed")
  }
  l.Info("Hello log")
}

Expected result

$ go run uber.go
{"level":"info","time":"2024-05-31T14:21:44Z","message":"Hello log"}

Got

$ yaegi run uber.go
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x128 pc=0x7f5c3f]

goroutine 1 [running]:
github.com/traefik/yaegi/interp.nodeType2(0xc00018e908, 0xc00067e750, 0xc000522500, {0xc000595220, 0x3, 0x4})
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/type.go:1083 +0x3aff
github.com/traefik/yaegi/interp.genType(0xc00018e908, 0xc00067e750, {0xc00003a720, 0x19}, 0xc00051f040, {0xc000540e48, 0x1, 0x1}, {0xc000595220, 0x3, ...})
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/type.go:1136 +0xcb
github.com/traefik/yaegi/interp.nodeType2(0xc00018e908, 0xc00067e750, 0xc0004f0a00, {0xc000595220, 0x2, 0x4})
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/type.go:847 +0x56bb
github.com/traefik/yaegi/interp.nodeType2(0xc00018e908, 0xc00067e750, 0xc0004f08c0, {0xc000693010, 0x1, 0x2})
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/type.go:425 +0x2f4b
github.com/traefik/yaegi/interp.nodeType2(0xc00018e908, 0xc00067e750, 0xc0004f03c0, {0xc00080dbc8, 0x0, 0x1})
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/type.go:1079 +0x3ad7
github.com/traefik/yaegi/interp.nodeType(...)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/type.go:400
github.com/traefik/yaegi/interp.(*Interpreter).gta.func1(0xc0004f0140)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/gta.go:320 +0x11d5
github.com/traefik/yaegi/interp.(*node).Walk(0xc0004f0140, 0xc0005430c8, 0x0)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:282 +0x2e
github.com/traefik/yaegi/interp.(*node).Walk(0xc0004f0000, 0xc0005430c8, 0x0)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:286 +0x6b
github.com/traefik/yaegi/interp.(*node).Walk(0xc0004ef900, 0xc0005430c8, 0x0)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:286 +0x6b
github.com/traefik/yaegi/interp.(*Interpreter).gta(0xc00018e908, 0xc0004ef900, {0xc00003a600, 0x1d}, {0xc00069e001, 0x16}, {0xc0008087f0, 0x6})
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/gta.go:20 +0x22b
github.com/traefik/yaegi/interp.(*Interpreter).importSrc(0xc00018e908, {0xc00003a3c0, 0x1e}, {0xc00069e001, 0x16}, 0x1)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/src.go:109 +0x925
github.com/traefik/yaegi/interp.(*Interpreter).gta.func1(0xc00080b2c0)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/gta.go:273 +0xcdb
github.com/traefik/yaegi/interp.(*node).Walk(0xc00080b2c0, 0xc000543e10, 0x0)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:282 +0x2e
github.com/traefik/yaegi/interp.(*node).Walk(0xc00080af00, 0xc000543e10, 0x0)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:286 +0x6b
github.com/traefik/yaegi/interp.(*node).Walk(0xc00080ac80, 0xc000543e10, 0x0)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:286 +0x6b
github.com/traefik/yaegi/interp.(*Interpreter).gta(0xc00018e908, 0xc00080ac80, {0xc00003a3c0, 0x1e}, {0xc00003a341, 0x17}, {0xc00011d3d0, 0x7})
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/gta.go:20 +0x22b
github.com/traefik/yaegi/interp.(*Interpreter).importSrc(0xc00018e908, {0xc0001201e0, 0x16}, {0xc00003a341, 0x17}, 0x1)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/src.go:109 +0x925
github.com/traefik/yaegi/interp.(*Interpreter).gta.func1(0xc0004ecc80)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/gta.go:273 +0xcdb
github.com/traefik/yaegi/interp.(*node).Walk(0xc0004ecc80, 0xc000544b58, 0x0)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:282 +0x2e
github.com/traefik/yaegi/interp.(*node).Walk(0xc0004ec640, 0xc000544b58, 0x0)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:286 +0x6b
github.com/traefik/yaegi/interp.(*node).Walk(0xc0004ec3c0, 0xc000544b58, 0x0)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:286 +0x6b
github.com/traefik/yaegi/interp.(*Interpreter).gta(0xc00018e908, 0xc0004ec3c0, {0xc0001201e0, 0x16}, {0xc0001200c1, 0xf}, {0xc00025ebdd, 0x3})
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/gta.go:20 +0x22b
github.com/traefik/yaegi/interp.(*Interpreter).importSrc(0xc00018e908, {0xc00025e290, 0x4}, {0xc0001200c1, 0xf}, 0x1)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/src.go:109 +0x925
github.com/traefik/yaegi/interp.(*Interpreter).gta.func1(0xc00012aa00)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/gta.go:273 +0xcdb
github.com/traefik/yaegi/interp.(*node).Walk(0xc00012aa00, 0xc0005458a0, 0x0)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:282 +0x2e
github.com/traefik/yaegi/interp.(*node).Walk(0xc00012a3c0, 0xc0005458a0, 0x0)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:286 +0x6b
github.com/traefik/yaegi/interp.(*node).Walk(0xc00012a140, 0xc0005458a0, 0x0)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:286 +0x6b
github.com/traefik/yaegi/interp.(*Interpreter).gta(0xc00018e908, 0xc00012a140, {0xc00025e290, 0x4}, {0xc00025e290, 0x4}, {0xc00025e290, 0x4})
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/gta.go:20 +0x22b
github.com/traefik/yaegi/interp.(*Interpreter).gtaRetry(0xc00018e908, {0xc000115a88?, 0xc0000c4820?, 0xc0001159c8?}, {0xc00025e290, 0x4}, {0xc00025e290, 0x4})
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/gta.go:395 +0x158
github.com/traefik/yaegi/interp.(*Interpreter).CompileAST(0xc00018e908, {0x10d3588?, 0xc0000c4820?})
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/program.go:92 +0x11f
github.com/traefik/yaegi/interp.(*Interpreter).compileSrc(0xc00018e908, {0xc0004d8000?, 0x392?}, {0x7ffc649acef4?, 0xc00044c000?}, 0x0?)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/program.go:64 +0xaa
github.com/traefik/yaegi/interp.(*Interpreter).eval(0xc00018e908, {0xc0004d8000?, 0x392?}, {0x7ffc649acef4?, 0xc000696000?}, 0x0?)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:554 +0x25
github.com/traefik/yaegi/interp.(*Interpreter).EvalPath(0xc00018e908, {0x7ffc649acef4, 0x7})
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/interp.go:512 +0xa6
main.runFile(0xc00018e908, {0x7ffc649acef4, 0x7}, 0x0)
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/cmd/yaegi/run.go:153 +0xd7
main.run({0xc0000362c0, 0x1, 0x1})
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/cmd/yaegi/run.go:116 +0xb65
main.main()
	/home/peter/go/pkg/mod/github.com/traefik/[email protected]/cmd/yaegi/yaegi.go:133 +0xca

Yaegi Version

0.16.1

Additional Notes

We had been using an older version of zap successfully in a custom traefik plugin but that version stops working from traefik v2.11.1 onwards. For the traefik version we are on (v2.10.1) zap v1.23.0 works but newer versions of zap do not.
So in summary:

@ldez
Copy link
Contributor

ldez commented May 31, 2024

Hello,

FYI, the support of Traefik v2.10 has ended in 2024/02 https://doc.traefik.io/traefik/deprecation/releases/
The Traefik security issues are only fixed on v2.11 and v3.0.

Traefik v2.10 uses an old version of yaegi and go1.20 (currently, the Go team supports only go1.21 and go1.22)

I think that the segfault comes from a divergence between the min Go required of yaegi v0.15 (go1.19/go1.20), the version of Go used by Traefik v2.10 (go1.20), and the Go version required by your plugin (go1.22.2).

I recommend migration from zap to slog because it's the new standard way to use structured logs.

I also highly recommend migrating to, at least, Traefik v2.11.

@pvbouwel
Copy link
Author

pvbouwel commented Jun 3, 2024

Thank you for the quick feedback. Yes, upgrade is necessary and one of the reasons of reporting this as it was unclear what would be a viable upgrade strategy. Thank you for the suggestion of slog, that could be the way forward for us.

Because I suspected the old Traefik version I did try with plain yaegi locally so the stacktrace in this ticket is really from an installation using go install github.com/traefik/yaegi/cmd/[email protected]

@theclapp
Copy link
Contributor

theclapp commented Jun 7, 2024

@pvbouwel said:

Because I suspected the old Traefik version I did try with plain yaegi locally so the stacktrace in this ticket is really from an installation using go install github.com/traefik/yaegi/cmd/[email protected]

The stack trace ends with

github.com/traefik/yaegi/interp.nodeType2(0xc00018e908, 0xc00067e750, 0xc000522500, {0xc000595220, 0x3, 0x4})
/home/peter/go/pkg/mod/github.com/traefik/[email protected]/interp/type.go:1083 +0x3aff

Lines 1079-1083 of interp/type.go are:

https://github.com/traefik/yaegi/blob/v0.16.1/interp/type.go#L1079-L1083

typ, err := nodeType2(interp, sc, c.child[l-1], seen)
if err != nil {
	return nil, err
}
incomplete = incomplete || typ.incomplete

So we get typ, err from a recursive call of nodetype2 on 1079, there's no error, and the nil pointer is from dereferencing typ on 1083.

I believe this is an instance (not a dup, exactly, since this issue actually has a test case) of #1636.

@pvbouwel
Copy link
Author

We have successfully moved to slog and are now transitioning to traefik v3.0.1 so we are not having any further impact from this.

I understand from the update of theclapp it might be useful to still track it separately so I'll leave the decision to close this issue to a maintainer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants