Ok, sorry to be posting so much here in my own thread, but I find that it is relevant information.
In looking at the root 5.20 source tree I find the following default constructor for RooRealVar:
//_____________________________________________________________________________
RooRealVar::RooRealVar() : _error(0), _asymErrLo(0), _asymErrHi(0), _binning(0), _sharedProp(0)
{
// Default constructor
}
In this constructor the RooAbsRealLValue is not explicitly instantiated like in the other constructors? Is this a problem. I would have thought that C++ would have implicitly ran the constructor for the inherited class. The code does not segfault at this point yet. It really goes crazy when you try to set something equal to it. So, when you set something equal to it the operator= is called and if it is just a value it still calls the RooAbsRealLValue::operator= method. Ohh, I think that I might have found the problem…
When the operator= method is called it uses the setVal method which checks to see if it is in a valid range. A chain of method calls eventually calls RooRealVar::getBinning() with no name, since there was not one anyway. Ok, so the getBinning method just bindly returns *_binning at this point which has not been initialized with a default value since the default constructor was used. The setVal() method then tries to dereference this which results in the segfault that I am seeing.
Another stange thing that I see is that the operator= method is not overloaded in the RooRealVar class. If this is the case then is the error not propagated in the copy? It seems from the code that the value of the variable is passed across but not the error. Is this true?
The following is the RooAbsRealLValue::operator= method that is used in the copy which I took from root/roofit/roofitcore/src/RooAbsRealLValue.cxx line 172.
//_____________________________________________________________________________
RooAbsArg& RooAbsRealLValue::operator=(const RooAbsReal& arg)
{
// Assignment operator from other RooAbsReal
return operator=(arg.getVal()) ;
}
It should be noted that when I try to add an explicit RooRealVar::setRange call so that something is there then it still segfaults due to a check on RooAbsRealLValue::getMin from somewhere inside the RooRealVar::getBinning method. Since this call is not explicitly in there I figure that it is coming from the return of the *binning somehow. The following is the gdb backtrace for the case where I create a RooRealVar using the default constructor and then try to explicitly call the setRange method.
GNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
(gdb) run
Starting program: /home/prophecy/Desktop/TMPWORK/BackgroundConsistency/test
[Thread debugging using libthread_db enabled]
[New Thread 0xb56e56d0 (LWP 21111)]
RooFit v2.50 -- Developed by Wouter Verkerke and David Kirkby
Copyright (C) 2000-2008 NIKHEF, University of California & Stanford University
All rights reserved, please read http://roofit.sourceforge.net/license.txt
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb56e56d0 (LWP 21111)]
0xb5924ccb in RooAbsRealLValue::getMin () from /usr/lib/root/libRooFitCore.so.5.20
(gdb) bt
#0 0xb5924ccb in RooAbsRealLValue::getMin () from /usr/lib/root/libRooFitCore.so.5.20
#1 0xb5a1f267 in RooRealVar::getBinning () from /usr/lib/root/libRooFitCore.so.5.20
#2 0xb5a22a7b in RooRealVar::setRange () from /usr/lib/root/libRooFitCore.so.5.20
#3 0x08048d59 in main () at test.cc:12
Justace