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

cmd/cgo: _crosscall2 not found from .dylib/.so generated by Swig in OS X Mountain Lion #4267

Closed
gopherbot opened this issue Oct 20, 2012 · 9 comments
Milestone

Comments

@gopherbot
Copy link

by nigel@vannevartech.com:

I had to use Swig to wrap some C++ code and had run into an issue with undefined symbols
while trying to run the Go executable in OS X Mountain Lion.

Background:

The C code generated by Swig is compiled into a .so using Clang c++, which has
crosscall2 as an undefined symbol. The Go executable is compiled separately using go
tools, which contains crosscall2().

I have a simplified example, illustrated here:

$ nm go/bin/main | grep crosscall2
0000000000026cc5 T _crosscall2
$ nm go/lib/example.so | grep crosscall2
                 U _crosscall2

And the main executable is linked to example.so by "go build" (presumably by
6l under the hood) like so:

$ DYLD_LIBRARY_PATH=go/lib otool -L go/bin/main 
go/bin/main:
    example.so (compatibility version 0.0.0, current version 0.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 0.0.0, current version 0.0.0)

In the example, I'm wrapping a simple function in C that returns a const char *, which
is then returned to Go as a string.

const char *message() {
  return "A Message";
}

I use this function in Go like:

func main() {
        fmt.Printf("Message is: %v\n", example.Message())
}

Once everything has been compiled, I than run
$ DYLD_LIBRARY_PATH=go/lib go/bin/main 

This operation triggers a call to crosscall2() in the generated C Swig code to create a
Go string. That forces a lazy resolution for crosscall2. In Mountain Lion, it failed to
resolve _crosscall2.

See attached package for complete source code.

What is the expected output?

The expected output is a successful execution with the output:

"Message is: A Message"

What do you see instead?

$ DYLD_LIBRARY_PATH=go/lib go/bin/main 
dyld: lazy symbol binding failed: Symbol not found: _crosscall2
  Referenced from: go/lib/example.so
  Expected in: flat namespace

dyld: Symbol not found: _crosscall2
  Referenced from: go/lib/example.so
  Expected in: flat namespace

SIGTRAP: trace trap
pc: 0x7fff6d36109d


goroutine 1 [syscall]:
example.Message(0xf84002b0d0, 0xf84002b0f0)
    /Users/nigelchoi/Code/crosscall2/go/src/example/example_gc.c:33 +0x32
main.main()
    /Users/nigelchoi/Code/crosscall2/go/src/main/main.go:9 +0x1c

goroutine 2 [syscall]:
created by runtime.main
    /usr/local/go/src/pkg/runtime/proc.c:221
rax     0x0
rbx     0x2400000
rcx     0x0
rdx     0x0
rdi     0x7fff6d3d0060
rsi     0x0
rbp     0xb0080c80
rsp     0xb0080c68
r8      0x7fff6d37ca14
r9      0xf
r10     0xb0080b38
r11     0x7fff6d3d0060
r12     0x1203
r13     0x0
r14     0x7fff6d3d0060
r15     0x269df
rip     0x7fff6d36109d
rflags  0x246
cs      0x2b
fs      0x0
gs      0x0

Which compiler are you using (5g, 6g, 8g, gccgo)?

I'm using the standard Go tools to compile the Go portion (go 1.0.3)

Clang c++ to compile the C portion (Apple clang version 4.1 (tags/Apple/clang-421.11.65)
(based on LLVM 3.1svn))

Which operating system are you using?

OS X Mountain Lion 10.8.2 (12C60)

Which version are you using?  (run 'go version')

go 1.0.3

Please provide any additional information below.

Curiously, another undefined symbol in example.so can be resolved back to the Go
executable, the __cgo_allocate symbol. Could it be bad formatting of the _crosscall2
function in the Mach-O?

$ DYLD_PRINT_BINDINGS=1 DYLD_LIBRARY_PATH=go/lib go/bin/main 
dyld: bind: example.so:0x020FC010 = main:__cgo_allocate, *0x020FC010 = 0x00026801
...
dyld: lazy symbol binding failed: Symbol not found: _crosscall2

Attachments:

  1. crosscall2.tgz (879 bytes)
@robpike
Copy link
Contributor

robpike commented Oct 20, 2012

Comment 1:

Labels changed: added priority-soon, removed priority-triage.

Owner changed to @ianlancetaylor.

Status changed to Accepted.

@rsc
Copy link
Contributor

rsc commented Dec 10, 2012

Comment 4:

Labels changed: added size-l.

@rsc
Copy link
Contributor

rsc commented Jan 31, 2013

Comment 5:

Labels changed: added priority-later, removed priority-soon.

@dvyukov
Copy link
Member

dvyukov commented Mar 17, 2013

Comment 6:

I see similar error messages on Linux when use swig:
foo_test: symbol lookup error:
swig.so: undefined symbol: crosscall2

@shivakumargn
Copy link
Contributor

Comment 7:

same error with windows. Output of "go build -x -v ." from within
GOROOT/misc/swig/callback is attached

Attachments:

  1. swig_error_windows.log (3736 bytes)

@shivakumargn
Copy link
Contributor

Comment 8:

Same error exists in windows but with "C" itself.
Output of "build -x -v ." from GOROOT/misc/swig/callback is attached.

Attachments:

  1. swig_error_windows.log (3736 bytes)

@dsymonds
Copy link
Contributor

Comment 9:

Labels changed: removed go1.1.

@rsc
Copy link
Contributor

rsc commented Jul 30, 2013

Comment 10:

Is this still happening with Go 1.1? External linking might have fixed this.

Labels changed: added go1.2maybe.

@rsc
Copy link
Contributor

rsc commented Sep 11, 2013

Comment 11:

I installed Swig 2.0.10 and, after changing your Makefile to invoke swig with -intgosize
64, was able to build the binary, and it runs fine:
$ DYLD_LIBRARY_PATH=go/lib go/bin/main
Message is: A Message
$
I suspect this was fixed by the introduction of external linking on OS X.

Status changed to Fixed.

@rsc rsc added this to the Go1.2 milestone Apr 14, 2015
@rsc rsc removed the go1.2maybe label Apr 14, 2015
@golang golang locked and limited conversation to collaborators Jun 24, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants