"cannot use struct as struct" due to reflect detection mishandling struct literals
What version of Garble and Go are you using?
$ garble version
mvdan.cc/garble v0.10.1
Build settings:
-buildmode exe
-compiler gc
DefaultGODEBUG panicnil=1
CGO_ENABLED 1
GOARCH amd64
GOOS linux
GOAMD64 v1
$ go version
go version go1.21.1 linux/amd64
What environment are you running Garble on?
go env Output
$ go env GO111MODULE='' GOARCH='amd64' GOBIN='' GOCACHE='/root/.cache/go-build' GOENV='/root/.config/go/env' GOEXE='' GOEXPERIMENT='' GOFLAGS='' GOHOSTARCH='amd64' GOHOSTOS='linux' GOINSECURE='' GOMODCACHE='/root/go/pkg/mod' GONOPROXY='' GONOSUMDB='' GOOS='linux' GOPATH='/root/go' GOPRIVATE='' GOPROXY='https://proxy.golang.org,direct' GOROOT='/usr/local/go' GOSUMDB='sum.golang.org' GOTMPDIR='' GOTOOLCHAIN='auto' GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64' GOVCS='' GOVERSION='go1.21.1' GCCGO='gccgo' GOAMD64='v1' AR='ar' CC='gcc' CXX='g++' CGO_ENABLED='1' GOMOD='/dev/null' GOWORK='' CGO_CFLAGS='-O2 -g' CGO_CPPFLAGS='' CGO_CXXFLAGS='-O2 -g' CGO_FFLAGS='-O2 -g' CGO_LDFLAGS='-O2 -g' PKG_CONFIG='pkg-config' GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build853078376=/tmp/go-build'
What did you do?
Can't build a package that imports github.com/sijms/go-ora/v2
/root/go/bin/garble build -ldflags '-linkmode=external "-extldflags=-Wl,-headerpad=0x500" -w -s' -o XXX *.go
# github.com/sijms/go-ora/v2
xm5H4KwhW9m.go:5: cannot use struct{g1c12lVZnml int; d1MzwrSH int; jyaY6LhUA int; ngmDRT int; s18DOF int; bt1DjT8 int}{…} (value of type struct{g1c12lVZnml int; d1MzwrSH int; jyaY6LhUA int; ngmDRT int; s18DOF int; bt1DjT8 int}) as struct{varchar int; nvarchar int; raw int; number int; date int; timestamp int} value in struct literal
exit status 2
exit status 1
Where do you think the problem originates from?
Where do you think the problem originates from?
The type Connection struct (defined here) is left "ungarbled", including the fields of maxlen, a field of Connection defined to be a struct literal.
In func NewConnection (defined here), a Connection struct is initialized. However, here, the struct literal is initialized with "garbled" fields. And due to the field name mismatches, it doesn't work.
So, tl;dr, it's improper handling of struct literals. I'll see if I can figure it out, but no promises.
Note that there are a number of related issues, like https://github.com/burrowers/garble/issues/785 as well.
Can you please try the latest master again? We've just merged a number of issues relating to structs and type obfuscation.
@mvdan I tested this already with my PR, many deeply nested structs, doesn't work yet.
Nothing changed, I get this error
# github.com/sijms/go-ora/v2
xm5H4KwhW9m.go:5: cannot use struct{g1c12lVZnml int; d1MzwrSH int; jyaY6LhUA int; ngmDRT int; s18DOF int; bt1DjT8 int}{…} (value of type struct{g1c12lVZnml int; d1MzwrSH int; jyaY6LhUA int; ngmDRT int; s18DOF int; bt1DjT8 int}) as struct{varchar int; nvarchar int; raw int; number int; date int; timestamp int} value in struct literal
exit status 2
exit status 1
I tried to debug this.
Here is a minimal reproducer:
package main
import (
"reflect"
)
func main() {}
var _ = reflect.TypeOf(Connection{})
type Connection struct {
MaxLen struct {
Varchar int
}
}
// NewConnection create a new connection from databaseURL string
func NewConnection() *Connection {
return &Connection{
MaxLen: struct {
Varchar int
}{
Varchar: 0x7FFF,
},
}
}
Problem being that to go/ssa the inline struct definition doesn't exist, the value is just directly assigned to the Connection struct.
For go/ast the inline struct definition is an inline struct definition without any external struct it "belongs to"
I'm a bit lost here, the only "easy" solution would be to blacklist all struct fields with the same name globally (because of imports).
There is probably another solution using go/ast, but I sense it will be complicated.
Problem being that to go/ssa the inline struct definition doesn't exist, the value is just directly assigned to the Connection struct.
Could you please show what you mean by this, perhaps with the relevant bits of the SSA statements?
I'd really try to avoid going back to go/ast, or mixing it with go/ssa, because that will just bring lots of other disadvantages.
If go/ssa doesn't track enough information needed to statically analyse this case, we could always raise an issue upstream.
same issue, any progress???
tried go install mvdan.cc/garble@66b61406c12990b7a02c906388027b8ea6c26b4a , same result.