This is one of many potential static linking problems in uClibc. Last time, I reported a bug on sigaction and submitted a patch, but similar multiple definition error could happen to any function that was defined as GLOBAL in both libc.a and libpthread.a while certain runtime supporting function from libc, like abort(), also call it.
For example, sigprocmask-test.c is a simple testing program and $ gcc sigprocmask-test.c -o sigprocmask-test -static -lpthread Since sigprocmask is GLOBAL in both libc.a and libpthread.a, sigprocmask called in main function will pull in pt-sigprocmask.os from libpthread.a, but later, another sigprocmask called in abort (part of libc) will pull in sigprocmask.os from libc.a and leads to multiple definition error. To fix it, sigprocmask has to be defined as weak symbol. The same solution could be applied to other functions in libc/sysdeps/linux/common that will be called in both main and runtime supporting function in libc. I will identify them and post patch later. Here is my patch to fix sigprocmask, and it was tested on gcc-4.5.2 based toolchain on MIPS. >From 2e435b037624eff8c0daaa146d6feca57ce1eecf Mon Sep 17 00:00:00 2001 From: Jian Peng <[email protected]> Date: Sat, 26 Mar 2011 23:44:52 -0700 Subject: [PATCH 1/1] common: fix sigprocmask static linking bug simple sigprocmask testing program will fail to be compiled due to multiple definition of sigprocmask in libpthread.a and libc.a mipsel-linux-gcc sigprocmask-test.c -o sigprocmask-test -static -lpthread sigprocmask.c:(.text+0x0): multiple definition of `sigprocmask' The solution is to define sigprocmask as weak symbol. Signed-off-by: Jian Peng <[email protected]> --- libc/sysdeps/linux/common/sigprocmask.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libc/sysdeps/linux/common/sigprocmask.c b/libc/sysdeps/linux/common/sigprocmask.c index 011d7b3..35fa6df 100644 --- a/libc/sysdeps/linux/common/sigprocmask.c +++ b/libc/sysdeps/linux/common/sigprocmask.c @@ -23,7 +23,7 @@ static __always_inline _syscall4(int, __rt_sigprocmask, int, how, const sigset_t *, set, sigset_t *, oldset, size_t, size) -int sigprocmask(int how, const sigset_t * set, sigset_t * oldset) +int __attribute__((weak)) sigprocmask(int how, const sigset_t * set, sigset_t * oldset) { #ifdef SIGCANCEL sigset_t local_newmask; @@ -58,7 +58,7 @@ static __always_inline _syscall3(int, __syscall_sigprocmask, int, how, const sigset_t *, set, sigset_t *, oldset) -int sigprocmask(int how, const sigset_t * set, sigset_t * oldset) +int __attribute__((weak)) sigprocmask(int how, const sigset_t * set, sigset_t * oldset) { #ifdef SIGCANCEL sigset_t local_newmask; -- 1.7.4.1 _______________________________________________ uClibc mailing list [email protected] http://lists.busybox.net/mailman/listinfo/uclibc
