diff --git a/src/libraries/DANA/JExceptionDataFormat.h b/src/libraries/DANA/JExceptionDataFormat.h new file mode 100644 index 000000000..6ade4f8df --- /dev/null +++ b/src/libraries/DANA/JExceptionDataFormat.h @@ -0,0 +1,30 @@ +// $Id$ +// +// File: JExceptionDataFormat.h +// Created: Tue Mar 6 15:57:29 EST 2018 +// Creator: davidl (on Linux gluon119.jlab.org 2.6.32-642.3.1.el6.x86_64 x86_64) +// + +#ifndef _JExceptionDataFormat_ +#define _JExceptionDataFormat_ + +#include +#include + +/// This is a subclass of JException that is used to indicate a +/// parsing error. This was motivated by hdmon needing to catch +/// this specific type of error and set an alarm. hdmon is used +/// for online monitoring and the source is kept in subversion. + +class JExceptionDataFormat: public JException{ + public: + JExceptionDataFormat(const std::string &txt):JException(txt){} + JExceptionDataFormat(const std::string &txt, const char *file, int line):JException(txt, file, line){} + virtual ~JExceptionDataFormat(){} + + protected: + +}; + +#endif // _JExceptionDataFormat_ + diff --git a/src/libraries/DAQ/DEVIOWorkerThread.cc b/src/libraries/DAQ/DEVIOWorkerThread.cc index cfa18ec39..ea79bd4fa 100644 --- a/src/libraries/DAQ/DEVIOWorkerThread.cc +++ b/src/libraries/DAQ/DEVIOWorkerThread.cc @@ -12,6 +12,7 @@ #include "LinkAssociations.h" #include +#include using namespace std; using namespace std::chrono; @@ -110,12 +111,21 @@ void DEVIOWorkerThread::Run(void) if( !current_parsed_events.empty() ) PublishEvents(); + } catch( JExceptionDataFormat &e ){ + for(auto pe : parsed_event_pool) delete pe; // delete all parsed events any any objects they hold + parsed_event_pool.clear(); + current_parsed_events.clear(); // (these are also in parsed_event_pool so were already deleted) + jerr << "Data format error exception caught" << endl; + jerr << "Stack trace follows:" << endl; + jerr << e.getStackTrace() << endl; + jerr << e.what() << endl; + japp->Quit(10); } catch (exception &e) { jerr << e.what() << endl; for(auto pe : parsed_event_pool) delete pe; // delete all parsed events any any objects they hold parsed_event_pool.clear(); current_parsed_events.clear(); // (these are also in parsed_event_pool so were already deleted) - //exit(-1); + japp->Quit(-1); } // Reset and mark us as available for use @@ -407,6 +417,7 @@ void DEVIOWorkerThread::ParseEPICSbank(uint32_t* &iptr, uint32_t *iend) // Unknown tag. Bail _DBG_ << "Unknown tag 0x" << hex << tag << dec << " in EPICS event!" < bank_len){ stringstream ss; ss << "BOR: Size of bank doesn't match amount of data given (" << borevent_len << " > " << bank_len << ")"; - throw JException(ss.str(), __FILE__, __LINE__); + throw JExceptionDataFormat(ss.str(), __FILE__, __LINE__); } iend = &iptr[borevent_len]; // in case they give us too much data! @@ -477,7 +488,7 @@ void DEVIOWorkerThread::ParseBORbank(uint32_t* &iptr, uint32_t *iend) if(bor_header != 0x700e01){ stringstream ss; ss << "Bad BOR header: 0x" << hex << bor_header; - throw JException(ss.str(), __FILE__, __LINE__); + throw JExceptionDataFormat(ss.str(), __FILE__, __LINE__); } // Loop over crates @@ -491,7 +502,7 @@ void DEVIOWorkerThread::ParseBORbank(uint32_t* &iptr, uint32_t *iend) if( (crate_header>>16) != 0x71 ){ stringstream ss; ss << "Bad BOR crate header: 0x" << hex << (crate_header>>16); - throw JException(ss.str(), __FILE__, __LINE__); + throw JExceptionDataFormat(ss.str(), __FILE__, __LINE__); } // Loop over modules @@ -542,7 +553,7 @@ void DEVIOWorkerThread::ParseBORbank(uint32_t* &iptr, uint32_t *iend) stringstream ss; ss << "Unknown BOR module type: " << modType << " (module_header=0x"< sizeof_dest ){ stringstream ss; ss << "BOR module bank size does not match structure! " << module_len << " > " << sizeof_dest << " for modType " << modType; - throw JException(ss.str(), __FILE__, __LINE__); + throw JExceptionDataFormat(ss.str(), __FILE__, __LINE__); } // Copy bank data, assuming format is the same @@ -588,7 +599,7 @@ void DEVIOWorkerThread::ParseTSscalerBank(uint32_t* &iptr, uint32_t *iend) if(Nwords != Nwords_expected){ _DBG_ << "TS bank size does not match expected!!" << endl; _DBG_ << "Found " << Nwords << " words. Expected " << Nwords_expected << endl; - + throw JExceptionDataFormat("TS bank size does not match expected", __FILE__, __LINE__); }else{ // n.b. Get the last event here since if this is a block // of events, the last should be the actual sync event. @@ -693,7 +704,7 @@ void DEVIOWorkerThread::ParseBuiltTriggerBank(uint32_t* &iptr, uint32_t *iend) if( ((*iptr) & mask) != mask ){ stringstream ss; ss << "Bad header word in Built Trigger Bank: " << hex << *iptr; - throw JException(ss.str(), __FILE__, __LINE__); + throw JExceptionDataFormat(ss.str(), __FILE__, __LINE__); } uint32_t tag = (*iptr)>>16; // 0xFF2X @@ -704,7 +715,7 @@ void DEVIOWorkerThread::ParseBuiltTriggerBank(uint32_t* &iptr, uint32_t *iend) if(Mevents == 0) { stringstream ss; ss << "DEVIOWorkerThread::ParseBuiltTriggerBank() called with zero events! "<misc.push_back(*iptr++); if(iptr > iend){ - throw JException("Bad data format in ParseBuiltTriggerBank!", __FILE__, __LINE__); + throw JExceptionDataFormat("Bad data format in ParseBuiltTriggerBank!", __FILE__, __LINE__); } } } @@ -873,6 +884,8 @@ void DEVIOWorkerThread::ParseDataBank(uint32_t* &iptr, uint32_t *iend) cout.flush(); cerr.flush(); DumpBinary(&iptr[-2], iend, 32, &iptr[-1]); // } + throw JExceptionDataFormat("Unknown bank type in EVIO", __FILE__, __LINE__); + } iptr = iend_data_block_bank; @@ -965,8 +978,7 @@ void DEVIOWorkerThread::ParseCAEN1190(uint32_t rocid, uint32_t* &iptr, uint32_t _DBG_ << "CAEN1290TDC parser sees more events than CODA header! (>" << current_parsed_events.size() << ")" << endl; for( auto p : events_by_event_id) cout << "id=" << p.first << endl; iptr = iend; - exit(-1); // should we exit, or try and continue?? - return; + throw JExceptionDataFormat("CAEN1290TDC parser sees more events than CODA header", __FILE__, __LINE__); } pe = *pe_iter++; events_by_event_id[event_id] = pe; @@ -1000,6 +1012,7 @@ void DEVIOWorkerThread::ParseCAEN1190(uint32_t rocid, uint32_t* &iptr, uint32_t break; default: cout << "Unknown datatype: 0x" << hex << type << " full word: "<< *iptr << dec << endl; + throw JExceptionDataFormat("Unknown data type for CAEN1190", __FILE__, __LINE__); } iptr++; @@ -1047,7 +1060,7 @@ void DEVIOWorkerThread::ParseModuleConfiguration(uint32_t rocid, uint32_t* &iptr for(uint32_t i=0; i< Nvals; i++){ if( iptr >= iend){ _DBG_ << "DAQ Configuration bank corrupt! slot_mask=0x" << hex << slot_mask << dec << " Nvals="<< Nvals << endl; - exit(-1); + throw JExceptionDataFormat("Corrupt DAQ config. bank", __FILE__, __LINE__); } daq_param_type ptype = (daq_param_type)((*iptr)>>16); @@ -1123,7 +1136,7 @@ void DEVIOWorkerThread::ParseModuleConfiguration(uint32_t rocid, uint32_t* &iptr default: _DBG_ << "Unknown module type: 0x" << hex << (ptype>>8) << endl; - exit(-1); + throw JExceptionDataFormat("Unknown module type in configuration bank", __FILE__, __LINE__); } @@ -1191,6 +1204,7 @@ void DEVIOWorkerThread::ParseJLabModuleData(uint32_t rocid, uint32_t* &iptr, uin while(iptr7) cout << " FADC250 unknown data type ("<7) cout << " FADC125 ignored data type: " << data_type <7) cout << " FADC125 unknown data type ("< (iptr+4)) break; } - throw JException("Unexpected word type in F1TDC block!", __FILE__, __LINE__); + throw JExceptionDataFormat("Unexpected word type in F1TDC block!", __FILE__, __LINE__); break; } } diff --git a/src/programs/Analysis/hd_ana/hd_ana.cc b/src/programs/Analysis/hd_ana/hd_ana.cc index b486c7f5e..cdb96ed35 100644 --- a/src/programs/Analysis/hd_ana/hd_ana.cc +++ b/src/programs/Analysis/hd_ana/hd_ana.cc @@ -23,6 +23,7 @@ int main(int narg, char *argv[]) // Run though all events, calling our event processor's methods app.Run(NULL, 1); + if( app.GetExitCode() ) cerr << "Exit code: " << app.GetExitCode() << endl; return app.GetExitCode(); } diff --git a/src/programs/Analysis/hd_root/hd_root.cc b/src/programs/Analysis/hd_root/hd_root.cc index fa5db2027..fb147cb85 100644 --- a/src/programs/Analysis/hd_root/hd_root.cc +++ b/src/programs/Analysis/hd_root/hd_root.cc @@ -46,6 +46,7 @@ int main(int narg, char *argv[]) delete myproc; + if( app.GetExitCode() ) cerr << "Exit code: " << app.GetExitCode() << endl; return app.GetExitCode(); }