I'm implementing std::signal into my server application to shut it down safely.
void signal_handler(int signal)
{
if (signal == SIGINT)
{
std::cout << "Hello.\n";
exit(signal);
}
}
void threadFunc()
{
while (gLoop)
{
std::cout << "Hello..\n";
std::this_thread::sleep_for(1s);
}
}
int main()
{
std::signal(SIGINT, signal_handler);
std::thread thrd{ threadFunc };
thrd.join();
}
This is an example code
It works fine when I run it as release mode..
But it stops when I press Ctrl+c in debug mode and of course notify me that exception occurred.
I just want it to ignore the exception and see what I've done something wrong in the terminating process (memory leaks, violation exception etc.)
Is there anyway that I can do for it?
I figured it out just a second after I post this!
I can do it by just disabling catch this exception next time setting in the exception box.
Related
My code:
QSerialPortInfo getCentralInfo()
{
const QList<QSerialPortInfo> infoList =
QSerialPortInfo::availablePorts();
for (auto it = infoList.cbegin();
it != infoList.cend(); ++it) {
if (it->manufacturer() == "1a86") {
happyTalk("Znaleziono centralkÄ™.");
return *it;
}
}
escape("Nie znaleziono centralki.");
}
void escape(QString errorMsg) {
qDebug() << "[!] " << errorMsg;
throw;
}
void happyTalk(QString msg) {
qDebug() << "[\u2713] " << msg;
}
Is it elegant to stop the application like that and why is it not? I'm getting debugger warnings but I think the debugger is wrong here. ;-)
Add the [[noreturn]] attribute to escape, and actually throw an object.
[[noreturn]] tells the compiler, optimizer and hopefully warning generator that escape never returns, so it should (in an ideal world) block that error.
The issue here is that
throw;
does not mean "throw some exception." It means "rethrow the exception currently being processed." If you execute throw with no active exception, I believe it calls std::terminate to end the program.
A more elegant way to handle this would either be to throw an exception (perhaps a std::logic_error) to indicate that something bad happened and transfer control to an error handler, or to exit the program by calling exit or abort.
Hope this helps!
I have the code below which is the start of a new thread. BeginWork function goes through a sequence of functions that have heavy exception handling. If threadgroup.interrupt_all(); is called the individual function will handle the interrupt and this causes the thread to remain in it's loop without being interrupted properly. How can I change my error handling to account for this type of exception and mimic the behavior as if the outer try catch block of the intial loop caught the thread interrupt exception? I'm thinking maybe catch the exception of time interupt and set a boolean to true which is checked within the main loop and break if it is set to true.
void ThreadWorker(int intThread)
{
try
{
int X = 0;
do
{
cout << "Thread " << intThread << "\n";
BeginWork();
}
while (true);
}
catch(...)
{
cout << "Thread: " << intThread << " Interrupted.";
}
}
You can easily do it by boost::thread_interrupted rethrowing in a function catch site
try
{
// data processing
}
catch(const boost::thread_interrupted &)
{
throw;
}
catch(...)
{
// exceptions suppression
}
But i think it's not a very good idea to handle all exceptions inside every function. Better way is to handle only specific exceptions, allowing others to propagate further to the top level function, where they will be handled.
Maybe this site will be useful for you
I did my best to follow the instructions in the ZMQ termination whitepaper, but so far I'm failing miserably.
I have a parent class, which spawns a listener thread (using win32-pthreads).
Accoring to the whitepaper, when terminating, I should set the _stopped flag, delete the context, which in turn would call zmq_term() and release the blocking recv(). Instead, what I get is either:
calling delete _zmqContext crashes the application (probably with a segmentation fault)
replacing the delete with zmq_term(_zmqContext) does not release the blocking recv()
I'm adding a partial code sample, which is long because I'm not sure which part may be important.
AsyncZmqListener.hpp:
class AsyncZmqListener
{
public:
AsyncZmqListener(const std::string uri);
~AsyncZmqListener();
bool Start();
void Stop();
private:
static void* _threadEntryFunc(void* _this);
void _messageLoop();
private:
bool _stopped;
pthread_t _thread;
zmq::context_t* _zmqContext;
};
AsyncZmqListener.cpp:
AsyncZmqListener::AsyncZmqListener(const std::string uri) : _uri(uri)
{
_zmqContext = new zmq::context_t(1);
_stopped = false;
}
void AsyncZmqListener::Start()
{
int status = pthread_create(&_thread, NULL, _threadEntryFunc, this);
}
void AsyncZmqListener::Stop()
{
_stopped = true;
delete _zmqContext; // <-- Crashes the application. Changing to 'zmq_term(_zmqContext)' does not terminate recv()
pthread_join(_thread, NULL); // <-- This waits forever
}
void AsyncZmqListener::_messageLoop()
{
zmq::socket_t listener(*_zmqContext, ZMQ_PULL);
listener.bind(_uri.c_str());
zmq::message_t message;
while(!_stopped)
{
listener.recv(&message); // <-- blocks forever
process(message);
}
}
P.S.
I'm aware of this related question, but none of the answers quite match the clean exit flow described in the whitepaper. I will resolve to polling if I have to...
ZMQ recv() did unblock after its related context was terminated
I was not aware that recv() throws an ETERM exception when this happens.
Revised code that works:
void AsyncZmqListener::_messageLoop()
{
zmq::socket_t listener(*_zmqContext, ZMQ_PULL);
listener.bind(_uri.c_str());
zmq::message_t message;
while(!_stopped)
{
try
{
listener.recv(&message);
process(message);
}
catch(const zmq::error_t& ex)
{
// recv() throws ETERM when the zmq context is destroyed,
// as when AsyncZmqListener::Stop() is called
if(ex.num() != ETERM)
throw;
}
}
}
i am creating client sever application in windows using socket and i want to throw exception at run time from thread if any problem occur but i am getting error for throw statement.
//create thread in cpp file
CreateThread(NULL,0,startServer,this,0,NULL);
//thread in header file
static unsigned long __stdcall startServer(void *i_SocketTransportServer)
{
((SocketTransportServer*)i_SocketTransportServer)->StartServerThread(((SocketTransportServer *)i_SocketTransportServer)->m_socketServer);
return 0;
}
//and StartServerThread is function called by thread
// SocketTransportServer is inner class of RMLThinTransport
void RMLThinTransport::SocketTransportServer::StartServerThread(SOCKET i_socketServer)
{
m_socketAccept=NULL;
while(true)
{
Sleep(20);
if(m_canAcceptMore)
{
m_canAcceptMore=false;
if(!m_isRunning)
{
break;
}
try
{
m_socketAccept=accept(m_socketServer,NULL,NULL);
if(m_socketAccept==INVALID_SOCKET)
{
int lastError=WSAGetLastError();
closesocket(m_socketAccept);
SocketExceptions
exceptionInAcceptAtServer;
exceptionInAcceptAtServer.detectErrorAccept(&lastError);
throw exceptionInAcceptAtServer;
}
else
{
//_LOG("Client connected",EventTypeInfo) ;
OutputDebugStringW(L"client connected.....");
/* If client connected then setClinetCout value 1 */
setClientCount(1);
m_ClientSockets.push_back(m_socketAccept);
CreateThread(NULL,0,receiveDataAtServer,this,0,NULL);
}
}
catch(SocketExceptions& i_exceptionInAcceptAtServer)
{
/*OutputDebugStringW(L"Can't accept client In Exception. ."); */
throw i_exceptionInAcceptAtServer;//getting runtime error from here
}
}
}
}
now i want to throw error when server close but i am getting run time error. so is there any way so i can get error in my main function.sorry but i am new in c++ so please help me. and error is
The code that throws the exception is not the problem; it's the lack of any code to catch the exception that's the problem. The application is terminating because nothing is catching the exception you're throwing; you must ensure that something is going to catch it. Your startServer method -- the thread procedure -- must catch the exception, and cleanly exit the thread.
Before I begin, I want to clarify that this is not a command-line tool, but an application that accepts commands through it's own command-line interface.
Edit: I must apologize about my explanation from before, apparently I didn't do a very good job at explaining it. One more time...
I am building a command-line interface application that accepts commands from a user. I have a signal handler setup to catch the signals, which then sets a flag that I need to terminate the application. The problem I'm having is all of the console functions I can find are blocking, which means that I can't detect that I need to exit from my console processing loop until the user presses a key (or enter, depending on the function).
Is there some standard way I can do either non-block console interaction, or is there an elegant way to structure the program so that if I just terminate from the signal thread, that everything will be handled and released properly (please don't mis-understand this, I know how this could be done using locking and releasing the resources from the signaling thread, but this could get messy, so I'd rather avoid it)
Hopefully that explanation makes more sense...
OK - this is working for me on Windows & is portable - notice the #ifdef SIGBREAK - this isn't a standard signal.
#include <csignal>
#include <iostream>
#include <ostream>
#include <string>
using namespace std;
namespace
{
volatile sig_atomic_t quit;
void signal_handler(int sig)
{
signal(sig, signal_handler);
quit = 1;
}
}
int main()
{
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
#ifdef SIGBREAK
signal(SIGBREAK, signal_handler);
#endif
/* etc */
while (!quit)
{
string s;
cin >> s;
cout << s << endl;
}
cout << "quit = " << quit << endl;
}
On *nix, you can use the signal function to register a signal handler:
#include <signal.h>
void signal_handler(int sig)
{
// Handle the signal
}
int main(void)
{
// Register the signal handler for the SIGINT signal (Ctrl+C)
signal(SIGINT, signal_handler);
...
}
Now, whenever someone hits Ctrl+C, your signal handler will be called.
In Windows: SetConsoleCtrlHandler
On a *nix based system you might not really need a signal handler for this to work. You could specify that you want to ignore the SIGINT call
int main(void)
{
// Register to ignore the SIGINT signal (Ctrl+C)
signal(SIGINT, SIG_IGN);
while(1)
{
retval = my_blocking_io_func();
if(retval == -1 && errno == EINTR)
{
// do whatever you want to do in case of interrupt
}
}
}
The important way that this works is to recognize that non-blocking functions do get interrupted. Normally, you would realize that the blocking function failed (e.g. read()) and reattempt the function. If it was some other value you would take the appropriate error related action.
A better *nix solution that is thread safe is to use pthread_sigmask() instead of signal().
For example, this is how you signore SIGINT, SIGTERM, and SIGPIPE in the current thread and future spawned threads:
sigset_t waitset;
sigemptyset(&waitset);
sigaddset(&waitset, SIGINT);
sigaddset(&waitset, SIGTERM);
sigaddset(&waitset, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &waitset, NULL);