Cannot unload transaction

Dear Cling community,

We are using Cling in our project and we’re loving it so far, this is an amazing piece of work.
Many thanks for that!

What we are trying to achieve is a program that compiles and executes small scripts based on a larger library.
So far it’s working pretty well when we don’t “unload” the transaction after each execution.

Here is a small snippet that reproduce the problem :

[code]
#include

#include “cling/Interpreter/Interpreter.h”

int main() {
const char* args[] = { “test-cling”, “-I…/cling/src/tools/cling/include”, “-std=c++14” };
cling::Interpreter interp(3, args, “/usr/local/etc/root/cling/”);

interp.loadFile(“iostream”);

{
std::string scriptSrc1 = “void myFunction1() { std::cout << “Hello 1” << std::endl; }”;
if (interp.declare(scriptSrc1) != cling::Interpreter::CompilationResult::kSuccess) {
std::cout << “Declaration Failed” << std::endl;
return -1;
}
interp.unload(1); // it works properly if you comment this line.
}

std::cout << “Declared 1” << std::endl;

{
std::string scriptSrc1 = “void myFunction2() { std::cout << “Hello 2” << std::endl; }”;
if (interp.declare(scriptSrc1) != cling::Interpreter::CompilationResult::kSuccess) {
std::cout << “Declaration Failed” << std::endl;
return -1;
}
interp.unload(1);
}

std::cout << “Declared 2” << std::endl;
return 0;
}[/code]

Our compilation command line is :

g++ -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS  -std=c++14 -Wall -L$(brew --prefix root6)/lib/root -lCling test-cling.cc

And we’re using Root version 6.04.10.

Are we missing something?
Is there any way to achieve that properly?

Many thanks in advance for your help!

Best regards,

Yves

Hi Ives,

Thanks for letting us know. We are aware of some unloading issues; this is one of the trickiest parts for a compiler library…

Which platform are we talking about here? Which GCC version, which OS?

Cheers, Axel.

Hi Axel,

Thanks for your quick reply.

Here are the missing info (sorry about that) :

GCC Version (Clang 3.7) :

$ g++ -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.0.0 (clang-700.1.76)
Target: x86_64-apple-darwin15.0.0
Thread model: posix

OS Version (MacOSX El Capitan) :

$ system_profiler SPSoftwareDataType
Software:

    System Software Overview:

      System Version: OS X 10.11.1 (15B42)
      Kernel Version: Darwin 15.0.0

I’m also experimenting on Ubuntu 14.04 and Alpine (but I have a lot of trouble compiling ROOT with Musl, I’m currently stalled on that front).

Many thanks again for your help and don’t hesitate to let me know how I can help, I’d be more than happy to contribute on that.

Cheers,

Yves

Hi,

To use cling all you need is (our branch of) llvm, clang and cling, see root.cern.ch/cling-build-instructions - you shouldn’t have to build ROOT.

I have created sft.its.cern.ch/jira/browse/ROOT-7835 to track your bug report. You can subscribe to that to be informed once it’s solved. Thanks for reporting!

The unloading is a really tricky part. I appreciate your offer to help - but while you are certainly welcome to debug this you might be better off picking a different area of contribution :wink:

Cheers, Axel.

Thank you very much for the quick update.

I cannot subscribe to the JIRA because I don’t have an account.
Is there any way I can create one?

Also do you have any idea how much time this could take to fix?
(a rough estimate would be prefect because we need to decide wether we can use Cling or not, and this issue is a major blocker as you can imagine)

Is there any API to unload all the symbols in a given namespace?
That could help us a lot in the meantime.

Many thanks in advance,

Best regards,

Yves

Hi Yves,

You can get an account here: account.cern.ch/account/Externals/

I cannot give an estimate; I can tell you that this is one of the more pressing items on my list - we have several reports about the failure to unload iostream. I (or a colleague of mine) might be able to have a look still in December.

We are currently setting up a mechanism to chain interpreters; i.e. have a first one, create a second one that adds knowledge on top of the first one. You can then destruct the second one without affecting the first one. It’s basically a stack (of tree) of interpreters, each extending the previous. Each interpreter is currently (not yet optimized) 50ms and 500kB. Would that be an option? I’d expect this to arrive in the master within a few weeks - either before Christmas or soon after.

Cheers, Axel.

Thank you very much, I’ve been able to subscribe to the issue.

Also, yes I think that your interpreters chain could be an option indeed.
We can combine that with an other mechanism that would “recycle” the interpreter only upon specific event (after some time and/or number of compilations).
Do you see any issue with a such use?

Again, don’t hesitate to contact me if you need help to work on this or to test/debug it, I’d be very happy to help.

Cheers,

Y.

Hi Yves,

That might work. Note that there is no knowledge sharing from prior interpreters to later ones, nor between children of an interpreter. Not sure whether that matches your use case.

Thanks for your offer to help our with the “tiered” interpreters - it’s actually fairly probable that I’ll come back to you on that!

Cheers, Axel.

Perfect, let me know.

Would that make sense to work on a library that would have only the interpreter?

Basically what we need is just a header file and a library with an API that looks like that :

Cheers,

Y.

Hi Yves,

2x yes:

  • you can use just cling instead of all of ROOT
  • the interpreter chaining is likely the perfect / more stable solution for you.

Cheers, Axel.