Wrong linkage of system functions

  • Thread starter Cristóvão Sousa
  • Start date
C

Cristóvão Sousa

Hi,
I'm having some trouble with a C project in a Linux system.
I already know which is the problem but I don't know how to fix it.

I have a program that links to a third party static library.
The problem is that the library declares a internal global variable
named 'accept' not visible by the user.
In my program I use the system Internet Sockets which API have a
function named 'accept'.
When I compile it does not complies but when I run the program it
segfaults because a call to Internet Sockets 'accept' function tries
to execute a function which address is the address of the 'accept'
global variable from the third party library.

I made a little source code that reproduce the problem with the
'printf' function. In this case the compiler gives me a warning, but
the beavior is equal.

Is this my problem? Is it a bug? I don't think a programer have to
know all possible system functions names...


I have three files:
mylib.c and mylib.h represents the third party library;
main.c is my program.
I also made a simple Makefile.

Here are the files:

---------------------------------------
$ cat mylib.h
int myfunc();

---------------------------------------
$ cat mylib.c
#include "mylib.h"

int printf[2];

int myfunc(){ // Just for example
printf[0] = 0;
return printf[1];
}

---------------------------------------
$ cat main.c
#include <stdio.h>
#include "mylib.h"

int main(){
printf("Helo World!");
return 0;
}

---------------------------------------
$ cat Makefile
exec: main mylib
gcc main.o mylib.o -o exec

main: main.c
gcc main.c -c -o main.o

mylib: mylib.c
gcc mylib.c -c -o mylib.o

---------------------------------------------------


And here are the results:


$ make
gcc main.c -c -o main.o
gcc mylib.c -c -o mylib.o
mylib.c:3: warning: built-in function 'printf' declared as non-
function
gcc main.o mylib.o -o exec

$ ./exec
Segmentation fault (core dumped)

$ gdb ./exec core
Core was generated by `./exec'.
Program terminated with signal 11, Segmentation fault.
#0 0x0000000000600884 in printf ()



Thanks in advance,

Cristóvão Sousa
ISR - FCT - University of Coimbra
 
B

Ben Bacarisse

Cristóvão Sousa said:
Hi,
I'm having some trouble with a C project in a Linux system.
I already know which is the problem but I don't know how to fix it.

I have a program that links to a third party static library.
The problem is that the library declares a internal global variable
named 'accept' not visible by the user.

This is non-standard terminology and might be confusing. In you
example below, the name class is with a file-scope object with
external linkage. The "not visible by the user" is still confusing
me, but if the problem is an object called "accept" with external
linkage in the library, then I think you will need to use system
specific trickery to solve the problem.

A post to comp.unix.programmer or a gcc group might bear fruit. It is
possible that some linker magic can help here, but that is a matter
for another group.
In my program I use the system Internet Sockets which API have a
function named 'accept'.
When I compile it does not complies but when I run the program it
segfaults because a call to Internet Sockets 'accept' function tries
to execute a function which address is the address of the 'accept'
global variable from the third party library.

I made a little source code that reproduce the problem with the
'printf' function. In this case the compiler gives me a warning, but
the beavior is equal.

This example is a little different since, printf is a reserved
identifier (when used like this) so your example in not "proper" C.
The compiler is allowed to do pretty much what it likes with it.

The identifier in question ("accept") is not reserved in this way, so
the library is allowed to define it. Of course, it is very bad
practice to do so. A library should define as few externally visible
identifiers as possible, and they should, usually, have some form of
prefixed name to reduce the chance of clashes like this.

If you have access to the source, fix the library. If the identifier
is not needed outside the library, you may be able to declare it
static so that it will not have external linkage,

<snip example code that defines an external array called "printf">
 
C

Cristóvão Sousa

This is non-standard terminology and might be confusing. In you
example below, the name class is with a file-scope object with
external linkage. The "not visible by the user" is still confusing
me, but if the problem is an object called "accept" with external
linkage in the library, then I think you will need to use system
specific trickery to solve the problem.

Well, I really don't know very well the standard terminology, but, yes
the 'accept' variable is global and non static. I call it a library
because the object file is inserted in a archive .a file.
I said "not visible by the user" in the way a person using the library
doesn't know that the variable exists unless she search the source
code, like I did when debugging.
A post to comp.unix.programmer or a gcc group might bear fruit. It is
possible that some linker magic can help here, but that is a matter
for another group.

Ok I'll try there too.
This example is a little different since, printf is a reserved
identifier (when used like this) so your example in not "proper" C.
The compiler is allowed to do pretty much what it likes with it.

The identifier in question ("accept") is not reserved in this way, so
the library is allowed to define it. Of course, it is very bad
practice to do so. A library should define as few externally visible
identifiers as possible, and they should, usually, have some form of
prefixed name to reduce the chance of clashes like this.

Ah, ok, that explains why the compiler does warn about 'printf' but
not about 'accept', anyway the result is the same.
If you have access to the source, fix the library. If the identifier
is not needed outside the library, you may be able to declare it
static so that it will not have external linkage,

Yes I have, and the static resolved it! But because I am not the
developer of the library I'll prefer to ask the real developer to
change it.

Anyway as 'accept' is not a reserved identifier and even defining it
externally visible is not a good practice I'll try to figure out which
is the cause of the problem.


Thanks,
Cristóvão
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top