PATCH: AddressSanitizer: Fix errors about mis-matched exception specifiers for intercepted libc functions on Linux

Hello,

On modern Linux installs, glibc has a very annoying practice: it adds an empty exception specifier to lots of libc functions as an optimization. It only does this if the compiler is modern and GCC-like, and we are compiling in C++ mode.

This, however, causes GCC to complain about signature mismatches between the glibc functions declared in malloc.h and those defined as an alias in the interceptors library:

…/asan_malloc_linux.cc:57:1: error: declaration of ‘void free(void*)’ has a different exception specifier
/usr/include/malloc.h:66:13: error: from previous declaration ‘void free(void*) throw ()’

I’ve attached a complete hack of a patch to address this… but surely there is a better way? I’m open to suggestions about this sticky issue.

Amusingly, this is only diagnosed by GCC, not by Clang. =] So I didn’t even notice it at first.
-Chandler

exception-spec.patch (593 Bytes)

Hello,

On modern Linux installs, glibc has a very annoying practice: it adds an empty exception specifier to lots of libc functions as an optimization. It only does this if the compiler is modern and GCC-like, and we are compiling in C++ mode.

This, however, causes GCC to complain about signature mismatches between the glibc functions declared in malloc.h and those defined as an alias in the interceptors library:

…/asan_malloc_linux.cc:57:1: error: declaration of ‘void free(void*)’ has a different exception specifier
/usr/include/malloc.h:66:13: error: from previous declaration ‘void free(void*) throw ()’

I’ve attached a complete hack of a patch to address this… but surely there is a better way? I’m open to suggestions about this sticky issue.

ouch!
How do I reproduce the failure?
For me, the code build fine with gcc (4.4.3 and 4.7.0).

–kcc

Looking at /usr/include/malloc.h I don't see any instances of throw()
(Goobuntu Lucid)
Shouldn't we have the same set of standard headers?

… And the right fix would be to completely get rid of “#include <malloc.h>” in this file.
I’ll do that change.

–kcc

done: r159132.

I really don’t see why this is the correct fix.

  1. I like including the system’s headers. It ensures that the interceptor DTRT.
  2. It’s hardly the only system header you pull in here
  3. I think we should probably match what glibc does when declaring these routines. any reason to avoid this?

Hello,

On modern Linux installs, glibc has a very annoying practice: it adds an empty exception specifier to lots of libc functions as an optimization. It only does this if the compiler is modern and GCC-like, and we are compiling in C++ mode.

This, however, causes GCC to complain about signature mismatches between the glibc functions declared in malloc.h and those defined as an alias in the interceptors library:

…/asan_malloc_linux.cc:57:1: error: declaration of ‘void free(void*)’ has a different exception specifier
/usr/include/malloc.h:66:13: error: from previous declaration ‘void free(void*) throw ()’

I’ve attached a complete hack of a patch to address this… but surely there is a better way? I’m open to suggestions about this sticky issue.

ouch!
How do I reproduce the failure?
For me, the code build fine with gcc (4.4.3 and 4.7.0).

I’m not sure… maybe add ‘-pedantic’ to your compile flags? It triggers easily with the in-progress CMake build, and one of the differences is inheritting the fairly strict set of compile flags from LLVM proper.

Ahem, not everyone works where we do? ;]

I’m testing this on a very generic Linux box. I think you’ll find that the preprocessed source of malloc.h does include throw(). It’s burried inside of MALLOC_P, other macros, __THROW, etc. But eventually it gets there.

I really don’t see why this is the correct fix.

  1. I like including the system’s headers. It ensures that the interceptor DTRT.
  2. It’s hardly the only system header you pull in here

Oh, it actually is (was) the only system header left in this file. I am glad to be able to get rid of it.
I’ve been fighting the system headers for a long time now: for this kind of code they are surprisingly painful.
Now, we have zero system headers in .h files and just a few in OS-dependent .cc files.

We are replacing functions that have a very clear “C” interface which is not going to change, so including system headers does not help.
But it actually hurts very much: event some innocent system headers like stddef.h or stdlib.h bring along some unexpected typedefs, definds, decls, etc.
Things get worse if a .cc file is used on more than one platform (e.g. asan_malloc_linux.cc is also used on Android) where the system headers are different.

  1. I think we should probably match what glibc does when declaring these routines. any reason to avoid this?

We only need to keep the functions binary-compatible.

–kcc