Hi, I’m trying to understand how are symbols resolved during the link phase of scripts.
I’m on OSX, using root 6 form brew:
$ brew info root6
homebrew/science/root6: stable 6.06.06 (bottled), HEAD
Here is the code I’m using:
// 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 link-symbols link-symbols.cc
#include <vector>
#include <exception>
#include <sstream>
#include <iostream>
#include <fstream>
#include "cling/Interpreter/Interpreter.h"
cling::Interpreter* interpreter(nullptr);
const char * script =
"namespace script { \n"
" \n"
" struct unresolved { \n"
" unresolved(); \n"
" ~unresolved(); \n"
" \n"
" int value(); \n"
" }; \n"
" \n"
" extern \"C\" int __main() { \n"
" return unresolved().value(); \n"
" } \n"
" \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());
}
int main() {
setup();
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("__main");
printf("GOT %p for %s\n", ptr, "__main");
if(!ptr) {
exit(-1);
}
auto func = reinterpret_cast<int (*)()>(ptr);
auto ret = func();
printf("GOT %d result\n", ret);
return 0;
}
struct unresolved in the script is valid c++ code, but its implementation is not defined.
I was expecting some link-time errors while trying to compile/execute the script, but instead I was random-like output:
$ ./link-symbols
declare OK.
GOT 0x10e055000 for __main
GOT 210373381 result
$ ./link-symbols
declare OK.
GOT 0x1105bb000 for __main
GOT 247028485 result
$ ./link-symbols
declare OK.
GOT 0x105271000 for __main
GOT 55520005 result
What is finally executed ? Is it possible to get a failure at some point when running this script ?
Thanks in advance for your help!
Vincent
(edit: script cleanup)