Belle II Software light-2406-ragdoll
CaptureStreamAbortHandler Class Reference

Small class to handle std::abort() calls by external libraries. More...

Collaboration diagram for CaptureStreamAbortHandler:

Public Member Functions

 CaptureStreamAbortHandler (const CaptureStreamAbortHandler &)=delete
 Singleton, no copy construction.
 
 CaptureStreamAbortHandler (CaptureStreamAbortHandler &&)=delete
 Singleton, no move construction.
 
CaptureStreamAbortHandleroperator= (const CaptureStreamAbortHandler &)=delete
 Singleton, no assignment.
 
void addObject (CaptureStream *obj)
 Add a CaptureStream object to guard against SIGABRT.
 
void removeObject (CaptureStream *obj)
 Remove a CaptureStream object to no longer guard against SIGABRT.
 

Static Public Member Functions

static CaptureStreamAbortHandlergetInstance ()
 Return the singleton instance.
 

Private Member Functions

 CaptureStreamAbortHandler ()
 Register handler.
 

Static Private Member Functions

static void handle (int signal)
 signal handler: print all pending redirection buffers and exit
 

Private Attributes

std::set< CaptureStream * > m_objects
 list of all active stream redirections
 

Detailed Description

Small class to handle std::abort() calls by external libraries.

External libraries like EvtGen seem to prefer calling abort() on error which means destructors are not called and so interception is never finished and thus the error message are lost.

This class installs a SIGABRT handler which is the only way to do something once std::abort() is called and dump all the output intercepted so far back on the original output (stdout or stderr) to basically "reverse" the redirection.

This seems like the best choice since calling abort means the user needs to be able to see the messages

Definition at line 34 of file IOIntercept.cc.

Constructor & Destructor Documentation

◆ CaptureStreamAbortHandler()

CaptureStreamAbortHandler ( )
inlineprivate

Register handler.

Definition at line 54 of file IOIntercept.cc.

55 {
56 auto result = std::signal(SIGABRT, &CaptureStreamAbortHandler::handle);
57 if (result == SIG_ERR) B2FATAL("Cannot register abort handler");
58 }
static void handle(int signal)
signal handler: print all pending redirection buffers and exit
Definition: IOIntercept.cc:65

Member Function Documentation

◆ addObject()

void addObject ( CaptureStream obj)
inline

Add a CaptureStream object to guard against SIGABRT.

Definition at line 49 of file IOIntercept.cc.

49{ m_objects.emplace(obj); }
std::set< CaptureStream * > m_objects
list of all active stream redirections
Definition: IOIntercept.cc:62

◆ getInstance()

static CaptureStreamAbortHandler & getInstance ( )
inlinestatic

Return the singleton instance.

Definition at line 43 of file IOIntercept.cc.

44 {
45 static CaptureStreamAbortHandler instance;
46 return instance;
47 }

◆ handle()

void handle ( int  signal)
staticprivate

signal handler: print all pending redirection buffers and exit

Definition at line 65 of file IOIntercept.cc.

66 {
67 // move set of registered objects in here so we can call finish when
68 // looping over them without invalidating the iterators
69 std::set<CaptureStream*> objects;
71 // loop over all registered instances and print the content in their
72 // buffer to the original file descriptor
73 for (CaptureStream* stream : objects) {
74 // close the write end of the pipe
75 close(stream->m_replacementFD);
76 // read all content
77 if (stream->finish()) {
78 const std::string& out = stream->getOutput();
79 // and write it to the original file descriptor
80 if (out.size()) write(stream->m_savedFD, out.c_str(), out.size());
81 }
82 }
83 // write error message and signal error
84 write(STDERR_FILENO, "abort() called, exiting\n", 24);
85 std::_Exit(EXIT_FAILURE);
86 }
static CaptureStreamAbortHandler & getInstance()
Return the singleton instance.
Definition: IOIntercept.cc:43

◆ removeObject()

void removeObject ( CaptureStream obj)
inline

Remove a CaptureStream object to no longer guard against SIGABRT.

Definition at line 51 of file IOIntercept.cc.

51{ m_objects.erase(obj); }

Member Data Documentation

◆ m_objects

std::set<CaptureStream*> m_objects
private

list of all active stream redirections

Definition at line 62 of file IOIntercept.cc.


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