Segfault when calling weak symbol in static library

66 views Asked by At

For some reason I get a segfault when calling a weak function but only if I put the weak definition in a static library. Here are my source files:

// mylib.h
#pragma once

void hello(const char* name) __attribute__((weak));
// mylib.cpp

#include "mylib.h"

#include <iostream>

void hello(const char* name) {
    std::cout << "Hello " << name << "\n";
}
// main.cpp

#include "mylib.h"

int main() {
    hello("world!");
}

Then I compile them:

$ g++ -o mylib.o -c mylib.cpp
$ g++ -o main.o -c main.cpp

Then if I link normally it works fine:

$ g++ -o main_works main.o mylib.o
$ ./main_works
Hello world!

However if I first put them in a static library, it segfaults!

$ ar rc mylib.a mylib.o
$ g++ -o main_fails main.o mylib.a
$ ./main_fails
Segmentation fault (core dumped)

What's going on here? The symbol table for mylib.o and mylib.a is identical (as you would expect) and has the weak symbol:

$ nm mylib.a

mylib.o:
...
0000000000000000 W _Z5helloPKc
...

However it is only resolved in main_works:

$ nm main_works | grep hello
000000000040076b W _Z5helloPKc

$ nm main_fails | grep hello
                 w _Z5helloPKc

I'm using GCC 8.5.0 on RHEL 8. I also tested GCC 13.2.1 and Clang 13.0.6 on Fedora 38 (though I guess it is really the linker that is screwing up here).

Edit: This fixes the segfault, but it doesn't explain why it segfaults in the first place. It also isn't a good solution because adding flags like this is difficult in most build systems.

g++ -o main_fails -Wl,--whole-archive main.o mylib.a -Wl,--no-whole-archive
0

There are 0 answers