Cgo and atexit in a .o file

140 views
Skip to first unread message

Ostsol

unread,
Jan 23, 2011, 12:29:35 AM1/23/11
to golang-nuts
Let me start by saying that I am not attempting to use 'atexit'. That
topic has already been discussed. However, 'atexit' happens to be in
use in a library that I -am- trying to use via cgo.

It is likely that there would be no problem had I decided to link to
the library were it compiled as a shared object. However, I decided
to take advantage of cgo's ability to include C .o files to more-or-
less statically link with a C library. When I do this, cgo succeeds
and the library is created, but when I try to use that library in a Go
program, the linker (6l) spits out the following error:

/home/ostsol/go/pkg/linux_amd64/cgotest.a(testlib.o)(.text): atexit:
not defined
atexit: not defined

I have created a small test case to eliminate the possibility of the
problem being with the library. I have uploaded it to my code
dump[1].

Am I doing something wrong or is this behaviour expected?

1. http://code.google.com/p/cheesesuncodedump/source/browse/cgoerror


-Daniel

Ian Lance Taylor

unread,
Jan 23, 2011, 12:41:16 AM1/23/11
to Ostsol, golang-nuts
Ostsol <ost...@gmail.com> writes:

> Let me start by saying that I am not attempting to use 'atexit'. That
> topic has already been discussed. However, 'atexit' happens to be in
> use in a library that I -am- trying to use via cgo.
>
> It is likely that there would be no problem had I decided to link to
> the library were it compiled as a shared object. However, I decided
> to take advantage of cgo's ability to include C .o files to more-or-
> less statically link with a C library. When I do this, cgo succeeds
> and the library is created, but when I try to use that library in a Go
> program, the linker (6l) spits out the following error:
>
> /home/ostsol/go/pkg/linux_amd64/cgotest.a(testlib.o)(.text): atexit:
> not defined
> atexit: not defined
>
> I have created a small test case to eliminate the possibility of the
> problem being with the library. I have uploaded it to my code
> dump[1].

The basic problem here is that atexit is not defined in /lib/libc.so.6.
It's defined in /usr/lib/libc_nonshared.a. That file is pulled in
because /usr/lib/libc.so is not a shared library as one might think from
the name, it's a linker script that tells the linker to link against
libc_nonshared.a. 6l knows about shared libraries, but it doesn't know
about linker scripts.

It may work if you explicitly link against /usr/lib/libc_nonshared.a.
I'm not sure what else to recommend. The approach that cgo uses to
determine which shared libraries it needs to link against does not work
for finding .a files. Conceivably cgo could ask the linker to generate
a map file. Or, simpler, we could just always tell cgo to link against
libc_nonshared.a on glibc based systems.

(The atexit function is not in libc.so.6 because it needs to record the
correct shared library handle so that when a shared library opened via
dlopen calls atexit the functions can be run if the library is
dlclose'd.)

Ian

Ostsol

unread,
Jan 23, 2011, 12:34:57 PM1/23/11
to golang-nuts
Ah, very informative. Looking at the source for the library in
question, however, it looks possible to modify it to remove the need
for 'atexit'. It appears to simply be a safeguard against the
possibility that the programmer does not kill a key object before the
program terminates.

Thanks!

-Daniel
Reply all
Reply to author
Forward
0 new messages