[LLVMdev] runStaticConstructorsDestructors not calling static destructors
Graham Wakefield
wakefield at mat.ucsb.edu
Fri Sep 9 13:36:35 PDT 2011
Hi there,
I'm having trouble getting ExecutionEngine->runStaticConstructorsDestructors(module, true) to actually trigger static destructors in my code. The static constructors however do get called.
I don't know if this is an LLVM or Clang issue, from looking at the IR (see below) it looks like the destructor is being tied to cxa_atexit, and I wonder if that is not called by runStaticConstructorsDestructors(module, true);
Thanks in advance for any suggestions you can offer!
Graham
Using LLVM/Clang 2.9 release for OSX, on OSX 10.6.8, on a core i7 macbook pro.
I'm compiling from C++ using Clang, and passing the compiled module to an ExecutionEngine created as follows:
EE = llvm::EngineBuilder(globalModule)
.setEngineKind(llvm::EngineKind::JIT)
.setErrorStr(&err)
.setOptLevel(llvm::CodeGenOpt::Default)
.setAllocateGVsWithCode(false)
//.setMAttrs("-avx")
.setMCPU("core2")
.create();
EE->DisableLazyCompilation();
After passing in the compiled module, I call:
EE->runStaticConstructorsDestructors(module, false);
Then to test the tear-down of the module, I call:
EE->runStaticConstructorsDestructors(mImpl->module, true);
EE->clearGlobalMappingsFromModule(mImpl->module);
EE->removeModule(mImpl->module);
The C++ code compiled:
#include <stdio.h>
class Foo {
public:
Foo() { printf("Foo\n"); };
~Foo() { printf("~Foo\n"); };
int x;
};
// a static variable:
Foo foo;
The constructor is being called (I see 'Foo' in my stdout), but the destructor is not.
The LLVM IR produced:
; ModuleID = 'mymodule'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32"
target triple = "i386-apple-darwin10"
%0 = type { i32, void ()* }
%class.Foo = type { i32 }
@foo = global %class.Foo zeroinitializer, align 4
@__dso_handle = external global i8*
@.str = private unnamed_addr constant [6 x i8] c"~Foo\0A\00"
@.str1 = private unnamed_addr constant [5 x i8] c"Foo\0A\00"
@llvm.global_ctors = appending global [1 x %0] [%0 { i32 65535, void ()* @_GLOBAL__I_a }]
define internal void @__cxx_global_var_init() nounwind section "__TEXT,__StaticInit,regular,pure_instructions" {
call void @_ZN3FooC1Ev(%class.Foo* @foo)
%1 = call i32 @__cxa_atexit(void (i8*)* bitcast (void (%class.Foo*)* @_ZN3FooD1Ev to void (i8*)*), i8* bitcast (%class.Foo* @foo to i8*), i8* bitcast (i8** @__dso_handle to i8*))
ret void
}
define linkonce_odr void @_ZN3FooC1Ev(%class.Foo* %this) unnamed_addr nounwind align 2 {
%1 = alloca %class.Foo*, align 4
store %class.Foo* %this, %class.Foo** %1, align 4
%2 = load %class.Foo** %1
call void @_ZN3FooC2Ev(%class.Foo* %2)
ret void
}
define linkonce_odr void @_ZN3FooD1Ev(%class.Foo* %this) unnamed_addr nounwind align 2 {
%1 = alloca %class.Foo*, align 4
store %class.Foo* %this, %class.Foo** %1, align 4
%2 = load %class.Foo** %1
call void @_ZN3FooD2Ev(%class.Foo* %2)
ret void
}
declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*)
define linkonce_odr void @_ZN3FooD2Ev(%class.Foo* %this) unnamed_addr nounwind align 2 {
%1 = alloca %class.Foo*, align 4
store %class.Foo* %this, %class.Foo** %1, align 4
%2 = load %class.Foo** %1
%3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0))
ret void
}
declare i32 @printf(i8*, ...)
define linkonce_odr void @_ZN3FooC2Ev(%class.Foo* %this) unnamed_addr nounwind align 2 {
%1 = alloca %class.Foo*, align 4
store %class.Foo* %this, %class.Foo** %1, align 4
%2 = load %class.Foo** %1
%3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str1, i32 0, i32 0))
ret void
}
define internal void @_GLOBAL__I_a() nounwind section "__TEXT,__StaticInit,regular,pure_instructions" {
call void @__cxx_global_var_init()
ret void
}
I added a JITEventListener, which displays:
JIT emitted Function _GLOBAL__I_a at 0x1c00010, size 12
JIT emitted Function __cxx_global_var_init at 0x1c00020, size 47
JIT emitted Function _ZN3FooD1Ev at 0x1c00060, size 23
JIT emitted Function _ZN3FooD2Ev at 0x1c00080, size 27
JIT emitted Function _ZN3FooC1Ev at 0x1c000a0, size 23
JIT emitted Function _ZN3FooC2Ev at 0x1c000c0, size 27
JIT freed 0x1c00020
JIT freed 0x1c000a0
JIT freed 0x1c00060
JIT freed 0x1c00080
JIT freed 0x1c000c0
JIT freed 0x1c00010
More information about the llvm-dev
mailing list