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

cgo gcc ld error: undefined reference to `mk_datum' #41727

Closed
balta2ar opened this issue Oct 1, 2020 · 3 comments
Closed

cgo gcc ld error: undefined reference to `mk_datum' #41727

balta2ar opened this issue Oct 1, 2020 · 3 comments

Comments

@balta2ar
Copy link

@balta2ar balta2ar commented Oct 1, 2020

Coming from this issue: go-delve/delve#2187

What version of Go are you using (go version)?

$ go version
go version go1.15.2 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/ybochkarev/.cache/go-build"
GOENV="/home/ybochkarev/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/ybochkarev/.gvm/pkgsets/go1.15.2/global/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/ybochkarev/.gvm/pkgsets/go1.15.2/global"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/ybochkarev/.gvm/gos/go1.15.2"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/ybochkarev/.gvm/gos/go1.15.2/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build670122447=/tmp/go-build -gno-record-gcc-switches"

What did you do?

$ git clone --depth=1 https://github.com/cfdrake/go-gdbm && cd go-gdbm
$ go build # builds OK
$ go test -v
=== RUN   TestVersion
--- PASS: TestVersion (0.00s)
=== RUN   TestKeys
--- PASS: TestKeys (0.01s)
=== RUN   TestRecreate
--- PASS: TestRecreate (0.00s)
=== RUN   TestWriteErrorWhenReader
--- PASS: TestWriteErrorWhenReader (0.01s)
=== RUN   TestReplace
--- PASS: TestReplace (0.01s)
=== RUN   TestExists
--- PASS: TestExists (0.01s)
=== RUN   TestDelete
--- PASS: TestDelete (0.01s)
=== RUN   TestReorganize
--- PASS: TestReorganize (0.01s)
=== RUN   TestSync
--- PASS: TestSync (0.01s)
PASS

$ CGO_CFLAGS='-O0 -g' go build -gcflags='all=-N -l'
# _/home/ybochkarev/dev/from-src/go-gdbm
/usr/bin/ld: $WORK/b001/_x002.o: in function `_cgo_d74df84b6f3c_Cfunc_mk_datum':
/tmp/go-build/cgo-gcc-prolog:300: undefined reference to `mk_datum'
collect2: error: ld returned 1 exit status

$ CGO_CFLAGS='-O1 -g' go build -gcflags='all=-N -l' # builds OK

$ CGO_CFLAGS='-O2 -g' go build -gcflags='all=-N -l' # builds OK

What did you expect to see?

I'd expect it to build with CGO_CFLAGS='-O0 -g' because these are the flags that GoLand uses when running a program in a debugger (compiling first).

What did you see instead?

Link (ld) error.

gcc versions

I tried two versions with the same result:

$ gcc --version 
gcc (Ubuntu 9.3.0-10ubuntu2) 9.3.0

$ gcc --version
gcc (Ubuntu 10-20200411-0ubuntu1) 10.0.1 20200411 (experimental) [master revision bb87d5cc77d:75961caccb7:f883c46b4877f637e0fa5025b4d6b5c9040ec566]
@cuonglm
Copy link
Contributor

@cuonglm cuonglm commented Oct 1, 2020

I think this is working as expected, as how gcc performs optimization with inline function. Example, this program:

inline int foo() {
    return 0;
}

int main() {
    return foo();
}

fails to compile, but this does:

static inline int foo() {
    return 0;
}

int main() {
    return foo();
}

Changing inline datum mk_datum(char * s) to static inline datum mk_datum(char * s), the repo is compiled successfully.

@balta2ar
Copy link
Author

@balta2ar balta2ar commented Oct 1, 2020

Thank you, @cuonglm, I submitted a PR. I'm not even close to be a compiler expert, but intuitively it looks strange that this case works with more aggressive optimization (O1, O2) and breaks with minimal optimization (O0). I'm not arguing with the fact that it may indeed be an expected behavior, just pointing out that it feels misleading to me.

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Oct 1, 2020

The behavior does seem odd, but it's behavior in the C compiler, so it's not something that the Go project can fix.

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

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.