[LLVMdev] lli crashes when running cpp programs

Dongpeng Xu dongpengxu at psu.edu
Fri Mar 21 11:35:14 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 example.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*) + 38
1  lli    
        0x0000000001323fbe
2  lli  
          0x0000000001323a02
3
 libpthread.so.0 0x00007fd4c168b210
4  libc.so.6  
    0x00007fd4c06de1d5 gsignal + 53
5  libc.so.6
      0x00007fd4c06e1388 abort + 328
6  libc.so.6
      0x00007fd4c06d7252
7  libc.so.6  
    0x00007fd4c06d7302
8  lli      
      0x0000000000cf1620
llvm::JIT::runJITOnFunctionUnlocked(llvm::Function*, llvm::MutexGuard
const&) + 66
9  lli          
  0x0000000000cf1a3a llvm::JIT::getPointerToFunction(llvm::Function*) +
694
10 lli            
0x00000000010fb64c llvm::ExecutionEngine::getPointerToGlobal(llvm::GlobalValue
const*) + 70
11 lli            
0x0000000000cfa2f0
12 lli            
0x0000000000cfaca3
13 lli            
0x00000000008c9368
14 lli            
0x0000000000d6a9e1
llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 95
15
lli             0x000000000129a53f
llvm::FPPassManager::runOnFunction(llvm::Function&) + 385
16 lli
            0x000000000129a286
llvm::legacy::FunctionPassManagerImpl::run(llvm::Function&) +
84
17 lli            
0x0000000001299e5e llvm::legacy::FunctionPassManager::run(llvm::Function&)
+ 180
18 lli            
0x0000000000cf175c llvm::JIT::jitTheFunction(llvm::Function*, llvm::MutexGuard
const&) + 72
19 lli            
0x0000000000cf1637 llvm::JIT::runJITOnFunctionUnlocked(llvm::Function*,
llvm::MutexGuard const&) + 89
20 lli        
    0x0000000000cf1a3a
llvm::JIT::getPointerToFunction(llvm::Function*) + 694
21 lli  
          0x0000000000817815 main + 4732
22
libc.so.6       0x00007fd4c06ca995 __libc_start_main +
245
23 lli            
0x000000000080d479
Stack dump:
0.    Program
arguments: lli example.bc 
1.    Running pass 'X86
Machine Code Emitter' on function
'@main'
Aborted




I look into
the problem and find that it is caused by the alias
instructions:


@_ZN3clsC1Ev = alias void (%class.cls*)*
@_ZN3clsC2Ev
@_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. Any comments are appreciated. Thanks for your help!




Sincerely,
Dongpeng
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140321/ae8cbe6b/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-dev/attachments/20140321/ae8cbe6b/attachment.obj>


More information about the llvm-dev mailing list