Problem with shared libs vs. variadic functions

We’re converting some of our libraries to be shared (this is in 6.1.0 on
an x86) and we’ve run into a serious problem.

It seems like any shared library that uses va_list, etc. (or maybe it’s
vsprintf()) will not be created or linked correctly, such that if an
executable is linked with that shared library it will segmentation fault
before main() is even invoked.

Here is a very simple testcase. Anyone have any ideas?


$ cat logapi.c

#include <stdio.h>
#include <stdarg.h>

int logMsg(const char *fmt, …)
{
int ret;

va_list args;
va_start(args, fmt);

ret = vprintf(fmt, args);

va_end(args);

return ret;
}

$ cat logtest.c

#include <stdio.h>

int main(void)
{
printf(“Hello…\n”);
return 0;
}

$ cat Makefile

CC = gcc -g

all: logtest

liblogapi.so: logapi.o ; $(CC) -shared -o $@ $^

logtest: logtest.o liblogapi.so ; $(CC) -o $@ $^

$ make
gcc -g -c -o logtest.o logtest.c
gcc -g -c -o logapi.o logapi.c
gcc -g -shared -o liblogapi.so logapi.o
gcc -g -o logtest logtest.o liblogapi.so

$ LD_LIBRARY_PATH=. ./logtest
segmentation violation (core dumped)

$ LD_LIBRARY_PATH=. gdb ./logtest
GNU gdb 5.0
Copyright 2000 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB. Type “show warranty” for details.
This GDB was configured as “–host=x86-pc-nto-qnx --target=ntox86”…
(gdb) run
Starting program: /tmp/./logtest
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0xb032b2db in ?? ()
(gdb) bt
#0 0xb032b2db in ?? ()
#1 0xb032b42b in ?? ()
#2 0xb032a363 in ?? ()

\


Paul D. Smith <pausmith@nortelnetworks.com> HASMAT–HA Software Mthds & Tools
“Please remain calm…I may be mad, but I am a professional.” --Mad Scientist

These are my opinions—Nortel Networks takes no responsibility for them.

Paul D. Smith <pausmith@nortelnetworks.com> wrote:
: We’re converting some of our libraries to be shared (this is in 6.1.0 on
: an x86) and we’ve run into a serious problem.

: It seems like any shared library that uses va_list, etc. (or maybe it’s
: vsprintf()) will not be created or linked correctly, such that if an
: executable is linked with that shared library it will segmentation fault
: before main() is even invoked.

: Here is a very simple testcase. Anyone have any ideas?

Bonjour Paul

if you use the gcc frontend
CCFLAGS += -fPIC

With qcc
CCFLAGS += -shared

: -------------------------------------------------------------------------------
: $ cat logapi.c

: #include <stdio.h>
: #include <stdarg.h>

: int logMsg(const char *fmt, …)
: {
: int ret;

: va_list args;
: va_start(args, fmt);

: ret = vprintf(fmt, args);

: va_end(args);

: return ret;
: }

: $ cat logtest.c

: #include <stdio.h>

: int main(void)
: {
: printf(“Hello…\n”);
: return 0;
: }

: $ cat Makefile

: CC = gcc -g

: all: logtest

: liblogapi.so: logapi.o ; $(CC) -shared -o $@ $^

: logtest: logtest.o liblogapi.so ; $(CC) -o $@ $^

: $ make
: gcc -g -c -o logtest.o logtest.c
: gcc -g -c -o logapi.o logapi.c
: gcc -g -shared -o liblogapi.so logapi.o
: gcc -g -o logtest logtest.o liblogapi.so

: $ LD_LIBRARY_PATH=. ./logtest
: segmentation violation (core dumped)

: $ LD_LIBRARY_PATH=. gdb ./logtest
: GNU gdb 5.0
: Copyright 2000 Free Software Foundation, Inc.
: GDB is free software, covered by the GNU General Public License, and you are
: welcome to change it and/or distribute copies of it under certain conditions.
: Type “show copying” to see the conditions.
: There is absolutely no warranty for GDB. Type “show warranty” for details.
: This GDB was configured as “–host=x86-pc-nto-qnx --target=ntox86”…
: (gdb) run
: Starting program: /tmp/./logtest
: (gdb) c
: Continuing.

: Program received signal SIGSEGV, Segmentation fault.
: 0xb032b2db in ?? ()
: (gdb) bt
: #0 0xb032b2db in ?? ()
: #1 0xb032b42b in ?? ()
: #2 0xb032a363 in ?? ()


: –
: -------------------------------------------------------------------------------
: Paul D. Smith <pausmith@nortelnetworks.com> HASMAT–HA Software Mthds & Tools
: “Please remain calm…I may be mad, but I am a professional.” --Mad Scientist
: -------------------------------------------------------------------------------
: These are my opinions—Nortel Networks takes no responsibility for them.

%% Alain Magloire <alain@qnx.com> writes:

am> if you use the gcc frontend
am> CCFLAGS += -fPIC

I was definitely using this, I just forgot to put it in my example.
In fact I built a number of shared libraries with the same makefile
structure and this library was the only one that had problems.

Hmm…

Wait, now it works. What? Ah. OK, I see what must have happened. I
didn’t clean out the .o’s for this library before I changed the build
structure to use shared libraries. Because I didn’t change the .c file,
but only the build methods, the .o wasn’t rebuilt and so wasn’t
recompiled with -fPIC. By some fluke or other all the other objects did
get rebuilt. I’m too used to clearmake, which remembers the command
line and rebuilds if it has changed.

I just did a very clean rebuild and now everything works as
expected… thanks for the heads-up.

Paul D. Smith <pausmith@nortelnetworks.com> HASMAT–HA Software Mthds & Tools
“Please remain calm…I may be mad, but I am a professional.” --Mad Scientist

These are my opinions—Nortel Networks takes no responsibility for them.

The following (amended makefile) and identical code (with the obvious bugfix) works for me.


Rennie

FYI, I know that main() didn’t invoke anything in the shared library;
that was on purpose, not a bug. The error happened regardless of
whether the shared library function was actually invoked.

Anyway, as I mentioned in my previous post the bug was that the shared
library was being built from an old .o which was not compiled with
-fPIC.

Thanks anyway!

Paul D. Smith <pausmith@nortelnetworks.com> HASMAT–HA Software Mthds & Tools
“Please remain calm…I may be mad, but I am a professional.” --Mad Scientist

These are my opinions—Nortel Networks takes no responsibility for them.