TClonesArray of a class, crash after constructor

Hi there,

I’m using TClonesArray to fill in a class holding data, which is then written to a file for analysis. I’ve been frequently encountering crashes when setting the branch for the output file as a TClonesArray holding the class. I’ll post the relevant code below.

I use my code to compile into a dll which is then loaded into root, where I call declare my analysis class (TH_01) and call a member function to do the analysis (TH_01::preprocess). Here is my output.
This problem has been a major issue for me, and has been very hard to understand.

$ root -l
root [0] .L _out/tei_histo_01.dll
FastADCData::FastADCData()
root [1] TH_01 th
root [2] th.preprocess(0,true,true,false,7)
Select OUTPUT file!
C:\0\tei\00
 1 : 11
C:\0\tei\00
 1 : 11.root
Select INPUT!
C:\0\tei\00
 1 : LH_ambe_20120213_150148_00.ddf
Opened OUTPUT: C:\0\tei\00\11.root
mpdTAP
anaHit::anaHit()
anaHit::~anaHit()
fdcTAP
fdcRAW
FastADCData::FastADCData()
Error: Symbol #include is not defined in current scope  (tmpfile)(1)
Error: Symbol exception is not defined in current scope  (tmpfile)(1)
Syntax Error: #include <exception> (tmpfile)(1)
Error: Symbol G__exception is not defined in current scope  (tmpfile)(1)
Error: type G__exception not defined FILE:(tmpfile) LINE:1
(int)0
*** Interpreter error recovered ***
root [3] .q
Warning in <TWinNTSystem::Run>: handle uncaugth exception, terminating

Further inspection when running root.exe under gdb gives the following

...
mpdTAP
anaHit::anaHit()
anaHit::~anaHit()
fdcTAP
fdcRAW
FastADCData::FastADCData()

Program received signal SIGSEGV, Segmentation fault.
0x7757e3c6 in ntdll!LdrWx86FormatVirtualImage ()
   from C:\Windows\system32\ntdll.dll
(gdb) backtrace full
#0  0x7757e3c6 in ntdll!LdrWx86FormatVirtualImage ()
   from C:\Windows\system32\ntdll.dll
No symbol table info available.
#1  0x00000000 in ?? ()
No symbol table info available.
	//inside TH_01::preprocess
	TFile *OUTPUT;
	int ret;
	{
		OUTPUT = new TFile(fname,"UPDATE");
		TTree *EVENT = 0;
		...
		//Initialize Clones array for output TTree
		TClonesArray *mpdTAP = new TClonesArray("anaHit");
		TClonesArray *fdcTAP = new TClonesArray("anaHit");
		TClonesArray *fdcRAW = new TClonesArray("FastADCData"); // <-- Offending TClonesArray
		OUTPUT->cd();
		EVENT = (TTree*)OUTPUT->Get("EVENT");

		std::cerr << "mpdTAP\n";
		if (output_type&0x1) EVENT->Branch("mpdTAP",&mpdTAP);
		std::cerr << "fdcTAP\n";
		if (output_type&0x2) EVENT->Branch("fdcTAP",&fdcTAP);
		std::cerr << "fdcRAW\n";
		if (output_type&0x4) EVENT->Branch("fdcRAW",&fdcRAW);
		std::cerr << "after\n";
		...
		Analysis stuff
		...
		return ret;
	}

The FastADCData class isn’t complicated, it is just basic constructors, an empty destructor and various analysis methods.

I’m asking if there are precautions one should take when using TClonesArrays like this, or nuances in using dll’s. I notice that FastADCData::FastADCData() is called right after loading the dll which I don’t understand, it’s most likely related to the issue. Any ideas or suggestions on better debugging are appreciated.

Hi,

On windows the code is compiled (by default) with the Microsoft Compiler and you might get better information using Visual Studio’s debugger (the stack trace shown by gdb here is uninformative).

TClonesArray *fdcRAW = new TClonesArray("FastADCData"); // <-- Offending TClonesArrayHow did you determine it was the offending line?

EVENT = (TTree*)OUTPUT->Get("EVENT"); if (output_type&0x1) EVENT->Branch("mpdTAP",&mpdTAP); This is extremely unlikely to be what you meant. This line adds a new branch with no data to the TTree that was just read from the file. Maybe you meant: EVENT = (TTree*)OUTPUT->Get("EVENT"); if (output_type&0x1) EVENT->SetBranchAddress("mpdTAP",&mpdTAP);
The code as shown in the post will always be empty.

One of the think that you need to make sure of is that you have loaded a dictionary for all the classes held by a TClonesArray.

Cheers,
Philippe.

Hi Philippe,

I was too conservative in leaving out code to try and simplify the issue… Here is the entire section up to where it is crashing, and the end portion.

int TH_01::preprocess(int option, bool USE_FADC, bool USE_PADC, bool USE_TDC, int output_type, int cmap){

	>>Initializing a bunch of simple variables.<<

	TFile *OUTPUT;

	int				ret;
	{
		>>A big portion handling a windows dialog for getting the file name, fname<<

		OUTPUT = new TFile(fname,"UPDATE");
		printf("Opened OUTPUT: %s\n",fname);
		
		//-------------------------------------
		//--- INITIALIZE (REMOVE FROM .cpp! ---
		//-------------------------------------
		//Fill TTree containing runwide data
		//////////////////////Define Runwide TTree////////////////////////////////
		TTree *EVENT = 0;
		int numd;	
		numd = kchan;
		if (kchan < kchan) numd = kchan;
		TTree* RUN_A = (TTree*)OUTPUT->Get("RUN");
		if(RUN_A){
			RUN_A->SetBranchAddress("numd",&numd);	    
			RUN_A->SetBranchAddress("Init_AbsTime",&Init_AbsTime);
			RUN_A->SetBranchAddress("Total_Time",&Total_Time);
			RUN_A->SetBranchAddress("Num_Raw_Data",&Num_Raw_Data);
			RUN_A->SetBranchAddress("Trigger_Scaler",&tscaler);
			RUN_A->SetBranchAddress("Coincidence_Scaler",&cscaler);
			RUN_A->SetBranchAddress("Neutron_Scaler",&nscaler);
			RUN_A->SetBranchAddress("Total_Deadtime",&Total_Deadtime);
			printf("6\n");
			RUN_A->GetEntry(0);
		}
		printf("3\n");
		//OUTPUT->cd();
		TTree* RUN_B = new TTree("RUN","RUN");
		//RUN_B->SetDirectory(0);
		RUN_B->Branch("numd",&numd,"numd/I");	    
		RUN_B->Branch("Init_AbsTime",&Init_AbsTime,"Init_AbsTime/D");
		RUN_B->Branch("Total_Time",&Total_Time,"Total_Time/F");
		RUN_B->Branch("Num_Raw_Data",&Num_Raw_Data,"Num_Raw_Data/I");
		RUN_B->Branch("Trigger_Scaler",&tscaler,"tscaler/i");
		RUN_B->Branch("Coincidence_Scaler",&cscaler,"cscaler/i");
		RUN_B->Branch("Neutron_Scaler",&nscaler,"nscaler/i");
		RUN_B->Branch("Total_Deadtime",&Total_Deadtime,"Total_Deadtime/F");
		//Initialize Clones array for output TTree
		TClonesArray *mpdTAP = new TClonesArray("anaHit");
		TClonesArray *fdcTAP = new TClonesArray("anaHit");
		TClonesArray *fdcRAW = new TClonesArray("FastADCData");
		printf("4\n");
		////////////////////////Define Data TTrees////////////////////////////////
		//OUTPUT->cd();
		EVENT = (TTree*)OUTPUT->Get("EVENT");
		//EVENT->SetDirectory(OUTPUT);
		//EVENT->SetDirectory(0);
		if(EVENT){
			printf("A\n");
			EVENT->SetBranchAddress("event_id",&event_id);
			EVENT->SetBranchAddress("tscaler",&tscaler);
			EVENT->SetBranchAddress("angle_P",&angle_P);
			EVENT->SetBranchAddress("runTime",&runTime);
			EVENT->SetBranchAddress("liveTime",&liveTime);
			EVENT->SetBranchAddress("Interevent_Time",&Interevent_Time);
			EVENT->SetBranchAddress("angle_LH",&angle_LH);
			EVENT->SetBranchAddress("angle_time",&angle_time);
			std::cerr << "mpdTAP\n";
			if (output_type&0x1) EVENT->SetBranchAddress("mpdTAP",&mpdTAP);
			std::cerr << "fdcTAP\n";
			if (output_type&0x2) EVENT->SetBranchAddress("fdcTAP",&fdcTAP);
			std::cerr << "fdcRAW\n";
			if (output_type&0x4) EVENT->SetBranchAddress("fdcRAW",&fdcRAW);
			std::cerr << "Loaded\n";
			Long64_t n = EVENT->GetEntries();
			EVENT->GetEntry(n-1);
			printf("5\n");
		}else{
			printf("6\n");
			EVENT = new TTree("EVENT","EVENT");
			EVENT->Branch("event_id",&event_id,"event_id/I");
			EVENT->Branch("tscaler",&tscaler,"tscaler/i");
			EVENT->Branch("angle_P",&angle_P,"angle_P/F");
			EVENT->Branch("runTime",&runTime,"runTime/D");
			EVENT->Branch("liveTime",&liveTime,"liveTime/D");
			EVENT->Branch("Interevent_Time",&Interevent_Time,"Interevent_Time/D");
			EVENT->Branch("angle_LH",&angle_LH,"angle_LH/F");
			EVENT->Branch("angle_time",&angle_time,"angle_time/F");
			printf("mpdTAP\n");
			if (output_type&0x1) EVENT->Branch("mpdTAP",&mpdTAP);
			std::cerr << "fdcTAP\n";
			if (output_type&0x2) EVENT->Branch("fdcTAP",&fdcTAP);
			std::cerr << "fdcRAW\n";
			if (output_type&0x4) EVENT->Branch("fdcRAW",&fdcRAW);
			std::cerr << "after\n";
		}
		if (ecal && detconf_header) ecal->set_adc_cuts(detconf_header,Energy_Cut_Low,Energy_Cut_High);
	
		... Lots of code ommitted here		
		//--- process input files ---
		... After the omitted code

		Total_Time = AbsTime-Init_AbsTime;
		RUN_B->Fill();
		OUTPUT->Write();
		delete RUN_B;
		delete RUN_A;
		delete EVENT;
BAIL:		
		OUTPUT->Close();
		delete fdcRAW;
		delete fdcTAP;
		delete mpdTAP;
		delete OUTPUT;
	}
	return ret;
}

Okay, so I compile this with a bunch of other classes in msys with the msvc compiler version 7.1 and a makefile including all of my other classes. I’m using root 5.32 for msvc 7.1

I was able to get a more useful output with gdb, the warnings in the beginning appear when I have a windows dialog popup, but they are fine. I have it printing when the anaHit and fdcDataRaw classes are constructed and deconstructed.

root [0] .L _out/tei_histo_01.dll
FastADCData::FastADCData()
root [1] TH_01 th
root [2] th.preprocess(0,true,true,false,7)

Select OUTPUT file!
[New Thread 3376.0xf7c]
[New Thread 3376.0xcd8]
[New Thread 3376.0x414]
[New Thread 3376.0x15f8]
[New Thread 3376.0x978]
[New Thread 3376.0x1e38]
[New Thread 3376.0x1edc]
[New Thread 3376.0x448]
[New Thread 3376.0x1448]
[New Thread 3376.0xc20]
[New Thread 3376.0x140c]
warning: SNACNP::NPGetCaps::WNNC_NET_TYPE

warning: SNACNP::NPGetCaps::WNNC_USER

warning: SNACNP::NPGetCaps::WNNC_CONNECTION

warning: SNACNP::NPGetCaps::WNNC_ENUMERATION

warning: SNACNP::NPGetCaps::WNNC_ADMIN

warning: SNACNP::NPGetCaps::WNNC_DIALOG

warning: SNACNP::NPGetCaps::WNNC_START

[New Thread 3376.0x1314]
BFD: C:\Windows\SysWOW64\WMVCORE.DLL: Warning: Ignoring section flag IMAGE_SCN_M
EM_NOT_PAGED in section .reloc
[New Thread 3376.0x7cc]
[New Thread 3376.0x880]
C:\0\tei\00
 1 : aergaa
C:\0\tei\00
 1 : aergaa.root

Select INPUT!
[New Thread 3376.0xb44]
[New Thread 3376.0x8d4]
BFD: C:\Windows\SysWOW64\WMVCORE.DLL: Warning: Ignoring section flag IMAGE_SCN_M
EM_NOT_PAGED in section .reloc
C:\0\tei\00
 1 : LH_ambe_20120213_150148_00.ddf
1
Opened OUTPUT: C:\0\tei\00\aergaa.root
3
4
6
mpdTAP
anaHit::anaHit()
anaHit::~anaHit()
fdcTAP
fdcRAW
FastADCData::FastADCData()
warning: HEAP[root.exe]:
warning: Invalid address specified to RtlValidateHeap( 00C60000, 06680E98 )


Program received signal SIGTRAP, Trace/breakpoint trap.
0x77620725 in ntdll!TpWaitForAlpcCompletion ()
   from C:\Windows\system32\ntdll.dll
(gdb) backtrace
#0  0x77620725 in ntdll!TpWaitForAlpcCompletion ()
   from C:\Windows\system32\ntdll.dll
#1  0x00172a44 in ?? ()
#2  0x775e295a in ntdll!RtlSelfRelativeToAbsoluteSD2 ()
   from C:\Windows\system32\ntdll.dll
#3  0x06680e90 in ?? ()
#4  0x775b1997 in wcspbrk () from C:\Windows\system32\ntdll.dll
#5  0x00c60000 in ?? ()
#6  0x76e84bf9 in KERNELBASE!ImpersonateAnonymousToken ()
   from C:\Windows\syswow64\KernelBase.dll
#7  0x00a0ad68 in MSVCR71D!_CrtIsValidPointer ()
   from c:\slbuild\msvc71\dll\msvcr71d.dll
#8  0x00a0a122 in free_dbg () from c:\slbuild\msvc71\dll\msvcr71d.dll
#9  0x00a09ff1 in free_dbg () from c:\slbuild\msvc71\dll\msvcr71d.dll
#10 0x00a3c5fa in MSVCR71D!??2@YAPAXIHPBDH@Z ()
   from c:\slbuild\msvc71\dll\msvcr71d.dll
#11 0x100c366b in libCore!?AdoptCollectionProxyInfo@TGenericClassInfo@ROOT@@QAEX
PAVTCollectionProxyInfo@2@@Z ()
   from c:\slbuild\usr\local\root532\bin\libCore.dll
#12 0x0571c5db in tei_histo_01!G__cpp_setupFastADCData_dict ()
   from c:\1\shg\hg_js\cpp\tei\_out\tei_histo_01.dll
#13 0x0571c60a in tei_histo_01!G__cpp_setupFastADCData_dict ()
   from c:\1\shg\hg_js\cpp\tei\_out\tei_histo_01.dll
#14 0x100472c7 in libCore!?LoadClass@TROOT@@QBEPAVTClass@@PBD_N@Z ()
   from c:\slbuild\usr\local\root532\bin\libCore.dll
#15 0x100accad in libCore!?GetClass@TClass@@SAPAV1@PBD_N1@Z ()
   from c:\slbuild\usr\local\root532\bin\libCore.dll
#16 0x100a635a in libCore!?Inspect@TBuildRealData@@UAEXPAVTClass@@PBD1PBX@Z ()
   from c:\slbuild\usr\local\root532\bin\libCore.dll
#17 0x05717e39 in tei_histo_01!?ShowMembers@FastADCData@@UAEXAAVTMemberInspector
@@@Z () from c:\1\shg\hg_js\cpp\tei\_out\tei_histo_01.dll
#18 0x100aac7e in libCore!?CallShowMembers@TClass@@QBE_NPAXAAVTMemberInspector@@
H@Z () from c:\slbuild\usr\local\root532\bin\libCore.dll
#19 0x100aa577 in libCore!?BuildRealData@TClass@@QAEXPAX_N@Z ()
   from c:\slbuild\usr\local\root532\bin\libCore.dll
#20 0x063ca1f9 in libTree!?BuildStreamerInfo@TTree@@QAEPAVTStreamerInfo@@PAVTCla
ss@@PAX_N@Z () from c:\slbuild\usr\local\root532\bin\libTree.dll
#21 0x06394825 in libTree!?Unroll@TBranchElement@@IAEHPBDPAVTClass@@1PADHHH@Z
    () from c:\slbuild\usr\local\root532\bin\libTree.dll
#22 0x063889f7 in libTree!?Init@TBranchElement@@IAEXPAVTTree@@PAVTBranch@@PBDPAV
TClonesArray@@HHH@Z () from c:\slbuild\usr\local\root532\bin\libTree.dll
#23 0x06388334 in libTree!??0TBranchElement@@QAE@PAVTTree@@PBDPAVTClonesArray@@H
HH@Z () from c:\slbuild\usr\local\root532\bin\libTree.dll
#24 0x063c9a80 in libTree!?BronchExec@TTree@@MAEPAVTBranch@@PBD0PAX_NHH@Z ()
   from c:\slbuild\usr\local\root532\bin\libTree.dll
#25 0x063c937b in libTree!?Bronch@TTree@@UAEPAVTBranch@@PBD0PAXHH@Z ()
   from c:\slbuild\usr\local\root532\bin\libTree.dll
#26 0x063c85f2 in libTree!?Branch@TTree@@UAEPAVTBranch@@PBD0PAXHH@Z ()
   from c:\slbuild\usr\local\root532\bin\libTree.dll
#27 0x063c7834 in libTree!?BranchImp@TTree@@MAEPAVTBranch@@PBDPAVTClass@@PAXHH@Z
 () from c:\slbuild\usr\local\root532\bin\libTree.dll
#28 0x05681183 in tei_histo_01!??_FFastADCData@@QAEXXZ ()
   from c:\1\shg\hg_js\cpp\tei\_out\tei_histo_01.dll
#29 0x0567c9da in tei_histo_01!??_FFastADCData@@QAEXXZ ()
   from c:\1\shg\hg_js\cpp\tei\_out\tei_histo_01.dll
#30 0x05688d86 in tei_histo_01!G__cpp_setup_tagtabletei_histo_01_dict ()
   from c:\1\shg\hg_js\cpp\tei\_out\tei_histo_01.dll
#31 0x0048b553 in libCint!?Next@G__IncludePathInfo@Cint@@QAEHXZ ()
   from c:\slbuild\usr\local\root532\bin\libCint.dll
#32 0x00531833 in libCint!G__check_setup_version ()
   from c:\slbuild\usr\local\root532\bin\libCint.dll
#33 0x00531e15 in libCint!G__check_setup_version ()
   from c:\slbuild\usr\local\root532\bin\libCint.dll
#34 0x00514576 in libCint!G__compile_bytecode ()
   from c:\slbuild\usr\local\root532\bin\libCint.dll
#35 0x004fdce3 in libCint!G__getfunction ()
   from c:\slbuild\usr\local\root532\bin\libCint.dll
#36 0x005d967c in libCint!G__value_get_tagnum ()
   from c:\slbuild\usr\local\root532\bin\libCint.dll
#37 0x005cf167 in libCint!G__value_get_tagnum ()
   from c:\slbuild\usr\local\root532\bin\libCint.dll
#38 0x004f231b in libCint!G__genericerror ()
   from c:\slbuild\usr\local\root532\bin\libCint.dll
#39 0x004ef9f9 in libCint!G__genericerror ()
   from c:\slbuild\usr\local\root532\bin\libCint.dll
#40 0x0055de26 in libCint!G__Longdoubleref ()
   from c:\slbuild\usr\local\root532\bin\libCint.dll
#41 0x0055b8af in libCint!G__Longdoubleref ()
   from c:\slbuild\usr\local\root532\bin\libCint.dll
#42 0x004cfbc4 in libCint!G__exec_tempfile_fp ()
   from c:\slbuild\usr\local\root532\bin\libCint.dll
#43 0x004cf757 in libCint!G__exec_tempfile_fp ()
   from c:\slbuild\usr\local\root532\bin\libCint.dll
#44 0x0056d925 in libCint!G__process_cmd ()
   from c:\slbuild\usr\local\root532\bin\libCint.dll
#45 0x10096e6e in libCore!?ProcessLine@TCint@@UAEJPBDPAW4EErrorCode@TInterpreter
@@@Z () from c:\slbuild\usr\local\root532\bin\libCore.dll
#46 0x1000713b in libCore!?ProcessLine@TApplication@@UAEJPBD_NPAH@Z ()
   from c:\slbuild\usr\local\root532\bin\libCore.dll
#47 0x001c290a in libRint!?HandleTermInput@TRint@@UAE_NXZ ()
   from c:\slbuild\usr\local\root532\bin\libRint.dll
#48 0x100dbf62 in libCore!?DispatchOneEvent@TWinNTSystem@@UAEX_N@Z ()
   from c:\slbuild\usr\local\root532\bin\libCore.dll
#49 0x1005bd6c in libCore!?InnerLoop@TSystem@@UAEXXZ ()
   from c:\slbuild\usr\local\root532\bin\libCore.dll
#50 0x1005bbef in libCore!?Run@TSystem@@UAEXXZ ()
   from c:\slbuild\usr\local\root532\bin\libCore.dll
#51 0x10007ae2 in libCore!?Run@TApplication@@UAEX_N@Z ()
   from c:\slbuild\usr\local\root532\bin\libCore.dll
#52 0x001c23e9 in libRint!?Run@TRint@@UAEX_N@Z ()
   from c:\slbuild\usr\local\root532\bin\libRint.dll
#53 0x00401082 in ?? ()
#54 0x0040322c in ?? ()
#55 0x77003677 in KERNEL32!BasepMapModuleHandle ()
   from C:\Windows\syswow64\kernel32.dll
#56 0x7efde000 in ?? ()
#57 0x77589f42 in ntdll!RtlpNtSetValueKey ()
   from C:\Windows\system32\ntdll.dll
#58 0x7efde000 in ?? ()
#59 0x77589f15 in ntdll!RtlpNtSetValueKey ()
   from C:\Windows\system32\ntdll.dll
#60 0x00403100 in ?? ()
#61 0x00000000 in ?? ()
(gdb)

Yes, we have dictionaries created and loaded for each class.

Hi,

The stack trace:#11 0x100c366b in libCore!?AdoptCollectionProxyInfo@TGenericClassInfo@ROOT@@QAEX PAVTCollectionProxyInfo@2@@Z () from c:\slbuild\usr\local\root532\bin\libCore.dll #12 0x0571c5db in tei_histo_01!G__cpp_setupFastADCData_dict () from c:\1\shg\hg_js\cpp\tei\_out\tei_histo_01.dll is suspicious as G__cpp_setupFastADCData_dict should not (can not) call TGenericClassInfo::AdoptCollectionProxyInfo so either gdb is inaccurate or there is a build problem (i.e. 2 object file are build and linked together but do not use the same definition/layout for a class or another.

I recommend recompile all your source files and library from scratch. If this does not solve the problem, please send us a minimal, complete example reproducing the problem and we will take a look.

Cheers,
Philippe.