Segmentation violation when editing global variable in compiled macro

Hi all,
I have trouble with a strange situation.
The following code:

#include <iostream>
using namespace std;
float a;
int test(){
        a=1.;
        cout<<a<<endl;
        return 0;
}

works when runned both as

root test.C

and compiled as

root test.C+

On the other end the following code:

#include <iostream>
using namespace std;
float step;
int test(){
        step=1.;
        cout<<step<<endl;
        return 0;
}

works when runned as

root test.C

both NOT when compiled as

root test.C+

(it works if compiled with g++ after the inclusion of int main(){return test();})

Is step some kind of protected keyword? How so? The workaround is as simple as “don’t use a global variable called step”, but I’d like to understand better what is wrong.

Alberto

Looks like it’s related to ROOT-8036.

Yes, this is the linker deciding to re-use the existing step symbol (from regex.h) for your float variable. This is actually worked around in the interpreter - which is why with root test.C is works. But as root test.C+ creates a shared library (test_C.so) and loads it into ROOT, the linker / dynamic loader decide what to do, and we have no means of interfering…

You can reproduce this outside of ROOT using:

// step_shlib.cxx:
float step;
int initMe() {
  step = 42.;
}

int trigger = initMe();
// step_main.cxx
#include <dlfcn.h>

extern "C" int printf(const char*,...);

int main() {
  dlopen("libstep_shlib.so", RTLD_NOW);
  printf("%s\n", dlerror());
  return 0;
}

and then run

g++ -g -shared -fPIC step_shlib.cxx -o libstep_shlib.so
g++ -g step_main.cxx -ldl
LD_LIBRARY_PATH=. ./a.out 

results in

./a.o terminated by signal SIGSEGV (Address boundary error)

with gdb pointing to

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7ff469d in initMe () at step_shlib.cxx:4
4	  step = 42.;

That’s not the first time we meet it (see some examples below).
I can only repeat what had already been asked in one of these old “problem reports” … could you, please, prepare a list of “known” global identifier clashes.

Hi Wile_E,

These are different issues; only the pi case is the same.

The important part is that for interactive use (i.e. the pi case you linked!) this is fixed! What we cannot fix is Linux’s dynamic loader: if you create a shared library and load it into a program that uses the same symbol name already then bad things happen. Independently of ROOT. And that’s what this post here was about.

The others are redefinition errors, i.e. C++ syntax errors not linker errors. That’s because of using namespace std; - and here we at least issue a helpful error message that allows people to pick a different name. Given that I don’t find that list of “known bad names” terribly helpful - it’s basically “all names in namespace std::”.

Axel.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.