Cling interpreter with -O3

Hi,

I am trying to produce optimized code with Cling.
I’m on OSX, using root 6 form brew:

$ brew info root6
homebrew/science/root6: stable 6.06.06 (bottled), HEAD

I used the code below:

// g++ -g -L/usr/local/lib/root -L/usr/local/opt/root6/lib/root -lCling -I/usr/local/etc/root/cling -I/usr/local/etc/root/ -std=c++14 -DDEBUG -o compile_crash compile_crash.cc
#include <vector>
#include <exception>
#include <sstream>
#include <iostream>
#include <fstream>

#include "cling/Interpreter/Interpreter.h"

cling::Interpreter* interpreter(nullptr);

const char *script =
  "#include <functional>                                                                                \n"
  "                                                                                                     \n"
  "namespace script {                                                                                   \n"
  "  static int __main(const int& args) {                                                               \n"
  "    return int();                                                                                    \n"
  "  }                                                                                                  \n"
  "  extern \"C\" std::function<int(int)>* __xxxx_exports(new std::function<int(int)>(script::__main)); \n"
  "}                                                                                                    \n";

void setup() {

  std::string base_cling_directory = "/usr/local/etc/root";
  std::string include_root = "-I" + base_cling_directory;
  std::vector<const char*> args = {"-nostdinc++",
                                   "-std=c++14",
                                   "-DDEBUG",
                                   "-O3",
#ifdef __APPLE__
                                   "-I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1",
#elif __linux__
                                   "-I/usr/include/c++/5", "-I/usr/include/x86_64-linux-gnu/c++/5", "-I/usr/include/c++/5/backward",
#else
  #error "Unknown compiler"
#endif
                                   include_root.c_str()};

  const std::string llvmdir = base_cling_directory + "/cling";
  interpreter               = new cling::Interpreter(args.size(), args.data(), llvmdir.c_str());
}

std::string load_file(const std::string &file) {
  std::ifstream t(file);
  if(!t) {
    printf("FAIL TO LOAD file %s.hh\n", file.c_str());
    exit(-1);
  }
  return std::string(std::istreambuf_iterator<char>(t), std::istreambuf_iterator<char>());
}

void compile() {
  if (interpreter->declare(script) != cling::Interpreter::CompilationResult::kSuccess) {
    printf("Failed to compile user script.\n");
    exit(-1);
  }

  printf("declare OK.\n");

  void* ptr = interpreter->getAddressOfGlobal("__xxxx_exports");
  printf("GOT %p for %s\n", ptr, "__xxxx_exports");
}

int main() {
  setup();

  compile("./script.cc", "__xxxx_exports");

  return 0;
}

Basically, I create a new cling interpreter with “-O3” in the arguments, and ‘declare’ this code:

#include <functional>

namespace script {
  static int __main(const int& args) {
    return int();
  }
  extern "C" std::function<int(int)>* __xxxx_exports(new std::function<int(int)>(script::__main));
}

It has a strange behavior: it fails sometimes, here is my terminal output:

$ ./compile_crash
declare OK.
GOT 0x1082d02a8 for __xxxx_exports

$ ./compile_crash
declare OK.
GOT 0x102ab12a8 for __xxxx_exports

$ ./compile_crash

 *** Break *** segmentation violation
 Generating stack trace...
 0x000000010eb20275 in llvm::Constant::removeDeadConstantUsers() const (in libCling.so) + 33
 0x000000010dd32e33 in cling::IncrementalExecutor::runStaticInitializersOnce(cling::Transaction const&) (in libCling.so) + 691
 0x000000010dd3b9cd in cling::Interpreter::executeTransaction(cling::Transaction&) (in libCling.so) + 117
 0x000000010dd36f4f in cling::IncrementalParser::commitTransaction(llvm::PointerIntPair<cling::Transaction*, 2u, cling::IncrementalParser::EParseResult, llvm::PointerLikeTypeTraits<cling::Transaction*> >) (in libCling.so) +
 0x000000010dd3763a in cling::IncrementalParser::Compile(llvm::StringRef, cling::CompilationOptions const&) (in libCling.so) + 146
 0x000000010dd3b5b5 in cling::Interpreter::DeclareInternal(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cling::CompilationOptions const&, cling::Transaction**) const (in libC
 0x000000010dd3a026 in cling::Interpreter::declare(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cling::Transaction**) (in libCling.so) + 52
 0x000000010dc6883f in compile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const*) (in compile_crash) (compile_crash.cc:56)
 0x000000010dc68a4f in main (in compile_crash) (compile_crash.cc:70)
 0x00007fff8cd255ad in start (in libdyld.dylib) + 1
 0x0000000000000001 in <unknown function>

$ ./compile_crash

 *** Break *** segmentation violation
 Generating stack trace...
 0x00000001062fd275 in llvm::Constant::removeDeadConstantUsers() const (in libCling.so) + 33
 0x000000010550fe33 in cling::IncrementalExecutor::runStaticInitializersOnce(cling::Transaction const&) (in libCling.so) + 691
 0x00000001055189cd in cling::Interpreter::executeTransaction(cling::Transaction&) (in libCling.so) + 117
 0x0000000105513f4f in cling::IncrementalParser::commitTransaction(llvm::PointerIntPair<cling::Transaction*, 2u, cling::IncrementalParser::EParseResult, llvm::PointerLikeTypeTraits<cling::Transaction*> >) (in libCling.so) +
 0x000000010551463a in cling::IncrementalParser::Compile(llvm::StringRef, cling::CompilationOptions const&) (in libCling.so) + 146
 0x00000001055185b5 in cling::Interpreter::DeclareInternal(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cling::CompilationOptions const&, cling::Transaction**) const (in libC
 0x0000000105517026 in cling::Interpreter::declare(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cling::Transaction**) (in libCling.so) + 52
 0x000000010543e83f in compile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const*) (in compile_crash) (compile_crash.cc:56)
 0x000000010543ea4f in main (in compile_crash) (compile_crash.cc:70)
 0x00007fff8cd255ad in start (in libdyld.dylib) + 1
 0x0000000000000001 in <unknown function>

$ ./compile_crash
declare OK.
GOT 0x10b4ff2a8 for __xxxx_exports

Is there anything I can fix on that to get it work with -O3 ?

Thanks in advance for your help!

Vincent

Hi,

I see no problem in the master, using cling interactively with -O3, and running with valgrind. I’ll have to debug this on MacOS. As before, do you think you can reproduce this on the regular cling binary?

Cheers, Axel.