[LLVM-commits] lli crashes when running cpp programs

Dongpeng Xu dongpengxu at psu.edu
Mon Mar 24 07:34:26 PDT 2014


Hi all,
I need to run c++ prgrams using lli. However, I find lli cannot handle the
alias instruction correctly. Following is an example:
------------ example.cc -------------
#include <iostream>using namespace std;
class cls {public:    cls();    ~cls();};
cls::cls() {    cout << "constructor" << endl;};
cls::~cls() {    cout << "destructor" << endl;}
int main(int argc, char *argv[]){    cls *A = new cls();    delete A;    return
0;}
----------- end of file -----------
I compile and run the program by:
$ clang++ -emit-llvm -S example.cc -o example.S$ llvm-as exampls.S -o
example.bc$ lli example.bc
and get the "Recursive compilation" error output:
lli: /home/dongpeng/Program/llvm/lib/ExecutionEngine/JIT/JIT.cpp:467: void
llvm::JIT::runJITOnFunctionUnlocked(llvm::Function*, const llvm::MutexGuard&):
Assertion `!isAlreadyCodeGenerating && "Error: Recursive compilation
detected!"' failed.0  lli             0x0000000001323d37
llvm::sys::PrintStackTrace(_IO_FILE*) + 381  lli            
0x0000000001323fbe2  lli             0x0000000001323a023  libpthread.so.0
0x00007fd4c168b2104  libc.so.6       0x00007fd4c06de1d5 gsignal + 535 
libc.so.6       0x00007fd4c06e1388 abort + 3286  libc.so.6      
0x00007fd4c06d72527  libc.so.6       0x00007fd4c06d73028  lli            
0x0000000000cf1620 llvm::JIT::runJITOnFunctionUnlocked(llvm::Function*,
llvm::MutexGuard const&) + 669  lli             0x0000000000cf1a3a
llvm::JIT::getPointerToFunction(llvm::Function*) + 69410 lli            
0x00000000010fb64c llvm::ExecutionEngine::getPointerToGlobal(llvm::GlobalValue
const*) + 7011 lli             0x0000000000cfa2f012 lli            
0x0000000000cfaca313 lli             0x00000000008c936814 lli            
0x0000000000d6a9e1 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) +
9515 lli             0x000000000129a53f
llvm::FPPassManager::runOnFunction(llvm::Function&) + 38516 lli            
0x000000000129a286 llvm::legacy::FunctionPassManagerImpl::run(llvm::Function&)
+ 8417 lli             0x0000000001299e5e
llvm::legacy::FunctionPassManager::run(llvm::Function&) + 18018 lli            
0x0000000000cf175c llvm::JIT::jitTheFunction(llvm::Function*, llvm::MutexGuard
const&) + 7219 lli             0x0000000000cf1637
llvm::JIT::runJITOnFunctionUnlocked(llvm::Function*, llvm::MutexGuard const&) +
8920 lli             0x0000000000cf1a3a
llvm::JIT::getPointerToFunction(llvm::Function*) + 69421 lli            
0x0000000000817815 main + 473222 libc.so.6       0x00007fd4c06ca995
__libc_start_main + 24523 lli             0x000000000080d479Stack dump:0.   
Program arguments: lli example.bc 1.    Running pass 'X86 Machine Code Emitter'
on function '@main'Aborted
This problem has also been reported as bug
10743<http://llvm.org/bugs/show_bug.cgi?id=10743>
I looked into the problem and find that it is caused by the alias instructions:
@_ZN3clsC1Ev = alias void (%class.cls*)* @_ZN3clsC2Ev at _ZN3clsD1Ev = alias void
(%class.cls*)* @_ZN3clsD2Ev
The first alias is for the constructor and the other one is for the destructor.
When finishing JIT the main function, JITEmitter needs to resolve all the names
in main. When it is trying to resolve the alias name @_ZN3clsC1Ev, the
following code in JITEmitter.cpp will go to resolve and JIT the original name
of the alias name. In my case, they are @_ZN3clsC2Ev and @_ZN3clsD2Ev. This
procedure will cause a recursive compilation error. 
---------------- lib/ExecutionEngine/JIT/JITEmitter.cpp ------------------------
void *JITEmitter::getPointerToGlobal(GlobalValue *V, void *Reference,          
                          bool MayNeedFarStub) {  if (GlobalVariable *GV =
dyn_cast<GlobalVariable>(V))    return TheJIT->getOrEmitGlobalVariable(GV);
  if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V))    return
TheJIT->getPointerToGlobal(GA->resolveAliasedGlobal(false));

One possible solution is to let JITEmitter emit a stub for the name like
following. 
@@ -687,8 +687,19 @@   if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V))   
 return TheJIT->getOrEmitGlobalVariable(GV); -  if (GlobalAlias *GA =
dyn_cast<GlobalAlias>(V))-    return
TheJIT->getPointerToGlobal(GA->resolveAliasedGlobal(false));+  if (GlobalAlias
*GA = dyn_cast<GlobalAlias>(V)) {+      Function *F =
const_cast<Function*>(dyn_cast<Function>(GA->resolveAliasedGlobal(false)));+   
  if (F == NULL) {+  	  return
TheJIT->getPointerToGlobal(GA->resolveAliasedGlobal(false));+      } else {+  	
   void *FnStub = Resolver.getLazyFunctionStubIfAvailable(F);+  	    if
(FnStub)+  		return FnStub;+  	    else+  		return
Resolver.getLazyFunctionStub(F);+      }+  }+    // If we have already compiled
the function, return a pointer to its body.   Function *F = cast<Function>(V);
Attached is the patch. I am not sure it is the correct way to solve the
problem. Please help me review it. Any comments are appreciated. Thanks for
your help!

Sincerely,Dongpeng

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140324/7d96407e/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: JITEmitter.patch
Type: application/octet-stream
Size: 972 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140324/7d96407e/attachment.obj>


More information about the llvm-commits mailing list