Linux: Check the glibc version

If you need to check which version of the GNU C library (glibc) is used on you Linux system, whether it’s to check whether you are affected by the GHOST vulnerability or you need to install a software requiring at least a certain version but not checking it on build/installation, the easiest way is to use ldd which comes with glibc and should in most cases have the same version:

> ldd --version
ldd (GNU libc) 2.11.1

If you know you might have patched the system to use a different version of ldd and know that its version doesn’t match the glibc version, you have two additional ways to find out the glibc version:

  1. Check the version of the installed glibc rpm package
  2. Check the version of the used libc.so file

First using rpm:

> rpm -q glibc
glibc-2.11.1-0.17.4

The second way is a little bit more difficult. You first have to find which libc.so file is being used by a known program e.g. netstat:

> ldd `which netstat`
        linux-vdso.so.1 =>  (0x00007ffff7ffb000)
        libc.so.6 => /lib64/libc.so.6 (0x00007ffff7a80000)
        /lib64/ld-linux-x86-64.so.2 (0x00007ffff7dde000)

You can also find the libc.so file used with the following command:

> cat `gcc -print-file-name=libc.so`
/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a  AS_NEEDED ( /lib64/ld-linux-x86-64.so.2 ) )

So we now know that /lib64/libc.so.6 is being used and we just need to get it’s version:

> /lib64/libc.so.6 --version
GNU C Library stable release version 2.11.1 (20100118), by Roland McGrath et al.
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Configured for x86_64-suse-linux.
Compiled by GNU CC version 4.3.4 [gcc-4_3-branch revision 152973].
Compiled on a Linux 2.6.32 system on 2010-05-06.
Available extensions:
        crypt add-on version 2.1 by Michael Glad and others
        GNU Libidn by Simon Josefsson
        Native POSIX Threads Library by Ulrich Drepper et al
        BIND-8.2.3-T5B
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.

If you want to determine the glibc version from C program and not from a shell script, you can just use something like this:

#include <stdio.h>
#include <stdlib.h>
#include <gnu/libc-version.h>

int main(int argc, char *argv[]) {
  printf("glibc version: %s\n", gnu_get_libc_version());
}

You can then compile it and execute it like this to get the glibc version:

> gcc glibc_version.c -o glibc_version
> ./glibc_version
glibc version: 2.11.1

Of course, if your C file is not called glibc_version.c, you’ll have to use the name you’ve actually used in the gcc arguments.

Since your current shell is probably also using glibc, you can also find out which libc library it has loaded by using the following command:

> lsof -p $$ | grep libc
bash    9177 root  mem    REG    8,2  1661454 827401 /lib64/libc-2.11.1.so

Of course there may be systems where the file name itself doesn’t give you the glibc version but just as shown above with /lib64/libc.so.6 you can call the so file with the –version to get its version information e.g.:

lsof -p $$ | grep libc | awk ' { print $NF" --version"; } ' | sh
GNU C Library stable release version 2.11.1 (20100118), by Roland McGrath et al.
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Configured for x86_64-suse-linux.
Compiled by GNU CC version 4.3.4 [gcc-4_3-branch revision 152973].
Compiled on a Linux 2.6.32 system on 2010-05-06.
Available extensions:
        crypt add-on version 2.1 by Michael Glad and others
        GNU Libidn by Simon Josefsson
        Native POSIX Threads Library by Ulrich Drepper et al
        BIND-8.2.3-T5B
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.

 

Visual Studio 2012: mspdb110.dll is missing when executing editbin.exe

I was having some issues using an OCX in an old application I had recompiled using Visual Studio 2012. One thing I found is that it might be related to a compatibility issue with Data Execution Prevention (DEP). Since I couldn’t recompile the OCX and didn’t have direct access to the linker settings, I went for using editbin.exe to apply a /NXCOMPAT:NO. But when I ran the following:

C:\Users\benohead>"c:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\editbin.exe" /NXCOMPAT:NO myfile.exe

I got a system error from link.exe saying:

The program can’t start because mspdb110.dll is missing from your computer. Try reinstalling the program to fix this problem.

The cause for this error is that I executed the command in the wrong DOS prompt. Not the one where I had executed vcvars32.bat. So I just executed vcvars32.bat:

"c:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\vcvars32.bat"

And gave it another try. Now no error message was displayed.

Visual C++: module unsafe for SAFESEH image, unable to generate SAFESEH image

Using Visual Studio 2012, I was building from the command line a software which was built until now using an older version (guess it was Visual Studio 2005). There were of course many things I had to change in the code itself (so much for portability…). And of course I had to upgrade the project in the solutions to VS2012 (using the devenv /upgrade command).

After converting the projects and modifying the code, I got the following error messages on a few projects:

error LNK2026: module unsafe for SAFESEH image.

fatal error LNK1281: Unable to generate SAFESEH image.

This means that the linker was started with the option meaning /SAFESEH “image has safe exception handlers” (also note that we only got this because we’re still building 32bit targets). The error occurs because some input modules were not compatible with the safe exception handlers feature of the linker. In our case it was some third party lib files for which I did not have the source code. These lib files are not be compatible with safe exception handlers is because they were created with an older version of the Visual C++ compiler.

But this is easy to fix. You just need to tell the linker not to produce an image with a table of safe exceptions handlers even if it thinks that all modules are compatible with the safe exception handling feature.

If you work in the Visual Studio Editor, you can right-click on your DLL project, go to Properties > Linker > Advanced and set “image has safe exception handlers” to No.

If like me you’re working from the command line, you can edit the .vcxproj file by opening it and searching for the <link> tags. Add the following to each <link> tag (there will be one per target e.g. one for debug and one for release):

<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>

It doesn’t matter where exactly you add it, it just needs to be between <link> and </link>.

If you call the linker yourself, you can also add /SAFESEH:NO to the command line.

After making this change, you can build your project again and the error will be gone.

OleViewer: STG_E_FILENOTFOUND and IDataObject interface viewer only supports IID_IDataObject

I had some problems loading a type library (TLB file) when building a Visual C++ project, so I wanted to have a look at the TLB file using the OleViewer. So I started the OleViewer as Administrator from C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\x64. When opening the TLB file I got the following error message:

LoadTypeLib(my tlb file) failed.
STG_R_FILENOTFOUND ($80030002)

The issue here was that I started the 64bit version of the OleViewer. With the 32bit version (present directly in C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin), this error was gone, so it could actually load the file but I got another error message:

IDataObject interface viewer only supports IID_IDataObject

Solving this was easy but kind of confusing. I went to the View menu, unchecked “Expert Mode” then opened the TLB file. And the error message was gone. After that I checked it again but could still open the TLB file. Eveb after closing the OleViewer and opening it again, I was able to load the TLB file.

I’m still not 100% sure what happened here… Another thing I did after removing the Expert Mode and before reopening my TLB file was to open a few object classes in the tree on the left. At least of them was the Microsoft Web Browser (under Controls). So if unchecking the Expert Mode alone doesn’t help, you could try this.

It looks like the error message I got above means that iviewers.dll in-process server was not properly registered. The OleViewer uses iviewers.dll to parse the type library. Somehow after the things I’ve done above, the registration was fine. Of course if it still doesn’t work for you, you can try registering it yourself using regsvr32 iviewers.dll.

Somewhere inbetween I’ve also try using but also had a problem with the same TLB file (also it worked for others). After the problem was solved with OleViewer, OleWoo was also able to open the TLB file. So I guess OleWoo parses the TLB the same way OleViewer does.

And actually after that Visual Studio 2012 wasn’t complaining anymore about the TLB file. Before that I got the following error message on the line where I import the TLB file:

error C1084: Cannot read type library file: ‘my tlb file’: Error loading type library/DLL.

So it looks like Visual Studio had the same issue with iviewers.dll as OleViewer and OleWoo but unfortunately only said it couldn’t load the type library instead of giving me a more precise error message…

Even if I don’t really get what happend here, I’m glad it’s solved 🙂

This file requires _WIN32_WINNT to be #defined at least to 0x0403. Value 0x0501 or higher is recommended

While building a product originally written with Visual Studio 6 on my machine (Windows 7 and Visual Studio 2010), I got for a few sub-projects the following error message:

c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\atlmfc\include\atlcore.h(35): fatal error C1189: #error : This file requires _WIN32_WINNT to be #defined at least to 0x0403. Value 0x0501 or higher is recommended.

Using findstr, I could see that _WIN32_WINNT was not set in those projects. So the solution was easy. I just had to add the following to the beginning of stdafx.h in those projects:

#ifndef WINVER				// Allow use of features specific to Windows XP or later.
#define WINVER 0x0501		// Change this to the appropriate value to target other versions of Windows.
#endif

#ifndef _WIN32_WINNT		// Allow use of features specific to Windows XP or later.                   
#define _WIN32_WINNT 0x0501	// Change this to the appropriate value to target other versions of Windows.
#endif

After that the projects could build successfully.

Linux: C++ lookup error – undefined symbol

At a customer site, we had a C++ program (renamed for the purpose of this blog to myprogram) which was failing after running for some time. It’s a program processing messages from an external system and seemed to fail only when the processing of the message triggered some given operations. The error message was:

lookup error: /home/xxx/bin/xxx/myprogram: undefined symbol: _Z22CxxxPxxxExxxPxxxR6CDBManRKSsRSt6vectorISsSaISsEE

The first thought was to use ldd to check whether everything was fine:

# ldd myprogram
        linux-gate.so.1 =>  (0xffffe000)
        libxxx230.so => not found
        libmc3adv.so => not found
        libsybdb.so => not found
        libxxxutl.so => not found
        libxxxdb.so => not found
        libxxxcustom.so => not found
        libxerces-c.so.23 => not found
        libdl.so.2 => /lib/libdl.so.2 (0x4001e000)
        libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x40022000)
        libm.so.6 => /lib/tls/libm.so.6 (0x400df000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x40101000)
        libc.so.6 => /lib/tls/libc.so.6 (0x40109000)
        /lib/ld-linux.so.2 (0x40000000)

So many not found ! Ok I must have forgotten something… Of course, LD_LIBRARY_PATH is probably not set in my shell:

# pidof myprogram
10132
# export `cat /proc/10132/environ | strings | grep LD_LIBRARY_PATH`
  • pidof return the id of the process running the specified program
  • /proc/10132/environ contains the whole environment of the specified process
  • strings is required to convert the 0x00 separated strings of /proc/xxx/environ
  • The rest just gets the line LD_LIBRARY_PATH=… and uses export to set it in my shell as well

Now I have the same LD_LIBRARY_PATH as the process running myprogram and can rerun ldd:

ldd myprogram
        linux-gate.so.1 =>  (0xffffe000)
        libxxx230.so => /home/xxx/libs/libxxx230.so (0x40018000)
        libmc3adv.so => /home/xxx/libs/libmc3adv.so (0x40051000)
        libsybdb.so => /opt/sybase-12.5/OCS-12_5/lib/libsybdb.so (0x403a5000)
        libxxxutl.so => /home/xxx/libs/libxxxutl.so (0x404e1000)
        libxxxdb.so => /home/xxx/libs/libxxxdb.so (0x405c5000)
        libxxxcustom.so => /home/xxx/libs/libxxxcustom.so (0x4068d000)
        libxerces-c.so.23 => /home/xxx/libs/libxerces-c.so.23 (0x40695000)
        libdl.so.2 => /lib/libdl.so.2 (0x40985000)
        libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x40988000)
        libm.so.6 => /lib/tls/libm.so.6 (0x40a46000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x40a68000)
        libc.so.6 => /lib/tls/libc.so.6 (0x40a70000)
        libstdc++-libc6.1-1.so.2 => /usr/lib/libstdc++-libc6.1-1.so.2 (0x40b8a000)
        libpthread.so.0 => /lib/tls/libpthread.so.0 (0x40bd2000)
        /lib/ld-linux.so.2 (0x40000000)

Everything looks OK. So it’s not that a library is missing. Also the paths to the libraries are OK.

Executing ldd -r -d myprogram basically just shows me the same plus an error with the missing symbol.

Finally, comparing the size of the library files on this system and at another customer site with the exact same version of the software gave us the answer: somehow a different version of one of our library landed there and didn’t contain the missing symbol.

So the search ended there. Otherwise we’d have had to use the following:

Use c++filt to find out the method behind the mangled symbol name:

# c++filt _Z22CxxxPxxxExxxPxxxR6CDBManRKSsRSt6vectorISsSaISsEE
CxxxPxxxExxxPxxx(CDBMan&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&)

Use nm to list the symbols in the libraries shown by ldd:

# nm /home/xxx/libs/libxxxdb.so

This will show the mangled symbol names. For demangled symbols, use the -C option:

 # nm -C /home/xxx/libs/libxxxdb.so