overriding default compiler options in distutils

January 29th, 2007 by Bramz

While debugging another segmentation fault on linux, I was trying to run LiAR in gdb (actually KDbg). The program crashed somewhere in an allocator, but the reason why was almost impossible to see. The debugging experience was crippled because distutils compiles with full optimization -O3 by default, at least my linux box.

If I was going to debug it properly, I would have to get rid of that switch and use -O0 instead. But for some mysterious reason, distutils always used -DNDEBUG -g -O3 -Wall -Wstrict-prototypes, regardless of the --debug switch. It turns out distutils is getting these from the original Makefile used to build Python and stores them, together with the name gcc, in an attribute compiler_so of the CCompiler object. This attribute is later used to invoke the compiler.

Fortunately, in liar_build_shared_lib and liar_build_ext, we have access to the compiler object. All we have to do is, before building, to grab compiler_so, remove any -O switch and put an -O0 instead:

def force_no_optimisation(compiler):
    for i in range(4):
        try: compiler.compiler_so.remove("-O%s" % i)
        except: pass
    compiler.compiler_so.append("-O0")

class liar_build_shared_lib(build_clib):
    def build_library(self, lib_name, build_info):
        force_no_optimisation(self.compiler)
        ...

class liar_build_ext(build_ext):
    def build_extension(self, ext):
        force_no_optimisation(self.compiler)
        ...

What was causing the segmentation fault? The std::vector in kernel::Intersection was requesting memory for 0 elements. The lass::util::AllocatorBinned wasn’t really prepared for that. Once identified, it was easily fixed …

Comments are closed.