Segfault Casting from RooRealProxy to Double_t

Dear RootTalkers,

I have a very curious problem. I am using Root v5.28.00a on 64-bit slc5. It comes with RooFit v3.14

Internal to my PDF I keep RooRealProxy(s) of the variables to be used, which are passed in as RooAbsReal& at instantiation time.
When I cast from a RooRealProxy to a double in evaluate I get a segfault.
If I perform the cast inside the constructor I do not get a segfault.

I have tested with and without class def, and several different methods of casting. Casting RooCategoryProxy to Int_t, seems not to suffer this problem.

I have written a simple h/cpp which demonstrates this (attached).

What’s going wrong?

root [0] test=RooRealVar("test","test",0.3,0,0.5)
(class RooRealVar)465232304
root [1] 
root [1] frame2=test.frame()
(const class RooPlot*)0x1baa4d50
root [2] 
root [2] .L src/RooTest.cpp++
root [3] 
root [3] pdt=RooTest("atest","btest",test)
(class RooTest)467252080
root [4] 
root [4] frame2=pdt.plotOn(frame2); frame2.Draw();

 *** Break *** segmentation violation
.....

#5  0x00002afdfd3f208e in RooTest::evaluate() const ()
   from /___snip___/src/RooTest_cpp.so
#6  0x00002b81e7ba9896 in RooAbsPdf::getVal(RooArgSet const*) const ()
   from /___snip___/ROOT/5.28.00a/x86_64-slc5-gcc43-opt/root/lib/libRooFitCore.so
#7  0x00002b81e7cf932c in RooRealIntegral::RooRealIntegral(char const*, char const*, RooAbsReal const&, RooArgSet const&, RooArgSet const*, RooNumIntConfig const*, char const*) ()
   from /___snip___/ROOT/5.28.00a/x86_64-slc5-gcc43-opt/root/lib/libRooFitCore.so
#8  0x00002b81e7bb622d in RooAbsReal::createIntObj(RooArgSet const&, RooArgSet const*, RooNumIntConfig const*, char const*) const ()

Thanks,

Rob Lambert
RooTest.cpp (1.52 KB)
RooTest.h (1.39 KB)

Dear All,

I have received no response. Are there really no experts willing to help?
This is a bottleneck in our analysis.

We can confirm that several collaborators see the same problem in different environments, and compiling into c++ (g++) rather than going through cint at all shows the same behavior.

Oddly this is exactly the same construction for a PDF as exists elsewhere in the Root code, such as RooGaussian (on which this simple example is modeled). A segfault suggests a memory cleanup issue, but in the example, there are no variables which leave the scope.

Again I re-iterate that several different methods and placement of the casting to double, either implicit or explicit, all just provoke a segfault in those locations.

Thanks,

Rob

Hi Rob,

I have located your problem, which might be considered a feature in RooRealProxy since it doesn’t warn you that you’re doing something wrong.

In your copy constructor the following line:
test(“test”,“test”,this,other.test) // (const char*, const char*,RooAbsArg*,RooAbsReal&)
Are what cause your crash. The reason is that this particular overload of the RooRealProxy constructor expects a RooAbsReal as the last argument, (I am really incredibly surprised that this ever worked, but such is the magic of CINT.) so what happened is when it tried to cast other.test to a RooAbsReal, created a NULL pointer and you know the rest of the story… The list of commands you supplied shouldn’t ever compile…

If you instead use the RooRealProxy constructor:
test(“test”,this,other.test) // (const char*, RooAbsArg*, const RooRealProxy&)
As you can see this expects a RooRealProxy as the final argument and doesn’t crash.

Best,
Lindsey

Actually, it makes a bit of sense that the class is able to compile.

The version of the copy constructor you were actually calling expects:

(const char*, const char*, RooAbsArg*, Bool_t, Bool_t,Bool_t)

With the last three bools having default values, so the other.test was casting to double which casted to bool, so that’s all fine. This particular RooRealProxy constructor does not take a RooAbsReal that it is proxy for and this must be set by hand, which is why you were getting the NULL pointer that later caused the crash…

-Lindsey

Lindsay, you life saver!

I never suspected the copy constructor!

Eventually I tried valgrind and gdb, but neither of them really showed me something I didn’t already know… after all, there was no memory leak, and at some point I magically had a class with a null pointer which I couldn’t work out where it came from.

Thanks for the help!

Rob Lambert