Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Note: shared libraries that use stb_image.h fail on Ubuntu 16.04 with "/usr/bin/ld: a.out: hidden symbol `__cpu_model' in /usr/lib/gcc/x86_64-linux-gnu/5/libgcc.a(cpuinfo.o) is referenced by DSO" #280

Closed
dankegel opened this issue Apr 8, 2016 · 4 comments

Comments

@dankegel
Copy link

dankegel commented Apr 8, 2016

This is a doc issue at most, but worth noting because it may confuse some users.

Apps that use stb_image.h inside a shared library fail with Ubuntu 16.04 beta 2 (with gcc-5.3).
Symptom is the main executable fails to link to that shared library, with error
/usr/bin/ld: a.out: hidden symbol `__cpu_model' in /usr/lib/gcc/x86_64-linux-gnu/5/libgcc.a(cpuinfo.o) is referenced by DSO

A workaround is to link the shared library with -lgcc_s -lgcc.

To reproduce:

::::::::::::::
bug.sh
::::::::::::::

!/bin/sh

echo Demonstrate gotcha in __builtin_cpu_supports on Ubuntu 16.04 and rawhide / f24
echo See https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/thread/ZM2L65WIZEEQHHLFERZYD5FAG7QY2OGB/
echo Maybe caused by https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61309

echo Linking with gcc works:
gcc -fPIC -shared buglib.c -lm -o buglib.so
gcc bugapp.c buglib.so

echo Linking with g++ fails:
g++ -fPIC -shared buglib.c -lm -o buglib.so
g++ bugapp.c buglib.so

echo Rescue by linking libgcc explicitly into shared library:
g++ -fPIC -shared buglib.c -lm -lgcc_s -lgcc -o buglib.so
g++ bugapp.c buglib.so

::::::::::::::
buglib.c
::::::::::::::

define STB_IMAGE_IMPLEMENTATION

include "stb_image.h"

::::::::::::::
bugapp.c
::::::::::::::

include <stdio.h>

include "stb_image.h"

int main(int argc, char **argv) {
int width, height, n;
stbi_load("foo.jpg", &width, &height, &n, 4);
}

@dankegel dankegel changed the title Building app that uses stb_image.h fails on Ubuntu 16.04 with "/usr/bin/ld: a.out: hidden symbol `__cpu_model' in /usr/lib/gcc/x86_64-linux-gnu/5/libgcc.a(cpuinfo.o) is referenced by DSO" Note: shared libraries that use stb_image.h fail on Ubuntu 16.04 with "/usr/bin/ld: a.out: hidden symbol `__cpu_model' in /usr/lib/gcc/x86_64-linux-gnu/5/libgcc.a(cpuinfo.o) is referenced by DSO" Apr 8, 2016
@dankegel
Copy link
Author

When I say "not a bug", I mean "not a bug in stb".
It's probably a g++ bug.
I filed a simplified test case at https://bugs.launchpad.net/ubuntu/+source/gcc-5/+bug/1568899 as a first step. There should (already?) be a bug at gcc.gnu.org, too.

@baldurk
Copy link
Contributor

baldurk commented Sep 20, 2016

FWIW since it doesn't seem like this will be fixed upstream by GCC any time soon, my solution to this was just to be slightly more conservative and avoid the use of __builtin_cpu_supports. x64 is guaranteed to have SSE2 and for my application people using x86 processors will be pretty rare or non-existant, so losing a little perf on SSE2-capable x86 processors is not a big problem.

I'm not suggesting this is a fix for upstream but I'm posting it here just in case it's useful for anyone else who wants a fix to commit that doesn't involve linking explicitly against libgcc:

diff --git a/renderdoc/3rdparty/stb/stb_image.h b/renderdoc/3rdparty/stb/stb_image.h
index 5ea802b..1292b24 100644
--- a/renderdoc/3rdparty/stb/stb_image.h
+++ b/renderdoc/3rdparty/stb/stb_image.h
@@ -712,12 +712,15 @@ static int stbi__sse2_available()

 static int stbi__sse2_available()
 {
-#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 // GCC 4.8 or later
-   // GCC 4.8+ has a nice way to do this
-   return __builtin_cpu_supports("sse2");
+#if defined(STBI__X64_TARGET)
+   // on x64, SSE2 can be assumed to be available.
+   return 1;
 #else
-   // portable way to do this, preferably without using GCC inline ASM?
-   // just bail for now.
+   // __builtin_cpu_supports is buggy on GCC 5 and above, causing problems if
+   // referenced in a shared object, giving missing __cpu_model hidden symbol errors.
+   // To get around that, just assume that SSE2 is not available on x86.
+   //
+   // See https://github.com/nothings/stb/issues/280 for more information.
    return 0;
 #endif
 }

@nothings
Copy link
Owner

Anybody know what the status of the gcc bug is?

redxdev pushed a commit to redxdev/imquery that referenced this issue Jan 25, 2017
redxdev pushed a commit to redxdev/imquery that referenced this issue Jan 26, 2017
* move imq from a static library to a shared library

* enable -fPIC on linux

* pic

* bug in GCC 5 workaround, see nothings/stb#280

* update travis to use antlr shared library
rygorous added a commit to rygorous/stb that referenced this issue Mar 5, 2017
We tried but it was nothing but trouble. New rule: with
GCC/Clang, if you're compiling with -msse2, you get always-on
SSE2 code, otherwise you don't get any. Trying to ship
anything with proper runtime dispatch requires both working
around certain bugs and some fiddling with build settings,
which runs contrary to the intent of a one-file library,
so bail on it entirely.

Fixes issue nothings#280.
Fixes issue nothings#410.
@rygorous
Copy link
Collaborator

Closing this, should be fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants