Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

undefined reference to `__ctype_b' on glibc 2.5-3

1,563 views
Skip to first unread message

wong_...@yahoo.ca

unread,
Sep 28, 2007, 1:29:04 PM9/28/07
to
I got an link error for undefined reference to `__ctype_b' and
`__ctype_tolower'.

The glibc version is 2.5-3 and gcc version is 4.1.2 20070626 (Red Hat
4.1.2-13) on FC6

$ make
/bin/sh ../../../libtool --mode=link g++ -O -O0 -DOS_LINUX -DOS_UNIX -
DLITTLE_ENDIAN -DUSE_PTHREADS -O -o RASMain RASMain.o RASServer.o
libHw.la -L/usr/lib -lUtility /usr/lib/libpopt.so -ldl
g++ -O -O0 -DOS_LINUX -DOS_UNIX -DLITTLE_ENDIAN -DUSE_PTHREADS -O -o
RASMain RASMain.o RASServer.o /usr/lib/libpopt.so ./.libs/libHw.al -L/
usr/lib -lUtility -ldl
/usr/lib/libUtility.so: undefined reference to `__ctype_tolower'
/usr/lib/libUtility.so: undefined reference to `__ctype_b'
collect2: ld returned 1 exit status
make: *** [RASMain] Error 1

How to fix this problem?

Paul Pluzhnikov

unread,
Sep 28, 2007, 9:41:40 PM9/28/07
to
wong_...@yahoo.ca writes:

> I got an link error for undefined reference to `__ctype_b' and
> `__ctype_tolower'.

Google is your friend:
http://groups.google.com/group/comp.os.linux.development.apps/browse_frm/thread/f6e454154e77340b
http://groups.google.com/group/comp.os.linux.development.apps/browse_frm/thread/93b84ddae89f089b

And please do not multi-post. This has absolutely nothing to do with gcc.

Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.

Dick Wesseling

unread,
Sep 29, 2007, 11:15:53 PM9/29/07
to
In article <1191000544.7...@g4g2000hsf.googlegroups.com>,

wong_...@yahoo.ca writes:
> I got an link error for undefined reference to `__ctype_b' and
> `__ctype_tolower'.
>
...

> /usr/lib/libUtility.so: undefined reference to `__ctype_tolower'
> /usr/lib/libUtility.so: undefined reference to `__ctype_b'
> collect2: ld returned 1 exit status
> make: *** [RASMain] Error 1
>
> How to fix this problem?
>
Re-link libUtility.so and use an explicit "-llibc.so"

The symbol table for libc.so contains versioned symbols for __ctype_xxxx.
If the linker encounters such a symbol it will replace the external
reference to - for example - __ctype_b with a reference to
__ctype_b@@GLIBC_2.0. The latter is supported by all versions of
libc.so.

wong_...@yahoo.ca

unread,
Oct 1, 2007, 12:14:19 PM10/1/07
to
On Sep 29, 11:15 pm, f...@securityaudit.val.newsbank.net (Dick
Wesseling) wrote:
> In article <1191000544.790678.290...@g4g2000hsf.googlegroups.com>,
> wong_po...@yahoo.ca writes:> I got an link error for undefined reference to `__ctype_b' and

libUtility.so is created by
ar -r libUtility.so MemoryBlock.o ... MemoryQueueClass.o HexDump.o

Therefore I tried:
ar -r libUtility.so MemoryBlock.o ... MemoryQueueClass.o HexDump.o
/usr/lib/libc.so

(This will create an error:
ar -r libUtility.so MemoryBlock.o ... MemoryQueueClass.o HexDump.o-
llibc.so
ar: -llibc.so: No such file or directory)

There is still compile error:


g++ -O -O0 -DOS_LINUX -DOS_UNIX -DLITTLE_ENDIAN -DUSE_PTHREADS -O -o
RASMain RASMain.o RASServer.o /usr/lib/libpopt.so ./.libs/libHw.al -L/

usr/lib -lUtility -ldl /usr/lib/libc.so

Paul Pluzhnikov

unread,
Oct 1, 2007, 6:22:13 PM10/1/07
to
wong_...@yahoo.ca writes:

[Irrelevant c.o.l.setup trimmed.]

> On Sep 29, 11:15 pm, f...@securityaudit.val.newsbank.net (Dick
> Wesseling) wrote:
>> Re-link libUtility.so and use an explicit "-llibc.so"

That is a bogus advice -- there is no Linux system on which one
can reasonably expect to find liblibc.so

> libUtility.so is created by
> ar -r libUtility.so MemoryBlock.o ... MemoryQueueClass.o HexDump.o

That is wrong as well -- you are creating an *archive* library,
and calling it .so By convention, archive libraries are called .a,
and shared libraries are called .so, so you've just managed to
confuse everyone for no good reason.

Further, if /usr/lib/libUtility.so was *really* produced as above,
your error message would have been different. For example:

$ echo "int foo() { return bar(); }" | gcc -c -o foo.o -xc -
$ ar -r libFoo.so foo.o
ar: creating libFoo.so
$ echo "int main() { return foo(); }" | gcc -xc - -L. -lFoo
./libFoo.so(foo.o)(.text+0x7): In function `foo':
: undefined reference to `bar'


collect2: ld returned 1 exit status

Note how the error message references *specific* object inside
libFoo.so which is causing the problem.

Since your error message doesn't do that, one can safely assume
that /usr/lib/libUtility.so was in fact *not* built with 'ar',
and that you are mistaken about the way it was built.

> Therefore I tried:

You've tried "snake oil". Now try a real solution.

To repeat, /usr/lib/libUtility.so was *not* build on the current
system, nor with the command you claim.

If you can rebuild it, do so and your problem will go away.

If you can't (e.g. because it's a 3rd party library), then you have
to hack on your own libc, as described in the link I already
gave you.

wong_...@yahoo.ca

unread,
Oct 2, 2007, 11:15:58 AM10/2/07
to
On Oct 1, 6:22 pm, Paul Pluzhnikov <ppluzhnikov-...@charter.net>
wrote:

You are right - there is no Linux system on which one can reasonably
expect to find liblibc.so. I've tried "snake oil":(.

I copied the make output incorrectly for my previous post.
libUtility.so is really created by
$ g++ -shared -fPIC -Wl,-Bsymbolic -Wl,-whole-archive -lpthread -ldl -
o


libUtility.so MemoryBlock.o ... MemoryQueueClass.o HexDump.o

This is confirmed by:
$ file libUtility.so
libUtility.so: ELF 32-bit LSB shared object, Intel 80386, version 1
(SYSV), not stripped

I can rebuild libUtility.so, but why my link problem do not go away?
Is something wrong with my link or compile options or some other
reasons?

Eventually I found a ctype.c on the internet which will link with
libUtility.so to eliminate the previous link errors.

Paul Pluzhnikov

unread,
Oct 2, 2007, 10:09:20 PM10/2/07
to
wong_...@yahoo.ca writes:

> I copied the make output incorrectly for my previous post.
> libUtility.so is really created by
> $ g++ -shared -fPIC -Wl,-Bsymbolic -Wl,-whole-archive -lpthread \

> -ldl -o libUtility.so MemoryBlock.o ... MemoryQueueClass.o HexDump.o

The link line above is *very* broken. Correct link line is:

g++ -shared -fPIC -Wl,-Bsymbolic -pthread -o libUtility.so \
MemoryBlock.o ... MemoryQueueClass.o HexDump.o -ldl

But that's not where your problem comes from ...

> I can rebuild libUtility.so, but why my link problem do not go away?

Because your newly built libUtility.so will no longer reference
obsolete glibc symbols [1].

> Is something wrong with my link or compile options or some other
> reasons?

Yes, your link line is incorrect.
You didn't tell what your compile line is, so I can't tell.

But the reason your old libUtility.so references obsolete symbols
is that it was built on an old system.

> Eventually I found a ctype.c on the internet which will link with
> libUtility.so to eliminate the previous link errors.

That's generally wrong solution, and may cause you subsequent
runtime problems, but whatever. If you insist on ugly hacks
instead of rebuilding libUtility.so, so be it.

Cheers,

[1] Note: you must recompile objects in it, not merely relink it.

Dick Wesseling

unread,
Oct 3, 2007, 4:24:24 PM10/3/07
to
In article <1191338158.0...@y42g2000hsy.googlegroups.com>,

wong_...@yahoo.ca writes:
> On Oct 1, 6:22 pm, Paul Pluzhnikov <ppluzhnikov-...@charter.net>
> wrote:
>> wong_po...@yahoo.ca writes:
>>
>> [Irrelevant c.o.l.setup trimmed.]
>>
>> > On Sep 29, 11:15 pm, f...@securityaudit.val.newsbank.net (Dick
>> > Wesseling) wrote:
>> >> Re-link libUtility.so and use an explicit "-llibc.so"
>>
>> That is a bogus advice -- there is no Linux system on which one
>> can reasonably expect to find liblibc.so
>>


Well, not bogus advice, but sloppy advice. Of course I intended to
write "-lc" instead. But it was kind of late when I wrote that.

The output below demonstrates how the linker treats the
__ctype_* externals when:

1) invoked without -lc
2) invoked with -lc
3) invoked via gcc (which provides -lc for you)


+ cat test.c
#include <ctype.h>

int islo(int c) {
return islower(c);
}
+ gcc -O0 -c -fPIC test.c
+ nm -u test.o | grep ctype
U __ctype_b_loc
+ ld -shared -o test.so test.o
+ nm -u test.so | grep ctype
U __ctype_b_loc
+ ld -shared -o test.so test.o -lc
+ nm -u test.so | grep ctype
U __ctype_b_loc@@GLIBC_2.3
+ gcc -v -shared -o test.so test.o
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.3/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/u
sr/share/info --enable-shared --enable-threads=posix --disable-checking --with-s
ystem-zlib --enable-__cxa_atexit --host=i386-redhat-linux
Thread model: posix
gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-59)
/usr/lib/gcc-lib/i386-redhat-linux/3.2.3/collect2 --eh-frame-hdr -m elf_i386 -s
hared -o test.so /usr/lib/gcc-lib/i386-redhat-linux/3.2.3/../../../crti.o /usr/l
ib/gcc-lib/i386-redhat-linux/3.2.3/crtbeginS.o -L/usr/lib/gcc-lib/i386-redhat-li
nux/3.2.3 -L/usr/lib/gcc-lib/i386-redhat-linux/3.2.3/../../.. test.o -lgcc -lc -
lgcc /usr/lib/gcc-lib/i386-redhat-linux/3.2.3/crtendS.o /usr/lib/gcc-lib/i386-re
dhat-linux/3.2.3/../../../crtn.o
+ nm -u test.so | grep ctype
U __ctype_b_loc@@GLIBC_2.3

Paul Pluzhnikov

unread,
Oct 3, 2007, 7:20:55 PM10/3/07
to
fr...@securityaudit.val.newsbank.net (Dick Wesseling) writes:

> Well, not bogus advice, but sloppy advice.

Actually, it was bogus advice.

> The output below demonstrates how the linker treats the
> __ctype_* externals when:

Under no conditions would adding '-lc' to the link line change
"__ctype_b" (which OP had unresolved) into "__ctype_b_loc", which
glibc-2.3 and above provides.

wong_...@yahoo.ca

unread,
Oct 4, 2007, 4:23:24 PM10/4/07
to
On Oct 3, 7:20 pm, Paul Pluzhnikov <ppluzhnikov-...@charter.net>
wrote:

> Under no conditions would adding '-lc' to the link line change
> "__ctype_b" (which OP had unresolved) into "__ctype_b_loc", which
> glibc-2.3 and above provides.
>
You are right - I tried adding '-lc' to the link line and the link
problem still exist:

g++ -O -O0 -DOS_LINUX -DOS_UNIX -DLITTLE_ENDIAN -DUSE_PTHREADS -O -o
RASMain RASMain.o RASServer.o /usr/lib/libpopt.so ./.libs/libHw.al -L/
usr/lib -lUtility -ldl -lc

/usr/lib/libUtility.so: undefined reference to `__ctype_tolower'
/usr/lib/libUtility.so: undefined reference to `__ctype_b'
collect2: ld returned 1 exit status

wong_...@yahoo.ca

unread,
Oct 4, 2007, 4:26:09 PM10/4/07
to
On Oct 2, 10:09 pm, Paul Pluzhnikov <ppluzhnikov-...@charter.net>
wrote:
>

> Yes, your link line is incorrect.
> You didn't tell what your compile line is, so I can't tell.
>
> But the reason your old libUtility.so references obsolete symbols
> is that it was built on an old system.
>
> > Eventually I found a ctype.c on the internet which will link with
> > libUtility.so to eliminate the previous link errors.
>
> That's generally wrong solution, and may cause you subsequent
> runtime problems, but whatever. If you insist on ugly hacks
> instead of rebuilding libUtility.so, so be it.
>
> Cheers,
>
> [1] Note: you must recompile objects in it, not merely relink it.
> --

I recompile libUtility.so with your suggested options, copied it to /
usr/lib and link again, but why my link problem do not go away?

$ make libUtility
g++ -c -x c++ -fPIC -D__EXTENSIONS__ -fPIC -I ../util_vob/Include -I -
DOS_LINUX -DOS_UNIX -D_REENTRANT -DUSE_PTHREADS -DLITTLE_ENDIAN -
DGCCBOOL MemoryBlock.cpp -o MemoryBlock.o
g++ -c -x c++ -fPIC -D__EXTENSIONS__ -fPIC -I ../util_vob/Include -I -
DOS_LINUX -DOS_UNIX -D_REENTRANT -DUSE_PTHREADS -DLITTLE_ENDIAN -
DGCCBOOL MemoryQueueClass.cpp -o MemoryQueueClass.o
...
g++ -shared -fPIC -Wl,-Bsymbolic -pthread -ldl -o libUtility.so \
MemoryBlock.o ... MemoryQueueClass.o HexDump.o

# cp -f libUtility.so /usr/lib

$ make RASMain
/bin/sh ../../../libtool --mode=link g++ -O -O0 -DOS_LINUX -DOS_UNIX -


DLITTLE_ENDIAN -DUSE_PTHREADS -O -o RASMain RASMain.o RASServer.o

libHw.la -L/usr/lib -lUtility /usr/lib/libpopt.so -ldl

g++ -O -O0 -DOS_LINUX -DOS_UNIX -DLITTLE_ENDIAN -DUSE_PTHREADS -O -o
RASMain RASMain.o RASServer.o /usr/lib/libpopt.so ./.libs/libHw.al -L/
usr/lib -lUtility -ldl

/usr/lib/libUtility.so: undefined reference to `__ctype_tolower'
/usr/lib/libUtility.so: undefined reference to `__ctype_b'

collect2: ld returned 1 exit status

Paul Pluzhnikov

unread,
Oct 4, 2007, 8:05:13 PM10/4/07
to
wong_...@yahoo.ca writes:

> I recompile libUtility.so with your suggested options, copied it to /
> usr/lib and link again, but why my link problem do not go away?

Ok, this is getting interesting ...

> $ make libUtility
> g++ -c -x c++ -fPIC -D__EXTENSIONS__ -fPIC -I ../util_vob/Include -I -
> DOS_LINUX -DOS_UNIX -D_REENTRANT -DUSE_PTHREADS -DLITTLE_ENDIAN -
> DGCCBOOL MemoryBlock.cpp -o MemoryBlock.o

> ...
> g++ -shared -fPIC -Wl,-Bsymbolic -pthread -ldl -o libUtility.so \
> MemoryBlock.o ... MemoryQueueClass.o HexDump.o

One possibility is that you are using obsolete glibc headers.
Another is that you are not in fact recompiling all objects that
are linked into libUtility.so.

Here are the steps to find the "culprit":

nm -A MemoryBlock.o ... MemoryQueueClass.o HexDump.o | grep '__ctype_b$'

This should produce no output. If it produces any, the object that
contains symbol reference is the "culprit". If you know that it
was in fact recompiled, preprocess it with 'g++ -E ...' and see
which header __ctype_b comes from.

If there is no output from 'nm ... | grep ...' above, then check
where this reference is being inserted into libUtility.so:

g++ -shared -fPIC -Wl,-Bsymbolic -pthread -Wl,-y,__ctype_b \
-o libUtility.so MemoryBlock.o ... MemoryQueueClass.o HexDump.o -ldl

[Note that you still have '-ldl' in the wrong place on your command line.]

Finally, it appears that __ctype_b* isn't used with C++ at all, only
with C. I bet you link some old C-only objects into libUtility.so,
which you didn't tell us about and have neglected to recompile.

Cheers,

wong_...@yahoo.ca

unread,
Oct 22, 2007, 9:33:22 AM10/22/07
to
On Oct 4, 8:05 pm, Paul Pluzhnikov <ppluzhnikov-...@charter.net>
wrote:

I traced the problem to the linking of libcrypto.a which is from
openssl.
The make file use gcc to compile and several openssl files use the
<ctype.h> header.
How to fix it?
By modifying the make file?

$ grep -r ctype_b crypto/*
Binary file crypto/bio/b_print.o matches
Binary file crypto/bn/bn_print.o matches
Binary file crypto/conf/conf_mod.o matches
Binary file crypto/engine/hw_lunaca3.o matches
Binary file crypto/objects/obj_dat.o matches
Binary file crypto/ocsp/ocsp_ht.o matches
Binary file crypto/pkcs7/pk7_mime.o matches
Binary file crypto/x509/x509_cmp.o matches
Binary file crypto/x509v3/v3_conf.o matches
Binary file crypto/x509v3/v3_utl.o matches

$ grep ctype crypto/bio/b_print.c
#include <ctype.h>

# make -f openssl.mf linux

...
../../util/domd ../.. -MD gcc -- -fPIC -DOPENSSL_THREADS -D_REENTRANT -
DDSO_DLFCN -DHAVE_DLFCN_H -DOPENSSL_NO_KRB5 -O -DOPENSSL_NO_MDC2 -
DOPENSSL_NO_RC5 -DOPENSSL_NO_IDEA -DL_ENDIAN -DTERMIO -O3 -fomit-frame-
pointer -m486 -Wall -DSHA1_ASM -DMD5_ASM -DRMD160_ASM -I.. -I../.. -
I../../include -DOPENSSL_NO_MDC2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_IDEA
-- bio_lib.c bio_cb.c bio_err.c bss_mem.c bss_null.c bss_fd.c
bss_file.c bss_sock.c bss_conn.c bf_null.c bf_buff.c b_print.c
b_dump.c b_sock.c bss_acpt.c bf_nbio.c bss_log.c bss_bio.c
...

gcc -I.. -I../.. -I../../include -fPIC -DOPENSSL_THREADS -D_REENTRANT -
DDSO_DLFCN -DHAVE_DLFCN_H -DOPENSSL_NO_KRB5 -O -DOPENSSL_NO_MDC2 -
DOPENSSL_NO_RC5 -DOPENSSL_NO_IDEA -DL_ENDIAN -DTERMIO -O3 -fomit-frame-
pointer -m486 -Wall -DSHA1_ASM -DMD5_ASM -DRMD160_ASM -c -o
b_print.o b_print.c
b_print.c:580: warning: conflicting types for built-in function
'pow10'
...

ar r ../../libcrypto.a bio_lib.o bio_cb.o bio_err.o bss_mem.o
bss_null.o bss_fd.o bss_file.o bss_sock.o bss_conn.o bf_null.o
bf_buff.o b_print.o b_dump.o b_sock.o bss_acpt.o bf_nbio.o bss_log.o
bss_bio.o
...

Paul Pluzhnikov

unread,
Oct 22, 2007, 9:46:20 PM10/22/07
to
wong_...@yahoo.ca writes:

> I traced the problem to the linking of libcrypto.a which is from
> openssl.

Why didn't you mention that you are linking "old" libcrypto.a?
What prevents you from recompiling *it* as well?

> How to fix it?

Your problem will persist so long as you link in objects that were
compiled on an old glibc. Rebuild *all* objects that you link into
your library, and the problem will go away.

> By modifying the make file?

No, by recompiling *everything* that you link in.

wong_...@yahoo.ca

unread,
Oct 23, 2007, 9:34:31 AM10/23/07
to
On Oct 22, 9:46 pm, Paul Pluzhnikov <ppluzhnikov-...@charter.net>
wrote:

I did recompile openssl completely. The previous posts included the
compile messages. However, after recompilation, some binary files
such as b_print.o still reference ctype_b, which I don't understand.
That is why I am wondering whether the make file use some _old_
compilation options which should be modified.

Paul Pluzhnikov

unread,
Oct 23, 2007, 12:24:55 PM10/23/07
to
wong_...@yahoo.ca writes:

> I did recompile openssl completely.

If you did. then openssl is *not* your problem.

Look, I told you *presisely* how to find offending objects:

On Oct 4, 8:05 pm, Paul Pluzhnikov <ppluzhnikov-...@charter.net> wrote:
PP> Here are the steps to find the "culprit":
PP>
PP> nm -A MemoryBlock.o ... MemoryQueueClass.o HexDump.o | grep '__ctype_b$'

Instead of follwing instructions, you are doing totally meaningless
thing:

$ grep -r ctype_b crypto/*
Binary file crypto/bio/b_print.o matches

...

It is meaningless because b_print.o probably contains references
to __ctype_b_loc, which aren't the problem.

Please follow instructions "to the letter".

0 new messages