golang / protobuf

Go support for Google's protocol buffers
BSD 3-Clause "New" or "Revised" License
9.8k stars 1.58k forks source link

Panic when use enum.String() before main() #1639

Closed lvhuat closed 3 months ago

lvhuat commented 3 months ago

What version of protobuf and what language are you using? protobuf version: v1.5.4 language: golang

What did you do? Use Enum String to init variable in package.

What did you expect to see? Process start smoothly

What did you see instead? Panic when call enumItem.String()

Make sure you include information that can help us debug (full error message, exception listing, stack trace, logs).

enum.proto

syntax = "proto3";

option go_package = "./main";

enum TestEnum {
  NA = 0;
  TEST_VALUE = 1;
}

main.go

package main

import "fmt"

var (
    str = TestEnum_TEST_VALUE.String() // it panic error.
)

func main() {
    fmt.Println("hello")
}

Print info:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x80 pc=0x4fcf9c]

goroutine 1 [running]:
google.golang.org/protobuf/internal/impl.Export.EnumStringOf({}, {0x0?, 0x0?}, 0x1)
        /home/keto/src/cryptobroker/account/vendor/google.golang.org/protobuf/internal/impl/api_export.go:75 +0x1c
main.TestEnum.String(0x1)
        /home/keto/src/cryptobroker/account/test/enum.pb.go:49 +0x31
main.init()
        /home/keto/src/cryptobroker/account/test/main.go:6 +0x188

Anything else we should know about your project / environment? $ go version go version go1.22.5 linux/amd64

$ protoc --version libprotoc 26.1

$ protoc-gen-go --version protoc-gen-go v1.34.2

My Guess After golang 1.21, golang has changed its initial order https://tip.golang.org/doc/go1.21

Package initialization order is now specified more precisely. The new algorithm is:

Sort all packages by import path.
Repeat until the list of packages is empty:
Find the first package in the list for which all imports are already initialized.
Initialize that package and remove it from the list.
znkr commented 3 months ago

Protos should always use a dedicated package and not share that package with non proto-generated Go code. I am closing this, because I am pretty sure that's the reason here. Please reopen if this also happens with using a dedicate package for the proto generated code.

puellanivis commented 3 months ago

Yes, it has to do with in-package init ordering. It’s resolved by spinning your protobuf relevant code out into its own package (as has already been said).