[LLVMdev] Memory leaks after llvm_shutdown

Alexey Zasenko alexey.zasenko at visutechsystem.by
Thu Dec 13 04:16:32 PST 2012


Hi llvmdev!

In our project (Windows, Visual Studio compiler) we've got some frontend 
which generates LLVM IR. Now I'm observing strange *llvm_shutdown* behavior.

If I called it when I was done using the LLVM APIs I saw that 
destructors of static objects created new ManagedStatic objects, which 
was never freed.

Then I tried to use static global llvm_shutdown_obj to cause destruction 
of ManagedStatics after calling all static destructors. In that case I 
got "pure virtual function call" because of early release of 
BumpPtrAllocator::DefaultSlabAllocator.

Call stack for this case:
      msvcr100d.dll!_purecall()  Line 54 + 0x7 bytes    C
 > llvm_test.exe!llvm::BumpPtrAllocator::DeallocateSlabs(llvm::MemSlab * 
Slab)  Line 71 + 0x1b bytes    C++
      llvm_test.exe!llvm::BumpPtrAllocator::~BumpPtrAllocator() Line 
30    C++
      llvm_test.exe!llvm::LLVMContextImpl::~LLVMContextImpl() Line 128 + 
0xf3 bytes    C++
      llvm_test.exe!llvm::LLVMContextImpl::`scalar deleting 
destructor'()  + 0x16 bytes    C++
      llvm_test.exe!llvm::LLVMContext::~LLVMContext()  Line 62 + 0x38 
bytes    C++
      llvm_test.exe!llvm::LLVMContext::`scalar deleting destructor'()  + 
0x16 bytes    C++
llvm_test.exe!llvm::object_deleter<llvm::LLVMContext>::call(void * Ptr)  
Line 32 + 0x37 bytes    C++
      llvm_test.exe!llvm::ManagedStaticBase::destroy()  Line 68 + 0x10 
bytes    C++
      llvm_test.exe!llvm::llvm_shutdown()  Line 78 + 0xb bytes C++

Also I tried not to use GlobalContext object and created my own one. 
This method didn't help - GlobalContext was still lazy creating by 
PseudoSourceValue ctor .

I would understand to know if I did something wrong or is this a bug?
I made tests both on 3.1 and trunk builds.

Thank you in advance!
--
Alexey Zasenko
Visutech System Ltd.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20121213/29f48ef2/attachment.html>
-------------- next part --------------
#include <iostream>

#include <llvm/LLVMContext.h>
#include <llvm/Linker.h>
#include <llvm/Module.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/ExecutionEngine/JIT.h>
#include <llvm/Support/ManagedStatic.h>

using namespace std;
using namespace llvm;

static llvm_shutdown_obj llvm_cleaner;

int main(int argc, char** argv)
{		
	LLVMContext context;// getGlobalContext();	
	InitializeNativeTarget();
	InitializeNativeTargetAsmPrinter();
	InitializeNativeTargetAsmParser();	

	Linker llvm_linker (StringRef("llvm_test"), StringRef("MergedModule"), context, Linker::Verbose);	
	if(argc >= 3){
		int next_module_idx = 2;
		Linker::ItemList linkItems;
		while (next_module_idx < argc ){			
			bool is_native = false;			
			linkItems.push_back(make_pair(string(argv[next_module_idx]), false));
			next_module_idx++;
		}

		Linker::ItemList natives;
		if(llvm_linker.LinkInItems(linkItems, natives)){
			cout << "Linking error! " << llvm_linker.getLastError()<< "\n";
			return 3;
		}
	}	
	Module *m = llvm_linker.releaseModule();

	string err;
	ExecutionEngine *ee = EngineBuilder(m).setEngineKind(EngineKind::JIT).setErrorStr(&err).create();

	ee->DisableGVCompilation(false);
	ee->DisableLazyCompilation(true);

	Function* func = ee->FindFunctionNamed(argv[1]);
	if(!func){
		cout<<"cannot find entry point\n";
		return -1;
	}

	typedef void (*PFN)();	
	PFN pfn = reinterpret_cast<PFN>(ee->getPointerToFunction(func));

	pfn();

	ee->freeMachineCodeForFunction(func);

	delete ee;	
	return 0;
}


More information about the llvm-dev mailing list