path: root/CommonLibs
diff options
authorPau Espin Pedrol <pespin@sysmocom.de>2018-09-03 15:22:50 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2018-09-03 15:22:53 +0200
commit86be40b4eb762d5c12e8e3f7388ca9f254e77b36 (patch)
tree1bb5d3d3b836fd8d48d29635e50b1e6edb11f32b /CommonLibs
parent288d8af07001ee86f6df26351e88e126f75163ad (diff)
Logger: Disable pthread cancel point inside Logger destructor
pthread_cancel is implemented in c++ using exception handlers. In destructor of Log object, the log function is called which will eventually call fputs() to write to a file. Since that function is considered a cancelation point, if pthread_cancel has been called the exception handler will start unstacking frames and calling destructors in the process. At some point this will cause a runtime exception in c++ which will call std::terminate() to abort the process. The solution is thus to avoid starting the cancellation process inside the destructor. This behavior was spotted while calling the destructor of Transceiver object in forthcoming patches. See a more detailed example here: https://skaark.wordpress.com/2010/08/26/pthread_cancel-considered-harmful/ Change-Id: I71ca90f3fbc73df58b878a03361f7b7831d838b4
Diffstat (limited to 'CommonLibs')
1 files changed, 3 insertions, 0 deletions
diff --git a/CommonLibs/Logger.cpp b/CommonLibs/Logger.cpp
index 393d882..171c635 100644
--- a/CommonLibs/Logger.cpp
+++ b/CommonLibs/Logger.cpp
@@ -44,6 +44,8 @@ std::ostream& operator<<(std::ostream& os, std::ostringstream& ss)
+ int old_state;
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
int mlen = mStream.str().size();
int neednl = (mlen==0 || mStream.str()[mlen-1] != '\n');
const char *fmt = neednl ? "%s\n" : "%s";
@@ -51,6 +53,7 @@ Log::~Log()
// The COUT() macro prevents messages from stomping each other but adds uninteresting thread numbers,
// so just use std::cout.
LOGPSRC(mCategory, mPriority, filename, line, fmt, mStream.str().c_str());
+ pthread_setcancelstate(old_state, NULL);
ostringstream& Log::get()