Old version of libc linking with my binary - gcc

I have inherited a piece of software which is having some issues. I believe the issues are related to the version of libc that is being statically linked.
I am building this on a Windows XP machine, targeting an x86 QNX Neutrino 6.3.2 machine.
Previously, the software built with GCC 2.95.3 (Well, technically, it's QNX's QCC that wraps and calls GCC)
Someone added a feature and had to port it to build with GCC 3.3.5 because the new feature needed it.
Now, the software is mine. I need to make some additions but have noticed weird behavior. After some digging, I found that there are static links to both libc for 2.95.3 and 3.3.5. According to QNX's web site, :
GCC 2.95.3 (from 6.2.1 or 6.3) and GCC 3.3.5 use different C++ ABIs
and have different name mangling. As a result, you can't link C++
binaries (objects, executables, libraries) built with GCC 2.95.3 with
binaries built with GCC 3.3.5.
This is a breaking ABI change, so I am obviously concerned. I wrote a small test for this
#include <stdio.h>
int main()
{
FILE *stream_ptr = popen("fakename","r"); /// use libc
return 0;
}
and built it with 3.3.5:
QCC -V3.3.5,gcc_ntox86 small.cpp -o small.out
then used strings to see what has been statically linked for this program
strings -a small.out | grep GCC
GCC: (GNU) 3.3.5 (qnx-nto)
GCC: (GNU) 3.3.5 (qnx-nto)
GCC: (GNU) 2.95.3
GCC: (GNU) 3.3.5 (qnx-nto)
As you can see, libc for GCC 2.95.3 has been statically linked.
My first question is: How can I make this link with a 3.3.5 version of libc?
My second question is: Why does it link with 2.95.3 in the first place?
What am I doing wrong/missing? Any suggestions are welcome.
(There's probably 60 other things in the project linking with 2.95.3 objects, and I need to fix them all, so implementing popen() and 59 of his closest friends myself isn't the best of ideas...)
Thanks,
Karl
UPDATE:
So I haven't figured out how to fix this yet, but a little bit of background for QNX 6.3.2 so folks who stumble upon this later don't have to figure this out the hard way:
You can use the verbose option for the linker ld --verbose and have it spit out everything it does. Note that I got the following output when I did that:
attempt to open C:/QNX632/host/win32/x86/usr/lib/gcc-lib/i386-pc-nto-qnx6.3.0/3.3.5//libc.a failed
attempt to open C:/QNX632/target/qnx6/x86/lib/gcc/3.3.5/libc.a failed
attempt to open C:/QNX632/target/qnx6/usr/i386-pc-nto-qnx6.3.0/lib//libc.a failed
attempt to open C:/QNX632/target/qnx6/usr/lib/libc.a failed
attempt to open C:/QNX632/target/qnx6/x86/lib//libc.a succeeded
As one can see, the linker is attempting to open the 3.3.5 version of libc.a, but it's simply not there. I took a look at 3 other coworkers computers, and the 3.3.5 version of libc.a is not there. How this is even working across a breaking ABI change, I'm not sure, but I am suspicious that some of the wonkiness in this project has to do with this discrepancy.
While this answers my original questions,
1) You can't make it link with nonexistant libc.a files,
2) It picks the 2.95.3 version because the 3.3.5 version isn't there,
it brings up new questions:
3) Why doesn't QNX ship a 3.3.5 version of libc.a with this version of Momentics? (or if they do, where do they hide it because I missed it.)
4) Are there any viable workarounds? I was able to build everything but the two most important servers in the project without using libc, but until I get the last two fixed up, I'm still searching for a solution.
Update to the Update:
Working with the QNX folks, they built me an unsupported, untested engineering version of libc.a, libm.a and libsocket.a with GCC 3.3.5, and everything has been good since.

When I compile for QNX 6.3.2, I always use 3.3.5 with the GNU C/C++ libraries. If you don't specify GNU, you will get Dinkum libraries by default. I have had problems in the past with Dinkum thread safety. Try these flags:
qcc -V3.3.5,gcc_ntox86 -Y_gpp
The -Y_gpp directs qcc to use the GNU libraries.

GCC 3.3 is prehistoric, isn't there a newer version for QNX?
There should be some option for the compiler or linker which will tell it to be verbose, which you could use to see all the library paths and libraries being linked to. That might show you how an older lib is being linked to.

In case someone else runs into a similar problem, to the best of my knowledge, here are the answers to the four questions I asked. They are not encouraging.
1) You can't make it link with nonexistent libc.a files. Of course.
2) It picks the 2.95.3 version of libc.a because the 3.3.5 version isn't there.
3) During discussions with the QNX folks, they stated that for QNX Neutrino 6.3.2, the official, tested compiler is only 2.95.3, even though GCC 3.3.5 is included in the shipped version of Momentics, it is not tested nor supported. It just happens to be there.
4) Options:
a) Go to a newer version of QNX which uses a newer version of GCC
b) Get source for libc (and libm as it turns out) and build it with GCC 3.3.5.
This one may pan out. Still waiting on QNX tech support.
c) Get already-built libraries from the QNX folks.
d) Don't use GCC 3.3.5 to build for Neutrino 6.3.2
Sincerely,
Karl

Related

Run a program built with gcc8 on a producing environment without gcc8

My developing/producing environments are all CentOS-7.7.
In order to compile my program with gcc-8.3.0, I have installed "devtoolset-8" on my developing env, but it can not be used in the way same as gcc-4.8.5 that was shipped with CentOS7 oringinally.
Every time I need to compile a program, I must use "scl enable devtoolset-8 -- bash" to switch to gcc8 instead of gcc4.8.5.
When the program was deploying onto the producing-env, there is no gcc8, nor libstdc++.so.6.0.25, so it can not run.
I guess libstdc++.so.6.0.25 should be released with gcc8? I can neither install "devtoolset-8" on the producing-env, nor build gcc8 from source on the producing env.
The version of libstdc++ that can be installed from the official yum repo of CentOS, is libstdc++.so.6.0.19, hence my programs can not be loaded at the producing-env.
How to let such programs to run?
Thanks!
Pls forgive my Ugly English.
In order to not have to copy or ship a separate libstdc++.so but rather link statically (as suggested in a comment) against the C++ runtime, one can link C++ programs with -static-libstdc++ (also specifying -static-libgcc will also make sure that the program does not depend on a recent enough version of libgcc_s.so on the system - although that should rarely be a problem).
There can also be the issue of the target system having a version of glibc that is too old (relative to the build system). In that case, one could anyhow compile gcc of no matter how recent of a version on the older system, so that the resulting C++ executables as well as libstdc++ are linked against the older glibc. Linking C++ programs with -static-libstdc++ will again help to not depend on the program having to be able to find libstdc++.so at run-time.
Finally, the C++ program could also be linked with -static not depending on any dynamic libraries at all.

LD needs DWARF version 3 or 2, but mine is version 4

After hours of research (and tries) on how to install id3lib on Qt (windows), but with no success, I decided to use TagLib's library.
I followed this tutorial to build a compatible version of taglib for Qt but still another problem (full log here):
...
C:\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\mingw32\bin\ld.exe: Dwarf
Error: found dwarf version '4', this reader only handles version 2 and 3
information.
C:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../mingw32/lib/crt2.o:crt1.c:(.text+0x1f1):
undefined reference to `__chkstk_ms'
...
In CMake, I did configure > MinGW Makefiles.
Can anyone tell how to fix it?
Environment:
Windows 7 (64-bit);
CMake 2.8.12.1;
TagLib 1.9.1;
GCC 3.4.5;
Qt 5.1.1.
The problem stems from the fact that you are using terribly outdated GCC, while your Qt binaries are most likely built with bleeding-edge GCC (or the one close to it). For instance, as the error message shows, DWARF is outdated in case of your current GCC and is incompatible with the one used by your current Qt. Furthermore, even if it wouldn't, you'd still hit other problems with binary incompatibilities, since you essentially mix compilers with different major version numbers, which is strongly discouraged. Notice, that your problem has nothing to do with CMake at all. You can see it yourself in the error message, i.e. the error is reported by ld, the linker utility from (your outdated) GCC toolchain. To conclude, your only option is to update GCC, ideally exactly to the one which was used to build your current Qt.

GCC GCJ needs ECJ and Other Libraries?

So I just downloaded mingw-w64-bin_i686-mingw_20110410.zip from here (GCC 4.7 apparently), and discovered it had a very recent version of the GCJ compiler.
I tried using it, but apparently gcj requires ecj1.exe, which is the Eclipse compiler for Java... so, where do I find a compatible version of the binaries of ECJ and the associated Java libraries that are needed (libgcj, etc.)?
Ideally this would be found on the MinGW-w64 project page, but it doesn't seem to exist.
(I've already tried copying them from a slightly older GCC version; it doesn't work.)
The cause for an openSUSE version of the gcc is basically this:
If the configure step of the compilation of gcc did not find the ecj.jar
file, ecj1 will be missing at the time when gcj, which has just been build,
is called.
ecj.jar can be taken from ftp://sourceware.org/pub/java/ecj-4.8.jar
for example.
The two options are:
i) Put ecj.jar in $HOME/share/java/ecj.jar, reconfigure gcc with
./configure .... --with-ecj-jar=$HOME/java/ecj.jar
and recompile gcc. Future compilations with that gcc will not require
ecj1 .
ii) Put ecj.jar in $HOME/share/java/ecj.jar and create ecj1(.exe)
through a compilation like
gcj -o$HOME/bin/ecj1(.exe) --main=org.eclipse.jdt.internal.compiler.batch.GCCMain $HOME/share/java/ecj.jar
assuming that the $HOME/bin is in the PATH for subsequent calls of gcj.
The thing that is actually "broken" here the fact that gcc 4.8.* is not shipped
by default with ecj.jar at some standard place.
That is a very old version of a MinGW-w64 toolchain.
I would suggest downloading one of my builds, I've had reports of gcj working (without libgcj, which does not work on Windows), although I can't seem to find a link to the discussion I had long ago with a user. The user's case had something to do with creating a JNI interface or something, which didn't require libgcj.
My old builds can be found here for 32-bit and here for 64-bit. I checked the 4.8 release build, and it contains the gcj compiler.
Would you be opposed to downloading the source and building it? I looked over the build doc in basic and advanced build docs. I didn't see anything about the GCJ compiler or ECJ, but you'll need gcc 4.5.1 in order to build it.

ARM toolchain for ubuntu Error while compiling

I am trying to make the ARM toolchain in ubuntu. The way it is specified in http://hri.sourceforge.net/tools/arm-elf-gcc.html
I am getting the following error:
Configuring for a x86_64-unknown-linux-gnu host.
Invalid configuration `x86_64-unknown-linux-gnu': machine `x86_64-unknown' not recognized
Invalid configuration `x86_64-unknown-linux-gnu': machine `x86_64-unknown' not recognized
Unrecognized host system name x86_64-unknown-linux-gnu.
does anybody have idea whats going wrong here.
A Google-search on the "machine `x86_64-unknown' not recognized" error message indicates that this can happen if the config.guess and config.sub files in the program you're building are too old to recognize the machine type for 64-bit linux. I expect that's your problem. You can fix that by replacing the ones in your GCC source tree with newer versions; your system should have some in the /usr/share/libtool directory that will work. Alternately, compile in a 32-bit Linux installation, or with "--build=i686-pc-linux-gnu --host=i686-pc-linux-gnu" configure options.
There are also copies here:
http://cvs.savannah.gnu.org/viewvc/*checkout*/config/config/config.guess
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
The real question, though, is: Why you are trying to build a version of the ARM toolchain that's that old? The directions on the site you link to will lead you to download the sources for the 2.95.3 version of GCC -- which was released nearly a decade ago. In GCC terms, that's positively ancient; the latest version is 4.5. It's older than a lot of ARM instruction-set changes, too.
Thus, the right solution to your problem, unless you have some specific need for a 2.95 compiler, is to get a version of GCC that's much more recent.
Also, you'll probably save some pain by not compiling it yourself, unless you particularly want to. There are numerous sources of precompiled cross-compilers; since I work at CodeSourcery, I'll recommend ours (which you can download and use for free):
http://www.codesourcery.com/sgpp/lite/arm/portal/subscription?#template=lite. If you want something equivalent to the compiler on the page you linked to, you probably want the "uClinux" version.

g++ 4.4.x bug?

I have build a g++ v4.4 from source by using the archives provided by gcc.gnu.org.
But the resulting g++ cannot compile some of our projects c++ files. I am receiving a message simply saying: assembler error. It turned out that the assembler chokes on some extremely long symbol names, e.g. symbols names with a length of more then 2k.
Am I missing something to get it to work?
I would very appreciate an advice on how to get this working!
Environment: Debian-Lenny 64bit
EDIT: The mentioned c++ files are compiling fine with g++ versions v4.2 and v4.3. So I don't think it is a bug in the assembler (from binutils v2.18). Just to be sure I have also tried with binutils v2.20 - but I got the identical error message.
EDIT: I need g++ v4.4.x for the purpose of comparing the output of different g++ versions (and there is no g++ v4.4 in the official lenny repositories)
If your analysis is correct, it seems the proper course of action would be to file a bug for binutils. Or gcc, if it turns out the long symbol names are due to a bug in gcc's name mangling.
Of course, a (preferably reduced) testcase will help the developers fix your problem. Heck, it could have helped SO readers to verify your problems.
You're going to have to compile the corresponding gas instead of depending on what lenny has in his refrigerator (/usr/bin).
Why don't a) upgrade or b) use the backports archive or c) rebuild from current Debian sources on your box? I happily run testing with g++ 4.2, 4.3 and 4.4.
Worst case, you could install a new Debian release in a virtual environment such as a chroot, a Xen or Kvm instance, or inside VirtualBox.

Resources