On Tue, Jun 14, 2011 at 1:24 AM, Ian Lance Taylor <iant@xxxxxxxxxx> wrote: > LRN <lrn1986@xxxxxxxxx> writes: > >> However, if i put anything more complex than "return 1" into Myfunc in >> Go (such as using fmt.Printf() or returning a string - with >> appropriate prototype changes to 'string' and 'char*' in Go and C, >> naturally), it segfaults at runtime. >> >> Is that a limitation of gccgo, a bug, or am i simply doing something wrong? > > This is a current limitation of gccgo. At present nothing initializes > the packages imported by a packaged compiled into a shared library. > This is fixable with a bit of thought but is not high on the priority > list. How's it going? Any news. As a side note, after discussing [1] static linking in Go (due to the fact that go doesn't have dynamic linking), i thought a bit, and came up with this: ---------main_shared.go package main_shared import ( "fmt" ) func Myfunc () string { return "result" } type ComplexType struct { somestring string someint int } func Myfunc2 (n int) (r ComplexType) { r.somestring = fmt.Sprintf ("a formatted version of integer %d", n) r.someint = n return } ---------end of main_shared.go ---------main_executable.go package main import ( "fmt" ) func myfunc () string __asm__ ("go.main_shared.Myfunc") type ComplexType struct { somestring string someint int } func myfunc2 (n int) (r ComplexType) __asm__ ("go.main_shared.Myfunc2") func main() { s := myfunc () fmt.Printf ("Calling myfunc() resulted in a string %s\n", s) n := 5 c := myfunc2 (n) fmt.Printf ("Passing %d to myfunc2() resulted in %s (with an integer %d)\n", n, c.somestring, c.someint) } ---------end of main_executable.go compile and run: gccgo -g -O0 -fPIC -shared main_shared.go -o libmain_shared.so -lgcc gccgo -g -O0 main_executable.go -o main -L. -lmain_shared LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./main and it prints: Calling myfunc() resulted in a string result Passing 5 to myfunc2() resulted in a formatted version of integer 5 (with an integer 5) Which was expected. ldd says that the executable is linked to libgo and libmain_shared: $ LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ldd ./main linux-vdso.so.1 => (0x00007fff9022b000) libmain_shared.so => ./libmain_shared.so (0x00007f0e4a7fa000) libgo.so.0 => /usr/lib/x86_64-linux-gnu/libgo.so.0 (0x00007f0e49bb7000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f0e49934000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f0e4971e000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0e4939a000) /lib64/ld-linux-x86-64.so.2 (0x00007f0e4a9ff000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f0e4917d000) I thought that since the problem lies in libgo not being initializing, then it should work with the main executable written in Go, because it does initialize its own runtime library, which is then shared with libmain_shared. My guess is that this will only work when both modules are linked to the same version of libgo. Are there any other problems with this kind of linking? Is it ever going to be a valid way of linking Go modules, or just a hack? Also, it really makes me think about putting ComplexType definition into separate file and calling it a "header" ... weird. P.S. This time it didn't work without -fPIC for some reason. [1] http://comments.gmane.org/gmane.comp.lang.go.general/41770