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

exBase & operator= (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 36 of file ExceptionBase.cpp.

37{
38 if (stackBuffer != NULL)
39 free(stackBuffer);
40 if (descriptionBuffer != NULL)
42}

◆ exBase() [1/2]

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

Definition at line 6 of file ExceptionBase.cpp.

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

◆ 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 83 of file ExceptionBase.cpp.

84{
85 // Compute the appended buffer's size
86 size_t appendedSize = strlen(buffer);
87
88 // Make sure we stay in the bounds of our buffer
89 if (appendedSize > (descriptionSize - descriptionUsed)) {
90 appendedSize = (descriptionSize - descriptionUsed);
91 }
92
93 // Append the new string (n keeps us safe from buffer overflow)
94 strncpy(descriptionBuffer + descriptionUsed, buffer, appendedSize);
95
96 // update the description size
97 descriptionUsed += appendedSize;
98
99 // enforce the null terminator
100 //(the buffer is one larger than the size so we always have space for a NULL)
101 // This is untrue if malloc failed initially, so we watch out for that.
102 if (descriptionBuffer != NULL)
104}

◆ 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 15 of file ExceptionBase_stacktrace.cpp.

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

◆ Copy()

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

Definition at line 45 of file ExceptionBase.cpp.

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

◆ Description()

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

Definition at line 107 of file ExceptionBase.cpp.

108{
109 if (descriptionBuffer == NULL) // If there was a bad alloc, return an error string
110 return descriptionError;
111 return descriptionBuffer;
112}
static const char descriptionError[]

◆ GenerateStackTrace()

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

Definition at line 41 of file ExceptionBase_stacktrace.cpp.

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

8{
9 if (stackBuffer == NULL)
10 return stackError;
11 return stackBuffer;
12}
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: