CentOS 5.9 build bust: rt sanitizer & incompatible TCP/IP headers

This is the same issue as reported in the "Trouble compiling CLANG on on
RHEL 3.0" from 18 June. It applies to CentOS/RHEL 5 as well. Afaict, the
bust was introduced on 7 June in check in "[compiler-rt] r183517 -
[sanitizer] ioctl interceptor"; though that's from code inspection, not
from having tried the immediate predecessor. The Clang 3.3 certainly
builds fine on CentOS/RHEL 5 using gcc upgraded to 4.8.1 from the distro's
stock gcc 4.1.2. I did not automate the SVN checkout and build until 24
June and have been getting this bust since then; here's last night's try:

In file included from /mnt/share/RHEL5_local/buildroot/llvm_projects/llvm_svn_wtest_20130712_191043/projects/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc:76:
In file included from /usr/include/linux/mroute.h:5:
/usr/include/linux/in.h:26:3: error: redefinition of enumerator 'IPPROTO_IP'
  IPPROTO_IP = 0, /* Dummy protocol for TCP */
  ^
/usr/include/netinet/in.h:34:21: note: expanded from macro 'IPPROTO_IP'
#define IPPROTO_IP IPPROTO_IP
                                ^
/usr/include/netinet/in.h:33:5: note: previous definition is here
    IPPROTO_IP = 0, /* Dummy protocol for TCP. */
    ^

IPPROTO_ICMP, IPPROTO_IGMP, IPPROTO_TCP and a number of other manifest
constants/enums collide in later messages. Further, if the build got by
this issue, I think it would land on the rocks again with the subsequent
include of <linux/mroute6.h> on the next line of
sanitizer_platform_limits_posix.cc since that file does not exist in the
CentOS/RHEL 5 distribution.

I did a code check of these headers on Ubuntu 12.04 and the organization
seems updated and consistent with the compiler-rt sanitizer code. It also
appears as though there is some effort to do OS/platform detection using
manifest constants SANITIZER_LINUX, SANITIZER_ANDROID, etc. But these are
based on things like "#if defined(__linux__)" and do not appear to be
granular enough to accomodate the header differences among Linux'es.

I'm a newbie to building/using and looking at Clang so I don't know the
idioms for OS/platform detection or the consumer side of sanitizer; and I
suspect fixups in those areas are the right way to address this bust.

+eugenis following Kostya Serebryany's lead

While the following partial patch may not be the best approach, it solves the compiler build failure problem on RHEL 5 in my sandbox (and probably for any Linux 2.x kernel at or before 2.6.18). Ultimately, maybe we should avoid holding a compiler build hostage to incompatible TCP/IP headers in a target/build host's distribution?

Also, is there an easy way to find out if there's a buildbot slave running RHEL5 w/gcc 4.8.1? I waded through some clicks off of http://lab.llvm.org:8011/buildslaves, but it wasn't obvious and I thought there must be an easier, better way? I could volunteer part of a modest box for that duty since it's dear to my heart.

Index: lib/sanitizer_common/sanitizer_platform_limits_posix.cc

+samsonov

Looks like 2.6.18 kernel is pretty old… Mark, do you actually plan to use sanitizers? We consider dropping support for old kernels to ease the maintenance.
Seems that with all the recent ioctl hackery we’ll need to add support for detecting Linux kernel version and headers availability to our build system…

Kernel is pretty old, but it's the core of a wildly popular RHEL5 distribution that's still getting kernel updates (i.e., kernel-2.6.18-348.12.1.el5 as recently as last week!). I think a bunch of 'nix shops are passing on RHEL6 awaiting 7, then there's the conversion period. So, my guess is that RHEL5 will represent widespread active production machines for at least the next 24 months.

On the "do I use sanitizers" question, the answer is not explicitly and/or not yet, being new to Clang. I only use the compiler now, but I want to use static analyzer and other llvm code quality tools as I find them, and play with formatter. The problem I had was even compiler would not build following the basic instructions with the mroute6?.h headers.

Conceptually, if there's a code bit that drills into headers for very platform specific things like ioctl, using autotool-like detection or support of a narrowed platform set seems like a real design choice. In the event of picking the latter, maybe the top level build instructions should provide a way to unplug "sanitizer" so the compiler itself can enjoy an wider target range?

Thank you.

Mark

I see your point. We’ll try to add header detection to our build system soon.

Hi,
Yes, the RedHat EL5 kernel will be maintained by RedHat for several more years. They
are just now EOLing EL4. So, you can believe the 2.6.18 kernel will be viable for
a number of years yet.

The EL5 kernel has a huge patch list. I believe it is about 1500 patches. Ball Park
estimate, could be more. RedHat backports whatever features they want to support. It
remains viable even today, despite the old release number.

enjoy,
Karen

Thanks, Alexey.

I would reiterate my willingness to put a piece of a modest RHEL5 machine in place as a buildbot slave if you could point me to the right person to get around the "builds now" requirement. Hey, it's not just a 286, it has a great V35 modem capable of 56 kilobaud! And I would have worked on finding some ac_helpful.m4 on mroute.h but, just as I was shutting down the fryer at my day job, this soccer team comes in ordering 31 super size. Hate it when that happens.

Hi,

sorry for the late response. First of all, any configure magic would
need to be replicated in cmake, as we have two build systems. That's
part of the reason we tend to do as much as possible right in the
source code.

I wonder if you could find out the minimal change to platform_limits
files to make them compile on your OS?

Hi Evgeniy,

Now my apologies for being late; the day job's been pretty consuming but maybe I'm on the good side. I'll look at the platform_limits files and see if I can help.

I'll keep you posted.

Thank you.

Mark

Well, I tried building clang on centos 5.9 and it did not go well.
Clang itself builds mostly fine, but the result is essentially
unusable because of incompatibilities with glibc headers.
There is a bunch of "extern inline" declarations in
"/usr/include/bits/string2.h". Because of the different semantics
between clang and gcc, they are emitted as publicly visible symbols in
every object file. As a result, linking fails with "multiple
definitions" errors. Newer glibc headers don't use "extern inline"
unless some magic GCC macros are defined.

How do people do it? Do I need to upgrade glibc? That sounds a bit scary.