Interpreter->declare crash on bad script

Hi,

I am trying to properly handle compiler errors.
I’m on OSX, using root 6 form brew:

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

Here is a piece of code, that try to use cling interpreter to declare a script containing an error:

// 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"

const char * script =
  "template <typename UnaryOperation>                        \n"
  "static int lambda_operation(UnaryOperation op);           \n"
  "                                                          \n"
  "template <typename T>                                     \n"
  "inline int templated_function() {                         \n"
  "                                                          \n"
  "  lambda_operation([](int) -> int { return 3; });         \n"
  "                                                          \n"
  "  something_wrong;                                        \n"
  "}                                                         \n"
  "                                                          \n"
  "static void __main() {                                    \n"
  "  templated_function<int>();                              \n"
  "}                                                         \n";

cling::Interpreter* interpreter(nullptr);

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",
#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());
}

int main() {
  setup();
  interpreter->declare(script);

  return 0;
}

Instead of returning a compile error as a result of the interpreter->declare (I expected cling::Interpreter::CompilationResult::kFailure), I have this output:

$ ./compile_crash_2
input_line_3:9:3: error: use of undeclared identifier 'something_wrong'
  something_wrong;
  ^

 *** Break *** segmentation violation
 Generating stack trace...
 0x0000000100d92423 in clang::RecursiveASTVisitor<clang::(anonymous namespace)::StaticVarCollector>::TraverseStmt(clang::Stmt*) (in libCling.so) + 28995
 0x0000000100d8c776 in clang::RecursiveASTVisitor<clang::(anonymous namespace)::StaticVarCollector>::TraverseStmt(clang::Stmt*) (in libCling.so) + 5270
 0x0000000100d8d506 in clang::RecursiveASTVisitor<clang::(anonymous namespace)::StaticVarCollector>::TraverseStmt(clang::Stmt*) (in libCling.so) + 8742
 0x0000000100d8bcfa in clang::RecursiveASTVisitor<clang::(anonymous namespace)::StaticVarCollector>::TraverseStmt(clang::Stmt*) (in libCling.so) + 2586
 0x0000000100d8a6b8 in clang::DeclUnloader::VisitFunctionDecl(clang::FunctionDecl*) (in libCling.so) + 128
 0x0000000100d967b2 in clang::declvisitor::Base<clang::declvisitor::make_ptr, clang::DeclUnloader, bool>::Visit(clang::Decl*) (in libCling.so) + 96
 0x0000000100d8b170 in cling::TransactionUnloader::RevertTransaction(cling::Transaction*) (in libCling.so) + 300
 0x0000000100d7908a in cling::IncrementalParser::rollbackTransaction(cling::Transaction*) (in libCling.so) + 168
 0x0000000100d78d7d in cling::IncrementalParser::commitTransaction(llvm::PointerIntPair<cling::Transaction*, 2u, cling::IncrementalParser::EParseResult, llvm::PointerLikeTypeTraits<cling::Transaction*> >) (in libCling.so) +
 0x0000000100d7963a in cling::IncrementalParser::Compile(llvm::StringRef, cling::CompilationOptions const&) (in libCling.so) + 146
 0x0000000100d7d5b5 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
 0x0000000100d7c026 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
 0x0000000100cab943 in main (in compile_crash_2) (compile_crash_2.cc:50)
 0x00007fff8cd255ad in start (in libdyld.dylib) + 1
 0x0000000000000001 in <unknown function>

Is there some way to get proper compile error handling ?

Thanks in advance for you help

Vincent

Hi Vincent,

I’ll look at it. For me it’s faster (also to get a response to you!) if you can come up with a reproducer in either cling itself (i.e. some reproducer code that I can run within cling) or ROOT, without the need to adjust paths, compile and link.

But as I said, I’ll have a look at your code…

Axel.

Hi again,

I can reproduce an issue with ROT 6.06 and the master with your code. With asserts on it complaints:

$ root.exe -l -b -q t.cxx 
root [0] 
Processing t.cxx...
In file included from input_line_8:1:
t.cxx:7:3: error: use of undeclared identifier 'something_wrong'
  something_wrong;
  ^
root.exe: interpreter/llvm/src/tools/clang/lib/AST/DeclCXX.cpp:1046: clang::CXXMethodDecl* clang::CXXRecordDecl::getLambdaCallOperator() const: Assertion `!Calls.empty() && "Missing lambda call operator!"' failed.
Aborted

That’s with

template <typename UnaryOperation>
static int lambda_operation(UnaryOperation op);

template <typename T>
inline int templated_function() {
  lambda_operation([](int) -> int { return 3; });
  something_wrong;
}

void t() {
   templated_function<int>();
}

I suspect this is reproducing what you see, right?

Cheers, Axel.

Exactly.

With the piece of code you used, I get this terminal output:

$ root -l -b -q compile_crash_2_cling.cc
root [0]
Processing compile_crash_2_cling.cc...
In file included from input_line_8:1:
/Users/vincent/workspace/sandbox/cling/compile_crash_2_cling.cc:9:3: error: use of undeclared identifier 'something_wrong'
  something_wrong;
  ^

 *** Break *** segmentation violation
 Generating stack trace...
 0x00000001090d5423 in clang::RecursiveASTVisitor<clang::(anonymous namespace)::StaticVarCollector>::TraverseStmt(clang::Stmt*) (in libCling.so) + 28995
 0x00000001090cf776 in clang::RecursiveASTVisitor<clang::(anonymous namespace)::StaticVarCollector>::TraverseStmt(clang::Stmt*) (in libCling.so) + 5270
 0x00000001090d0506 in clang::RecursiveASTVisitor<clang::(anonymous namespace)::StaticVarCollector>::TraverseStmt(clang::Stmt*) (in libCling.so) + 8742
 0x00000001090cecfa in clang::RecursiveASTVisitor<clang::(anonymous namespace)::StaticVarCollector>::TraverseStmt(clang::Stmt*) (in libCling.so) + 2586
 0x00000001090cd6b8 in clang::DeclUnloader::VisitFunctionDecl(clang::FunctionDecl*) (in libCling.so) + 128
 0x00000001090d97b2 in clang::declvisitor::Base<clang::declvisitor::make_ptr, clang::DeclUnloader, bool>::Visit(clang::Decl*) (in libCling.so) + 96
 0x00000001090ce170 in cling::TransactionUnloader::RevertTransaction(cling::Transaction*) (in libCling.so) + 300
 0x00000001090bc08a in cling::IncrementalParser::rollbackTransaction(cling::Transaction*) (in libCling.so) + 168
 0x00000001090bbd7d in cling::IncrementalParser::commitTransaction(llvm::PointerIntPair<cling::Transaction*, 2u, cling::IncrementalParser::EParseResult, llvm::PointerLikeTypeTraits<cling::Transaction*> >) (in libCling.so) +
 0x00000001090bc63a in cling::IncrementalParser::Compile(llvm::StringRef, cling::CompilationOptions const&) (in libCling.so) + 146
 0x00000001090c05b5 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
 0x00000001090c17e4 in cling::Interpreter::loadFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool, cling::Transaction**) (in libCling.so) + 364
 0x00000001090eab9a in cling::MetaSema::actOnLCommand(llvm::StringRef, cling::Transaction**) (in libCling.so) + 226
 0x00000001090eb03b in cling::MetaSema::actOnxCommand(llvm::StringRef, llvm::StringRef, cling::Value*) (in libCling.so) + 63
 0x00000001090e7dd2 in cling::MetaParser::isXCommand(cling::MetaSema::ActionResult&, cling::Value*) (in libCling.so) + 380
 0x00000001090e79db in cling::MetaParser::isCommand(cling::MetaSema::ActionResult&, cling::Value*) (in libCling.so) + 135
 0x00000001090e78c8 in cling::MetaParser::isMetaCommand(cling::MetaSema::ActionResult&, cling::Value*) (in libCling.so) + 42
 0x00000001090e96a9 in cling::MetaProcessor::process(char const*, cling::Interpreter::CompilationResult&, cling::Value*) (in libCling.so) + 293
 0x000000010901a9c0 in TCling::ProcessLine(char const*, TInterpreter::EErrorCode*) (in libCling.so) + 2668
 0x000000010901d576 in TCling::ProcessLineSynch(char const*, TInterpreter::EErrorCode*) (in libCling.so) + 116
 0x00000001081a2d1f in TApplication::ExecuteFile(char const*, int*, bool) (in libCore.so) + 2285
 0x0000000108114c2a in TRint::ProcessLineNr(char const*, char const*, int*) (in libRint.so) + 118
 0x00000001081149b4 in TRint::Run(bool) (in libRint.so) + 912
 0x000000010810cecc in main (in root.exe) + 79
 0x00007fff8cd255ad in start (in libdyld.dylib) + 1

Thanks.

This looks like a deficiency in the StmtVisitor; I’ll discuss with Vassil once he’s back. I have created sft.its.cern.ch/jira/browse/ROOT-8357 for this.

Until then: no invalid code with uncalled lambdas, please :wink:

Cheers, Axel.

Hello,

I found this thread after searching for an explanation of this crash when instantiating a wrongly defined class :

root 
   ------------------------------------------------------------
  | Welcome to ROOT 6.06/06                http://root.cern.ch |
  |                               (c) 1995-2016, The ROOT Team |
  | Built for linuxx8664gcc                                    |
  | From tag v6-06-06, 6 July 2016                             |
  | Try '.help', '.demo', '.license', '.credits', '.quit'/'.q' |
   ------------------------------------------------------------

root [0] class B { public: int f(){ return erfdsf;}};
root [1] B b; b.f()

 *** Break *** segmentation violation



===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
#0  0x00007fe66c107dfa in waitpid () from /lib64/libc.so.6
#1  0x00007fe66c089fbc in do_system () from /lib64/libc.so.6
#2  0x00007fe66d0058e4 in TUnixSystem::StackTrace() () from /home/delsart/SOFTWARE/root/lib/libCore.so
#3  0x00007fe66d007a4c in TUnixSystem::DispatchSignals(ESignals) () from /home/delsart/SOFTWARE/root/lib/libCore.so
#4  <signal handler called>
#5  0x0000000001904d00 in ?? ()
#6  0x00000000018fce40 in ?? ()
#7  0x00000000018fd240 in ?? ()
#8  0x00000000018fce40 in ?? ()
#9  0x0000000001904d00 in ?? ()
#10 0x00007fe66949e227 in clang::ASTContext::getTypeInfo(clang::Type const*) const () from /home/delsart/SOFTWARE/root/lib/libCling.so
#11 0x00007fe6694a0c23 in clang::ASTContext::getPreferredTypeAlign(clang::Type const*) const () from /home/delsart/SOFTWARE/root/lib/libCling.so
#12 0x00007fe6694a1d63 in clang::ASTContext::getDeclAlign(clang::Decl const*, bool) const () from /home/delsart/SOFTWARE/root/lib/libCling.so
#13 0x00007fe668f402d0 in clang::CodeGen::CodeGenFunction::EmitDeclRefLValue(clang::DeclRefExpr const*) () from /home/delsart/SOFTWARE/root/lib/libCling.so
#14 0x00007fe668f46e36 in clang::CodeGen::CodeGenFunction::EmitLValue(clang::Expr const*) () from /home/delsart/SOFTWARE/root/lib/libCling.so
#15 0x00007fe668f48e1a in clang::CodeGen::CodeGenFunction::EmitCheckedLValue(clang::Expr const*, clang::CodeGen::CodeGenFunction::TypeCheckKind) () from /home/delsart/SOFTWARE/root/lib/libCling.so
#16 0x00007fe668f6dabc in (anonymous namespace)::ScalarExprEmitter::EmitLoadOfLValue(clang::Expr const*) () from /home/delsart/SOFTWARE/root/lib/libCling.so
#17 0x00007fe668f6cb73 in (anonymous namespace)::ScalarExprEmitter::Visit(clang::Expr*) () from /home/delsart/SOFTWARE/root/lib/libCling.so
#18 0x00007fe668f6d5e0 in clang::CodeGen::CodeGenFunction::EmitScalarExpr(clang::Expr const*, bool) () from /home/delsart/SOFTWARE/root/lib/libCling.so
#19 0x00007fe668e4d38a in clang::CodeGen::CodeGenFunction::EmitReturnStmt(clang::ReturnStmt const&) () from /home/delsart/SOFTWARE/root/lib/libCling.so
#20 0x00007fe668e4f57e in clang::CodeGen::CodeGenFunction::EmitStmt(clang::Stmt const*) () from /home/delsart/SOFTWARE/root/lib/libCling.so
#21 0x00007fe668e4f820 in clang::CodeGen::CodeGenFunction::EmitCompoundStmtWithoutScope(clang::CompoundStmt const&, bool, clang::CodeGen::AggValueSlot) () from /home/delsart/SOFTWARE/root/lib/libCling.so
#22 0x00007fe668e689b2 in clang::CodeGen::CodeGenFunction::EmitFunctionBody(clang::CodeGen::FunctionArgList&, clang::Stmt const*) () from /home/delsart/SOFTWARE/root/lib/libCling.so
#23 0x00007fe668e6f0e0 in clang::CodeGen::CodeGenFunction::GenerateCode(clang::GlobalDecl, llvm::Function*, clang::CodeGen::CGFunctionInfo const&) () from /home/delsart/SOFTWARE/root/lib/libCling.so
#24 0x00007fe668e8a9ea in clang::CodeGen::CodeGenModule::EmitGlobalFunctionDefinition(clang::GlobalDecl, llvm::GlobalValue*) () from /home/delsart/SOFTWARE/root/lib/libCling.so
#25 0x00007fe668e8b188 in clang::CodeGen::CodeGenModule::EmitGlobalDefinition(clang::GlobalDecl, llvm::GlobalValue*) () from /home/delsart/SOFTWARE/root/lib/libCling.so
#26 0x00007fe668e8b32e in clang::CodeGen::CodeGenModule::EmitDeferred() () from /home/delsart/SOFTWARE/root/lib/libCling.so
#27 0x00007fe668e8b409 in clang::CodeGen::CodeGenModule::Release() () from /home/delsart/SOFTWARE/root/lib/libCling.so
#28 0x00007fe668bf4965 in cling::IncrementalParser::codeGenTransaction(cling::Transaction*) () from /home/delsart/SOFTWARE/root/lib/libCling.so
#29 0x00007fe668bf459f in cling::IncrementalParser::commitTransaction(llvm::PointerIntPair<cling::Transaction*, 2u, cling::IncrementalParser::EParseResult, llvm::PointerLikeTypeTraits<cling::Transaction*> >) () from /home/delsart/SOFTWARE/root/lib/libCling.so
#30 0x00007fe668bf6845 in cling::IncrementalParser::Compile(llvm::StringRef, cling::CompilationOptions const&) () from /home/delsart/SOFTWARE/root/lib/libCling.so
#31 0x00007fe668bd5db7 in cling::Interpreter::EvaluateInternal(std::string const&, cling::CompilationOptions, cling::Value*, cling::Transaction**) () from /home/delsart/SOFTWARE/root/lib/libCling.so
#32 0x00007fe668bd6095 in cling::Interpreter::process(std::string const&, cling::Value*, cling::Transaction**) () from /home/delsart/SOFTWARE/root/lib/libCling.so
#33 0x00007fe668c3f5db in cling::MetaProcessor::process(char const*, cling::Interpreter::CompilationResult&, cling::Value*) () from /home/delsart/SOFTWARE/root/lib/libCling.so
#34 0x00007fe668ad388d in TCling::ProcessLine(char const*, TInterpreter::EErrorCode*) () from /home/delsart/SOFTWARE/root/lib/libCling.so
#35 0x00007fe66cf6b726 in TApplication::ProcessLine(char const*, bool, int*) () from /home/delsart/SOFTWARE/root/lib/libCore.so
#36 0x00007fe66cb5a6cf in TRint::ProcessLineNr(char const*, char const*, int*) () from /home/delsart/SOFTWARE/root/lib/libRint.so
#37 0x00007fe66cb5a991 in TRint::HandleTermInput() () from /home/delsart/SOFTWARE/root/lib/libRint.so
#38 0x00007fe66d00704d in TUnixSystem::CheckDescriptors() () from /home/delsart/SOFTWARE/root/lib/libCore.so
#39 0x00007fe66d0082ea in TUnixSystem::DispatchOneEvent(bool) () from /home/delsart/SOFTWARE/root/lib/libCore.so
#40 0x00007fe66cf5b4d4 in TSystem::InnerLoop() () from /home/delsart/SOFTWARE/root/lib/libCore.so
#41 0x00007fe66cf5a141 in TSystem::Run() () from /home/delsart/SOFTWARE/root/lib/libCore.so
#42 0x00007fe66cf68d8f in TApplication::Run(bool) () from /home/delsart/SOFTWARE/root/lib/libCore.so
#43 0x00007fe66cb5bdeb in TRint::Run(bool) () from /home/delsart/SOFTWARE/root/lib/libRint.so
#44 0x0000000000401090 in main ()
===========================================================

The code just works if ‘erfdsf’ is replaced by a literal int or a previously defined int.

Is it something we can expect to be fixed in a near future ?

Cheers,

P-A

Hi P-A,

Even better: it’s the near future called the recent past! :wink: I don’t even get there with v6.08:

root [0] class B { public: int f(){ return erfdsf;}};
ROOT_prompt_0:1:35: error: use of undeclared identifier 'erfdsf'
class B { public: int f(){ return erfdsf;}};
                                  ^

Cheers, Axel.

Thanks a lot, I should have upgraded before posting !

Cheers,

P-A

Not a problem, P-A, thanks for reporting!

Axel.