If I know a pid of a certain process that doesn't run the code(say firefox)
how do I assign a signal handler(say SIGINT) to it?
I have now :
pid = fork();
printf("forked and my pid is %d\n",pid);
//check for errors
if (pid<0){
printf("Error: invoking fork to start ss has failed, Exiting\n ");
exit(1);
}
//the child process runs the gulp
if (pid==0){
printf("STARTING THE FIREFOX\n");
//calling signal(somehandler,SIGINT); here will bind the child, which is replaced by the firefox new process,hence won't invoke the "somehandler"
if (execv(args[0],args)<0){
perror("Error: running s with execvp has failed, Exiting\n");
}
//invoking signal(somehandler,SIGINT); will obviously not do anything
printf("IVE BEEN KILLED\n");
}
//dad is here
printf("DAD IS GOING TO KILL\n");
if (pid>0){
sleep(6);
//how do I bind a handler to that signal????
kill(get_pidof(string("firefox")),SIGINT);
}
You can only establish a signal handler from within the process. Put another way, you can't make firefox call your signal handler when it gets a SIGINT.
EDIT
As you noticed, indeed signal handlers are not kept after an exec - the image of the process is replaced so it wouldn't make sense. So, like I said before: you can't make firefox call your handler even if you control its parent.
I need my program to run another program(say firefox), and to know
when the firefox died or crashed
In that case you want to establish a signal handler for SIGCHLD: your process will jump to it when the child dies.
As Cnucitar answered here, you can only change signal handler from inside the process.
If you wanted to make a signal handler inside firefox, you could patch it, perhaps thru a plugin. But I am sure that would be a bad idea.
Related
I'm getting this error: ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 0x0x20e51b65eb0. Receiver 'gw2g' (of type 'gw2g') was created in thread 0x0x20e4fd0c930"
DEBUG:
MAIN_thread started: QThread(0x20e4fd0c930)
DUMMY_LOOP started: QThread(0x20e51b65eb0)
What could cause this error?
gw2g.cpp
addExtenders()
{
//...model gets set etc
//
connect(this, SIGNAL(xprep_ready(bool)), ui->connectButton, SLOT(setEnabled(bool)), Qt::AutoConnection);
connect(ui->listView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(prep_connectx(QItemSelection)), Qt::AutoConnection);
}
While debugging with breakpoints I found out that I get this error after leaving addExtenders()
I also set breakpoints inside destructor of dummyMain_c and gw2g, neither gets destroyed unwantedly. Sometimes dummyMain_c does get destroyed unexpectedly.
(Press Retry to debug the application)
QCoreApplication::exec: The event loop is already running
Maybe it has something to do with this event_loop
emit extend_list();
wait_xcon.exec();
It gets quit when clicking one of the buttons in the GUI.
QObject::connect(mwindow.ui->connectButton, &QPushButton::clicked, &dummy_main.wait_xcon, &QEventLoop::quit);
I don't even get to that part though unfortunately.
the threads in the picture are the main (0x0x2059fdfd9b0) and the dummy (0x0x205a1c85ff0)
I also checked if all main window functions run in the main thread - they do.
So all GUI stuff happens in the main - I don't know anymore.
I figured it out.
The error message was very misleading, since the problem was the QEventLoop in dummy.
When main window(gw2g) QPushButton is clicked it quits this eventloop, so why is the receiver (gw2g)?
So, I just got rid of
wait_xcon.exec();
and replaced it with a simple
while(!quitloop){}
clicking the button now sets this bool to true
I have gSOAP server generated from a WSDL file + a Qt GUI. The generated code works perfectly fine, except one point that causes my process to stay alive after GUI exits. (I'm deploying on Windows, so I have no signaling)
I need my GUI to stay alive (naturally) so I moved server-proxy object to a QObject-based class that the latter is moved to another QThread, and the I fire it up by an external signal. The server now runs on event-loop of its parent QObject and works fine.
The only problem is that I have no clue how to terminate server on exit. I tried tweaking generated code for server (is that really a good idea by the way?)
int MySweetService::run(int port)
{ if (!soap_valid_socket(this->soap->master) && !soap_valid_socket(this->bind(NULL, port, 100)))
return this->soap->error;
for (;;) // =====> Maybe here I can put my while(module_is_running_atomic_bool) ?
{ if (!soap_valid_socket(this->accept()))
{ if (this->soap->errnum == 0) // timeout?
this->soap->error = SOAP_OK;
break;
}
if (this->serve())
break;
this->destroy();
}
return this->soap->error;
}
Calling soap_done(&soap) from another thread terminates blocking call to accept() and next your "serving" thread. It works for me on Windows but I doesn't on Linux - it looks like gsoap has some multitasking issue. You also need some boolean flag to let "serving" thread know that you shut it down and it's not just error in gsope.
I have a c++ app that has to create a gtk based popup on certain event.
Currently, I fork a thread on that event called _displaytask and that thread calls gtk_init().
The call to gtk_init hangs and never returns. Anyone knows here as to why the call hangs?
The gtk version is gtk+-2.0.
void* Gui::displayTask(void *data)
{
IDC_TRACE("Gui::display task tart");
Gui* obj=(Gui *)data;
if(obj!=NULL)
{
if( ! g_thread_supported() )
g_thread_init( NULL );
/* Secure gtk */
gdk_threads_init();
gdk_threads_enter();
IDC_TRACE("doing a gtk init");
gtk_init_check(0,0);
obj->initialise();
The control reaches gtk_init() but never gets past it to reach initialise.
http://www.bassi.io/articles/2014/08/27/gdk-and-threads/
Your order is wrong.
Should be:
enter
init
main
leave
Gui_display:04714807269964847148072699648
errno variable = 0
(process:26070): Gtk-WARNING **: This process is currently running setuid or setgid.
This is not a supported use of GTK+. You must create a helper
program instead. For further details, see:
http://www.gtk.org/setuid.html
Refusing to initialize GTK+.
I did not know this earlier.Got this error message.Now, the only way to do it would be in a different process
My application create child process using fork(). I have a signal handler in parent process. In signal handler i have to do different logic for parent and child.
ie in signal handler
case SIGSEGV:
if (parent)
{
cout<<"signal from parent";
}
else
{
cout <<"signal from child";
}
Is it possible? or i have to keep two different signal handlers?
Check the usage of signalfd (man signalfd) with select and read as this last will give you signalfd_siginfo structure, which has
uint32_t ssi_pid; /* PID of sender */
Maybe this will help you.
I using Indy with C++ Builder XE3. It's perfect system but i have some problems. IdTCPServer works really good but when i have some connections on him and i want to stop server then my application freezed. I try to tell how i do it step by step:
1) Starting application (and server listening)
2) wait for new connections (or simulate it, no difference)
3) when we have 10-15 connections - then try to stop server listening.
4) when code came to IdTCPServer1->Active = false - application will be frozen
i made little video. Maybe it explain situation much better. http://www.youtube.com/watch?v=BNgTxYbLx8g
And here my code:
OnConnect:
EnterCriticalSection(&CritLock);
++ActiveConnections;
SetActiveConnections(ActiveConnections);
LeaveCriticalSection(&CritLock);
OnDisconnect:
EnterCriticalSection(&CritLock);
--ActiveConnections;
SetActiveConnections(ActiveConnections);
LeaveCriticalSection(&CritLock);
StopServer Code:
void TForm1::StopServer()
{
TList *list = IdTCPServer1->Contexts->LockList();
try
{
for(int i = 0; i < list->Count; ++i)
{
TIdContext *AContext = reinterpret_cast<TIdContext*>(list->Items[i]);
try
{
if (AContext->Connection->Connected())
{
AContext->Connection->IOHandler->InputBuffer->Clear();
AContext->Connection->IOHandler->WriteBufferCancel();
AContext->Connection->IOHandler->WriteBufferClear();
AContext->Connection->IOHandler->WriteBufferClose();
AContext->Connection->IOHandler->CloseGracefully();
AContext->Connection->Disconnect();
}
}
catch (const Exception &e)
{
}
}
}
__finally
{
IdTCPServer1->Contexts->UnlockList();
}
IdTCPServer1->Contexts->Clear();
//IdTCPServer1->StopListening();
IdTCPServer1->Active = false;
}
Thanks for advise!
You need to get rid of all your StopServer() code except for the very last line. When TIdTCPServer is deactivated, it performs all necessary cleanups for you. DO NOT DO IT YOURSELF (especially since you are doing it wrong anyway).
void TForm1::StopServer()
{
IdTCPServer1->Active = false;
}
Now, with just that code, if your app is still freezing, then that means you are deadlocking the main thread. That happens if you call StopServer() in the context of the main thread and one of two things are happening in your server code:
one of your TIdTCPServer event handlers performs a synchronized operation to the main thread (either via TIdSync or TThread::Synchronize()).
one of your TIdTCPServer event handlers swallows Indy exceptions and does not allow TIdTCPServer to terminate one or more client threads correctly when needed.
Internally, the TIdTCPServer::Active property setter closes all active sockets and waits for their respective threads to fully terminate, blocking the calling thread until the property setter exits. If yoou are deactivating the server in the main thread and one of the server threads performs a sync that the main thread cannot process, or otherwise does not terminate correctly when it should be, that will block the server deactivation from exiting and thus deadlock the main thread.
So make sure that:
you are not performing sync operations to the main thread while the server is being deactivated by the main thread. If you must sync, then deactivate the server in a worker thread instead so the main thread is not blocked anymore.
your event handlers are not swallowing any Indy EIdException-derived exceptions in try/catch blocks. If you catch such an exception, re-throw it when you are finshed using it. Let TIdTCPServer handle any Indy exceptions so it can perform internal cleanups as needed.
Lastly, on a side note, you do not need to keep track of connections manually. TIdTCPServer already does that for you in the Contexts property. If you need to know how many clients are currently connected at any moment, simply Lock() the Contexts list, read its Count property (or do anything else you need to do with the clients), and then Unlock() the list.