mindoverflow
mindoverflow

Reputation: 424

Silent symbol collision?

Posted on the Raspberry Stackexchange before, closed as off-topic, so here I am.

The following program compiles cleanly with gcc main.c -lpigpio -lpthread -Wall -Wextra. I'm using gcc 8.3.0 (crosscompiler or normal compiler doesn't change anything).

// main.c
#include <stdio.h>
#include <pigpio.h>

void listen() {
        printf("hi from listen\n");
}

int main() {
        gpioInitialise();
        printf("hi from main\n");
        gpioTerminate();
        return 0;
}

No warnings, yet the program happily prints

hi from listen
hi from main

The cause seems to be that gpioInitialise() tries to call listen(2) from <sys/sockets.h> here, but instead calls the function from main.c. Of course, this doesn't work and results in an error message from the pigpio library:

xxxx-xx-xx xx:xx:xx pthSocketThread: setsockopt() fail, closing socket -1
xxxx-xx-xx xx:xx:xx pthSocketThread: accept failed (Bad file descriptor)

Question: How come that gcc links a function with a completly different signature without throwing any errors? I know about static, but I want to make sense of this to learn from it. Surely it can't be as simple as listen(2) not being declared as static?

Upvotes: 0

Views: 145

Answers (1)

yugr
yugr

Reputation: 21878

Linker allows you to interpose symbols like this for debugging, profiling, etc. purposes. Unfortunately at link stage the typing information is generally not available so linker can not perform any sanity checking to verify that expected and actual signatures match. One might argue that with -g this would be possible but noone cared enough to implement this (this might be a good home project though).

Static would help in your case because it would prevent listen from being exported and libc's listen from being overridden.

As a side note, on ELF systems (Linux) situation is ever worse because they allow runtime symbol interposition (i.e. libraries compete for who wins over symbol names at program startup). This is typically resolved with static or -fvisiblity=hidden (unfortunately many libraries do not use them).

Upvotes: 1

Related Questions