sigprocmask testing program failed with static linking

Jian Peng jipeng at broadcom.com
Sun Mar 27 07:27:06 UTC 2011


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 <jipeng2005 at gmail.com>
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 <jipeng2005 at gmail.com>
---
 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




More information about the uClibc mailing list