Fragen? Antworten! Siehe auch: Alternativlos
dietlibc hat eine libc.a und eine libpthread.a. Wenn man mit -pthread baut, wird auch libpthread.a reingelinkt.
Mehrere Symbole gibt es sowohl in libc als auch in libpthread, z.B. wenn man fputc aufruft, um ein Zeichen in ein FILE* zu schreiben. Die libc-Variante schreibt halt ein Zeichen, und die libpthread-Variante holt sich einen Mutex, schreibt dann das Zeichen, und lässt den Mutex dann wieder gehen.
Für die Korrektheit des Programms ist es also wichtig, dass die libpthread-Variante gewinnt.
Das ist relativ einfach:
$ gcc -o main main.c -lpthread -lcOK, nächstes Problem: fopen. fopen ruft eine Init-Funktion auf, die ein FILE* alloziert und initialisiert. Die Variante der Init-Funktion in libpthread alloziert mehr Platz für den Mutex und initialisiert den. So und jetzt kommt das Problem: Hier gewinnt bei obigem gcc-Aufruf nicht etwa die Variante aus libpthread sondern die aus libc.
Ich habe mal ein Ticket aufgemacht bei GNU binutils (wo GNU ld herkommt), und die um Rat gebeten. Die meinten, ich soll -lc -lpthread machen.
Ich habe also einen kleinen Demonstrator gebaut, bei dem das auch nicht hilft. Schlimmer noch: Es gibt ja noch andere Linker als GNU ld. Es gibt noch GNU gold (auch aus binutils), lld (von LLVM) und mold (separates Projekt von dem Autor von lld). ld und gold sind sich einig, und lld und mold sind sich in die Gegenrichtung einig.
Das ist jetzt ein ziemlich riesiges Problem für mich, denn wenn ich nicht dafür sorgen kann, dass die Init-Funktion aus libpthread immer gewinnt, dann kriege ich Speicherkorruption, weil die aus libc zu wenig alloziert, aber dann jemand auf dem nicht mitallozierten Mutex herumpolkt. Und das Programm ist natürlich auch kaputt dann.
Falls ihr mal gucken wollt: Hier ist das binutils-Ticket. Ich bin mal sehr gespannt, was die Nerds da jetzt vorschlagen.