[LLVMdev] runStaticConstructorsDestructors not calling static destructors (original) (raw)
Graham Wakefield wakefield at mat.ucsb.edu
Fri Sep 9 13:36:35 PDT 2011
- Previous message: [LLVMdev] Help: I'm getting the "Entry point not found for 'libiconv_set_relocation_prefix' in dll libiconv-2.dll"
- Next message: [LLVMdev] runStaticConstructorsDestructors not calling static destructors
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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
- Previous message: [LLVMdev] Help: I'm getting the "Entry point not found for 'libiconv_set_relocation_prefix' in dll libiconv-2.dll"
- Next message: [LLVMdev] runStaticConstructorsDestructors not calling static destructors
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]