DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
BUException::exBase Class Referenceabstract

#include <ExceptionBase.hh>

Inheritance diagram for BUException::exBase:
[legend]
Collaboration diagram for BUException::exBase:
[legend]

Public Member Functions

virtual ~exBase () throw ()
 
const char * StackTrace () const throw ()
 
void Append (const char *buffer) throw ()
 
void Append (std::string str)
 
const char * Description () const throw ()
 
virtual const char * what () const throw () =0
 
pid_t GetPID ()
 

Protected Member Functions

 exBase () throw ()
 
void Copy (const exBase &rh) throw ()
 
 exBase (const exBase &rh) throw ()
 

Private Member Functions

exBaseoperator= (const exBase &rh) throw ()
 
void GenerateStackTrace () throw ()
 
void AppendStackLine (const char *line) throw ()
 

Private Attributes

size_t descriptionSize
 
size_t descriptionUsed
 
char * descriptionBuffer
 
size_t stackSize
 
size_t stackUsed
 
char * stackBuffer
 
pid_t PID
 

Detailed Description

Definition at line 47 of file ExceptionBase.hh.

Constructor & Destructor Documentation

◆ ~exBase()

BUException::exBase::~exBase ( )
throw ( )
virtual

Definition at line 41 of file ExceptionBase.cpp.

42{
43 if(stackBuffer != NULL)
44 free(stackBuffer);
45 if(descriptionBuffer != NULL)
47}

◆ exBase() [1/2]

BUException::exBase::exBase ( )
throw ( )
protected

Definition at line 6 of file ExceptionBase.cpp.

6 : descriptionSize(255),
7 stackSize(1024),
8 PID(-1)
9{
10 //Allocate memory (throw if failed)
11 stackBuffer = (char *) malloc(stackSize+1);
12 descriptionBuffer = (char *) malloc(descriptionSize+1);
13
15 stackUsed = 0;
16
17 //Null terminate the strings to empty
18 //also make the char after the nominal end of string null terminated
19 if(descriptionBuffer != NULL)
20 {
21 descriptionBuffer[0] = '\0';
23 }
24 else
25 {
27 }
28 if(stackBuffer != NULL)
29 {
30 stackBuffer[0] = '\0';
31 stackBuffer[stackSize] = '\0';
32 }
33 else
34 {
35 stackSize=0;
36 }
37
39}

◆ exBase() [2/2]

BUException::exBase::exBase ( const exBase & rh)
throw ( )
inlineprotected

Definition at line 71 of file ExceptionBase.hh.

71{(void) rh;}; // have to cast to void to keep from unused param error

Member Function Documentation

◆ Append() [1/2]

void BUException::exBase::Append ( const char * buffer)
throw ( )

Definition at line 94 of file ExceptionBase.cpp.

95{
96 //Compute the appended buffer's size
97 size_t appendedSize = strlen(buffer);
98
99 //Make sure we stay in the bounds of our buffer
100 if( appendedSize > (descriptionSize - descriptionUsed))
101 {
102 appendedSize = (descriptionSize - descriptionUsed);
103 }
104
105 //Append the new string (n keeps us safe from buffer overflow)
107 buffer,
108 appendedSize);
109
110 //update the description size
111 descriptionUsed += appendedSize;
112
113 //enforce the null terminator
114 //(the buffer is one larger than the size so we always have space for a NULL)
115 //This is untrue if malloc failed initially, so we watch out for that.
116 if(descriptionBuffer != NULL)
118}

◆ Append() [2/2]

void BUException::exBase::Append ( std::string str)
inline

Definition at line 57 of file ExceptionBase.hh.

57{Append(str.c_str());};
void Append(const char *buffer)

◆ AppendStackLine()

void BUException::exBase::AppendStackLine ( const char * line)
throw ( )
private

Definition at line 13 of file ExceptionBase_stacktrace.cpp.

14{
15 //Check for NULL line
16 if(line == NULL)
17 return;
18
19 //get raw line size
20 size_t lineSize = strlen(line);
21 if(lineSize >= (stackSize - stackUsed))
22 lineSize = stackSize - stackUsed;
23 //copy string
24 strncpy(stackBuffer+stackUsed,line,lineSize);
25 //update size
26 stackUsed += lineSize;
27 //Add eol
28 if((stackSize - stackUsed) > 1)
29 {
30 stackBuffer[stackUsed] = '\n';
31 stackUsed++;
32 }
33 //add null terminator (there is always room for one(unless NULL))
34 if(stackBuffer != NULL)
35 {
36 stackBuffer[stackUsed] = '\0';
37 }
38}

◆ Copy()

void BUException::exBase::Copy ( const exBase & rh)
throw ( )
protected

Definition at line 49 of file ExceptionBase.cpp.

50{
51 //Copy description buffer
52 this->descriptionUsed = 0;
53 this->descriptionSize = rh.descriptionSize;
54 //Check if the allocation had worked for rh
55 if(rh.descriptionBuffer == NULL)
56 {
57 //It didn't work, make sure our copy is also NULL
58 this->descriptionBuffer = NULL;
59 }
60 else
61 {
62 //rh has a valid description, build ours
63 this->descriptionBuffer = (char *) malloc(descriptionSize+1);
64 if(this->descriptionBuffer != NULL)
65 {
66 memcpy(this->descriptionBuffer,rh.descriptionBuffer,descriptionSize);
67 this->descriptionUsed = rh.descriptionUsed;
68 }
69 }
70
71 //Copy stack trace buffer
72 this->stackUsed = 0;
73 this->stackSize = rh.stackSize;
74 //Check if the allocation worked for rh
75 if(rh.stackBuffer == NULL)
76 {
77 //It didn't work, make sure our copy is also NULL
78 this->stackBuffer = NULL;
79 }
80 else
81 {//rh was valid, so construct ours
82 this->stackBuffer = (char *) malloc(stackSize+1);
83 if(this->stackBuffer != NULL)
84 {
85 memcpy(this->stackBuffer,rh.stackBuffer,stackSize);
86 this->stackUsed = rh.stackUsed;
87 }
88 }
89
90 //Copy PID
91 this->PID = rh.PID;
92}

◆ Description()

const char * BUException::exBase::Description ( ) const
throw ( )

Definition at line 120 of file ExceptionBase.cpp.

121{
122 if(descriptionBuffer == NULL) //If there was a bad alloc, return an error string
123 return descriptionError;
124 return descriptionBuffer;
125}
static const char descriptionError[]

◆ GenerateStackTrace()

void BUException::exBase::GenerateStackTrace ( )
throw ( )
private

Definition at line 40 of file ExceptionBase_stacktrace.cpp.

41{
42 //Get the thread/process ID for this stack trace
43 PID = syscall(SYS_gettid);
44
45 //Get the stack trace (void *s)
46 const size_t maxStackSize = 20;
47 void * functionStack[maxStackSize];
48 size_t stackSize;
49
50 //Fill functionStack with void * pointers to return address of the corresponding stack frame
51 //filed up to maxStackSize with most recent calls
52 stackSize = backtrace(functionStack,maxStackSize);
53
54 //Get the stack trace strings (we have to free this)
55 char ** functionNames = backtrace_symbols(functionStack,stackSize);
56 if(functionNames == NULL)
57 {
58 fprintf(stderr,"Error in exBase::GenerateStackTrace(). backtrace_symbols failed\n");
59 return;
60 }
61
62 char * demangledName = NULL;
63 //Start stack trace from 3 to skip the exception class's functions
64 for(size_t iFunction = 3; iFunction < stackSize; iFunction++)
65 {
66 //based off of http://panthema.net/2008/0901-stacktrace-demangled/
67 //Be paranoid about these pointers and make sure they are valid
68 if(functionNames[iFunction] == NULL)
69 {
70 AppendStackLine("Unknown");
71 continue;
72 }
73
74 char * mangledStart = NULL;
75 char * offsetStart = NULL;
76 char * offsetEnd = NULL;
77
78 //Find mangled and offset start/ends
79 char * bufferEnd = functionNames[iFunction] + strlen(functionNames[iFunction]);
80 for(char * buffer = functionNames[iFunction];buffer != bufferEnd;buffer++)
81 {
82 //Look for function's opening '('
83 if(*buffer == '(')
84 mangledStart = buffer;
85 //Look for offset in function
86 else if(*buffer == '+')
87 offsetStart = buffer;
88 //Look for closing ')', but only if we've found an opening one
89 else if( (*buffer == ')') && (offsetStart != NULL))
90 {
91 offsetEnd = buffer;
92 break;
93 }
94 }
95
96 //if the parsing makes sense
97 if( (mangledStart != NULL) &&
98 (offsetStart != NULL) &&
99 (offsetEnd != NULL) &&
100 (mangledStart < offsetStart)
101 )
102 {
103 //Make manglesStart point to the beginning of the name
104 mangledStart++;
105 //put in a null terminator at offsetStart to end the mangled name
106 *offsetStart = '\0';
107
108 //Make offset start point to the beginning of the offset
109 offsetStart++;
110 //put a null terminator at the end of the offset
111 *offsetEnd = '\0';
112
113 //demangle
114 size_t demangledSize = 0;
115 int demangledRet = 0;
116 char * retName = abi::__cxa_demangle(mangledStart,
117 demangledName,
118 &demangledSize,
119 &demangledRet);
120 //Append demangled line
121 if((demangledRet == 0) && (retName != NULL))
122 {
123 //copy possibly reallocated c-string
124 demangledName = retName;
125 AppendStackLine(demangledName);
126 }
127 else //if ther was an error, append the mangled name
128 {
129 AppendStackLine(mangledStart);
130 }
131 }
132 else //Bad parse, just print the line
133 {
134 AppendStackLine(functionNames[iFunction]);
135 }
136 }
137
138 if(demangledName != NULL)
139 free(demangledName);
140 free(functionNames);
141
142}
void AppendStackLine(const char *line)

◆ GetPID()

pid_t BUException::exBase::GetPID ( )
inline

Definition at line 64 of file ExceptionBase.hh.

64{return PID;};

◆ operator=()

exBase & BUException::exBase::operator= ( const exBase & rh)
throw ( )
private

◆ StackTrace()

const char * BUException::exBase::StackTrace ( ) const
throw ( )

Definition at line 6 of file ExceptionBase_stacktrace.cpp.

7{
8 if(stackBuffer == NULL)
9 return stackError;
10 return stackBuffer;
11}
static const char stackError[]

◆ what()

virtual const char * BUException::exBase::what ( ) const
throw ( )
pure virtual

Member Data Documentation

◆ descriptionBuffer

char* BUException::exBase::descriptionBuffer
private

Definition at line 84 of file ExceptionBase.hh.

◆ descriptionSize

size_t BUException::exBase::descriptionSize
private

Definition at line 82 of file ExceptionBase.hh.

◆ descriptionUsed

size_t BUException::exBase::descriptionUsed
private

Definition at line 83 of file ExceptionBase.hh.

◆ PID

pid_t BUException::exBase::PID
private

Definition at line 91 of file ExceptionBase.hh.

◆ stackBuffer

char* BUException::exBase::stackBuffer
private

Definition at line 89 of file ExceptionBase.hh.

◆ stackSize

size_t BUException::exBase::stackSize
private

Definition at line 87 of file ExceptionBase.hh.

◆ stackUsed

size_t BUException::exBase::stackUsed
private

Definition at line 88 of file ExceptionBase.hh.


The documentation for this class was generated from the following files: