Trying to prevent race conditions with pselect(), but signal won't interupt - c++

I am currently trying to implement a server in C++ using sockets. I am trying to prevent race conditions by blocking the SIGINT signal until it is stuck in the blocking pselect. From there, it should be exiting, changing my loop variable, and then quitting the thread. From my attempts at getting this working, it appears that it reaches the pselect(), but it does not get interrupted using my code. Any help is appreciated.
Listener.h:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
class CListener
{
public:
CListener();
void quitListener(void);
private:
void* InitListener(void);
static void* StartListenerThread(void* context);
static bool mbListening;
pthread_t mtThreadID;
};
Listener.cpp
#include <iostream>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <pthread.h>
#include <signal.h>
#include <errno.h>
#include "Listener.h"
bool CListener::mbListening = true;
CListener::CListener()
{
mbListening = true;
mtThreadID = 0;
pthread_create(&mtThreadID, NULL, &CListener::StartListenerThread, this);
}
void* CListener::StartListenerThread(void* context)
{
return ((CListener*)context)->InitListener();
}
void* CListener::InitListener()
{
sigset_t tSignalSet;
sigset_t tOriginalSignalSet;
sigemptyset(&tSignalSet);
sigaddset(&tSignalSet, SIGINT);
sigprocmask(SIG_BLOCK, &tSignalSet, &tOriginalSignalSet);
FD_ZERO(&tConnectionSet);
FD_SET(0, &tConnectionSet);
while(mbListening)
{
tSelectSet = tConnectionSet;
std::cout << "Reached pselect\n";
nReadyConnections = pselect(nSelectSocket+1, &tSelectSet,
NULL, NULL, NULL, &tOriginalSignalSet);
std::cout << "Broke out of pselect\n";
if(nReadyConnections < 0 && errno == EINTR)
{
mbListening = false;
}
}
pthread_exit(NULL);
return NULL;
}
void CListener::quitListener()
{
raise(SIGINT);
}
As long as I copied everything correctly fingers crossed you should just be able to run:
CListener tListener = CListener();
usleep(20000);
tListener.quitListener();
and the outputs should be displayed in terminal. My end goal is that I can allow for pselect to be interrupted without breaking any processing that may come after and allowing the thread to close gracefully. (blocking at pselect > recieve SIGINT > interupt pselect > return to loop > finish up and exit)

I've solved my own problem. Since I am generating a thread, I needed to add functions that allow for that, as well as adding a signal handler, like shown below.
void CListener::quitListener()
{
pthread_kill(mtThreadID,SIGINT);
}
void CListener::installSIGINTHandler()
{
signal(SIGINT, CListener::SIGINTHandler);
}
void CListener::SIGINTHandler(int signo)
{
mbListening = false;
}
And needed to change the sig mask setup to this:
pthread_sigmask(SIG_BLOCK, &tSignalSet, &tOriginalSignalSet);

Related

Valgrind with signal handling

In this code, I am trying to ipc with signals. Parent process will send SIGUSR1 signal to his children and waits for a SIGUSR1 signal for conformation of the signal arrive at the child end.
So I have;
Parent --> SIGUSR1 --> CHILD[i]
Parent <--- SIGUSR1 <--- CHILD[i]
this kind of communication between parent child processes. In normal executing, I have never face with a deadlock scenario. But when I run with valgrind, sometimes child process canot receive SIGUSR1 signal from parent process, which is start signal for communication.
Is the valgrind uses some mechanisms to avoid signal communication between processes ?
Parent process :
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#define CHILD_SIZE 80
sigset_t sigusr_mask;
pid_t children[CHILD_SIZE];
void SIGUSR1_handler(int sig)
{
write(1,"test.\n",6);
}
void init_signal()
{
sigset_t blck_msk;
sigemptyset(&blck_msk);
sigaddset(&blck_msk, SIGUSR1);
sigfillset(&sigusr_mask);
sigdelset(&sigusr_mask, SIGUSR1);
struct sigaction usr1_act;
memset(&usr1_act, 0, sizeof(usr1_act));
usr1_act.sa_handler = &SIGUSR1_handler;
sigaction(SIGUSR1, &usr1_act, NULL);
if(-1== sigprocmask(SIG_BLOCK, &blck_msk,NULL))
exit(-1);
}
void create_children(const char* processPath, int round_)
{
for(int i = 0; i < CHILD_SIZE; ++i)
{
pid_t pid_c = fork();
if(pid_c > 0) {
children[i] = pid_c;
}
else if(pid_c == 0)
{
char* arg[1024] = {"childProcess", (char*)0};
execve(processPath, arg, NULL);
}
}
}
// for the synchronization
void wait_childs()
{
for (int i = 0; i < CHILD_SIZE; ++i)
{
// send SIGUSR1 to the children.
kill(children[i], SIGUSR1);
printf("%d : %s\n", children[i],strerror(errno));
// wait until children reply by SIGUSR1
sigsuspend(&sigusr_mask);
}
}
int main(int argc, char const *argv[])
{
init_signal();
create_children("childProcess", 1);
wait_childs();
return (0);
}
Child process :
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include "utils.h"
sigset_t sigusr_mask;
void SIGUSR1_handler(int sig) {
write(1,"usr1\n",4);
}
void init_signal()
{
sigfillset(&sigusr_mask);
sigdelset(&sigusr_mask, SIGUSR1);
struct sigaction usr1_act;
memset(&usr1_act, 0, sizeof(usr1_act));
usr1_act.sa_handler = &SIGUSR1_handler;
sigaction(SIGUSR1, &usr1_act, NULL);
}
int main(int argc, char const *argv[])
{
init_signal();
printf("child %d waiting \n",getpid());
// wait until parent starts the communication.
sigsuspend(&sigusr_mask);
// after parent sends SIGUSR1, send reply.
kill(getppid(), SIGUSR1);
return 0;
}

How to access the Accepted and Close Event of QDialogbox

i have a Qdialogbox and in this qdialogbox i have a thread(named thread3) which executes Print_Descendants_key(IUIAutomation* pUIAutomation, IUIAutomationElement* pParent, int indent) function,
in this thread3.
so in my Accepted event(when i click okay in buttonbox) and closeEvent of dialog box, i want to quit/terminate this thread3. How can i do that ?
probably something like this ??
void KeyComd::closeEvent(QCloseEvent* event)
{
std::terminate();
thread3.terminate(); ??
}
void KeyComd::accepted()
{
std::terminate();
}
for reference here is my QDialog code
#include "KeyComd.h"
#include "ui_KeyComd.h"
#include <QtCore>
#include <QtGui>
#include <vector>
#include<QDebug>
#include "ExecutionContext.h"
#include "XMLParser.h"
#include "Logger.h"
#include "BlockCommand.h"
#include "UIAElementUtils.h"
ExecutionContext exc;
QStringList refreshed_elements;
KeyComd::KeyComd(QWidget *parent)
: QDialog(parent)
{
ui.setupUi(this);
HRESULT hr = exc.init();
}
KeyComd::~KeyComd()
{
}
void KeyComd::on_showbutton_clicked()
{
ui.elements_listwidget->clear();
desktop_elements.clear();
std::thread thread3(&KeyComd::Print_step, this); // Here it calls a thread, because of this thread ,the execution of "Print_Descendants_key" function happens in a separate thread from main thread
thread3.detach();
}
void KeyComd::Print_step()
{
Print_Descendants_key(exc.pUIAutomation, nullptr, 0);
}
void KeyComd::Print_Descendants_key(IUIAutomation* pUIAutomation, IUIAutomationElement* pParent, int indent)
{
///Function which appends 1000 list-items in a QListWidget called "elements_listwidget" in my QDialog.
}
There's no good way to force terminate a single thread- see this related SO answer. However, what you can do is signal that thread to end itself. Here's another relevant SO question, but also wrote a quick example demonstrating the technique with an atomic_bool:
#include <iostream>
#include <thread>
#include <atomic>
#include <chrono>
std::atomic_bool terminateThreads; // Atomic for setting and reading safely across threads
void runInfinitely() {
while (!terminateThreads) {
// Do some work
std::cout << "Running infinite thread..." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(150));
}
std::cout << "Terminated thread" << std::endl;
}
int main() {
// Create your thread as you normally would
std::thread infThread(runInfinitely);
// Whatever else you like to do...
std::this_thread::sleep_for(std::chrono::seconds(1));
// Once you're ready to end it, just set the atomic flag as appropriate
terminateThreads = true;
infThread.join(); // Optional in context of this SO question
std::cout << "End of main" << std::endl;
return 0;
}
However, going by that comment in KeyComd::Print_Descendants_key it seems like the function has a finite length and thus will naturally finish + clean itself up (relevant SO answer here). Thus, if you're fine waiting until the thread's function naturally ends, then you're not required to "terminate" or clean up the thread manually at all.

terminate a thread in C++ along with any process(es) it has spawned

I'm writing a fuzzer in C++ on linux. It spawns multiple threads and has a timeout function if the thread hangs for whatever reason. I cannot figure out the correct way to kill the thread off after it's timer runs out. What I am doing now is something along the lines of:
`
#include <signal.h>
#include <string.h>
#include <sys/wait.h>
#include <errno.h>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <chrono>
#include <thread>
#include <stdlib.h>
#include <sys/wait.h>
#include <stdio.h>
#include <vector>
#include <iostream>
#include <sys/time.h>
#include <random>
#include <cstdlib>
#include <climits>
#include <sstream>
#include <iomanip>
#include <unistd.h>
#include <cstring>
#define READ 0
#define WRITE 1
void reaper (int c_pid, int t_timeout) {
std::this_thread::sleep_for(std::chrono::milliseconds(t_timeout));
kill (c_pid, 9);
}
FILE * popen2 (std::string command, std::string type, int & pid, std::string low_lvl_user) {
pid_t child_pid;
int fd[2];
pipe(fd);
if((child_pid = fork()) == -1) {
perror("fork");
exit(1);
}
if (child_pid == 0) { // child begins
if (type == "r") {
close(fd[READ]); //Close the READ
dup2(fd[WRITE], 1); //Redirect stdout to pipe
}
else {
close(fd[WRITE]); //Close the WRITE
dup2(fd[READ], 0); //Redirect stdin to pipe
}
if (getuid() == 0) {
execl("/bin/su", "su", "-c", "/bin/sh", "-c", command.c_str(), low_lvl_user.c_str(), NULL); // fixes not being able to reap suid 0 processes
}
else {
execl("/bin/sh", "/bin/sh", "-c", command.c_str(), NULL); // runs it all
}
exit(0);
}
else {
if (type == "r") {
close(fd[WRITE]); //Close the WRITE
}
else {
close(fd[READ]); //Close the READ
}
}
pid = child_pid;
if (type == "r") {
return fdopen(fd[READ], "r");
}
return fdopen(fd[WRITE], "w");
}
int pclose2(FILE * fp, pid_t pid) // close it so we don't fuck outselves
{
int stat;
fclose(fp);
while (waitpid(pid, &stat, 0) == -1) {
if (errno != EINTR) {
stat = -1;
break;
}
}
return stat;
}
int spawn_ch (std::string out_str) {
std::string low_lvl_user = "nobody";
int t_timeout = 500;
int pid; // initializes child
FILE * fp = popen2(out_str, "r", pid, low_lvl_user); // opens child process fork
char command_out[4096] = {0};
std::stringstream output;
std::thread reaper_thread(reaper, pid, t_timeout); // takes care of killing it off if it takes too long
reaper_thread.join();
while (read(fileno(fp), command_out, sizeof(command_out)-1) != 0) {
output << std::string(command_out);
memset(&command_out, 0, sizeof(command_out));
}
pclose2(fp, pid);
std::string token;
}
int main () {
std::string command = "HOME=AAAAAAAAA MAIL=AA /usr/sbin/exim4 -Ac AAAAAA -G -MCP,9,-Mar -Mf -Mset b -S 999999 -X,,-bF 999 -bdf -bpc -bpr -bpru,,-bt -exim4,AAA, -f,AAAAAAAAA,-oA -oMa,5Mu^i, -oMaa,, -oMas,,-oMs -oX isotanr -odb -oee -oem,999, -oo,99999999 -r 999999999 -t -ti 999999";
std::vector<std::thread> threads;
int num_threads = 2;
for (int cur_thread=1; cur_thread <= num_threads; ++cur_thread) threads.push_back(std::thread(spawn_ch, command)); // Thrift Shop
for (auto& all_thread : threads) all_thread.join(); // is that your grandma's coat?
exit(0);
}
But as the processes are spawned as suid 101 in this example (or 0, or whatever else), the kill function can be run as root to reap the processes it spawned... which would work, except exim4 apparently tries to spawn multiple processes, and when one dies the others don't. Is there a way to let the program know what processes were spawned to kill them, or preferably, a way to just terminate the entire thread that spawned them (which I think should work, as if you ctrl+c my program it will kill off what it spawned)?
The whole codebase is on github.
Thanks in advance.
The std::thread class provides no means to arbitrary terminate an active execution thread. This functionality is not implemented in the current C++ standard.
The sample code you posted is pretty much the only thing that can be done using purely the functionality in the C++ and C libraries.
The POSIX thread API is an alternative option. It does provide the means to terminate an active thread; however that comes with many important caveats, and it's very difficult to avoid undefined behavior, when terminating an execution thread using pthread_cancel(), since this will not properly unwind the terminated thread's stack, and invoke all the needed destructors; furthermore the executing thread must reach a cancellation point, in order for pthread_cancel() to take effect.
Additionally, if the executing thread execs another process, the new process is going to replace the thread's entire process, not just the executing thread's context. If this was your intent all along, trying to cancel the thread won't do much good anyway, and you pretty much have to do what you are already doing.

End two alarm signals in Unix and count SIGINT

#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
using namespace std;
int count = 0;
void alarm2(int signo)
{
cout << count;
}
void alarm1(int signo)
{
signal(SIGALRM, alarm2);
cout << "ctrl+C";
alarm(10);
sleep(10);
}
int main()
{
signal(SIGALRM, alarm1);
alarm(3);
sleep(5);
}
I want that after 3 seconds I get the message "ctrl+C" and then another alarm set for 10 seconds; after that I should get the value of count. But when I run after just 10 sec I get "ctrl+C" and the value of count.
In your example you made many, many mistakes.
First of all look at documentation about which function is safe to call from
signal handlers:
https://www.securecoding.cert.org/confluence/display/seccode/SIG30-C.+Call+only+asynchronous-safe+functions+within+signal+handlers
Of course functions that can allocate memory is not safe to call, because of it is not safe to call malloc.
Because of it is not right to call printf or std::ostream::opeartor<< (std::cout <<) in signal handler.
Second, in documentation (type man 3 sleep) clearly written it is not safe mix sleep and alarm,
Third you not wait enough in main function, so it can exit before the second alarm handler run.
Here is how it can be done:
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
volatile sig_atomic_t done = 0;
void alarm2(int signo)
{
write(STDOUT_FILENO, "alarm2\n", sizeof("alarm2\n") - 1);
done = 1;
}
void alarm1(int signo)
{
signal(SIGALRM, alarm2);
write(STDOUT_FILENO, "ctrl+C\n", sizeof("ctrl+C\n") - 1);
alarm(10);
}
int main()
{
signal(SIGALRM, alarm1);
alarm(3);
while (done == 0)
sleep(1); //sleep can be wake up by alarm signal, so check flag
}
Add "<< endl;" to all your cout statements and try again.

Deadlock with sigsuspend()

I am trying to synchronize a father and children, the following code is not working (apparently usr_interrupt++ is not atomic). Semaphores does not seems to help either.
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <unistd.h>
#include <cstdlib>
#include <iostream>
#include <unistd.h>
#include <cstring>
#include <string>
#include <semaphore.h>
#include <fcntl.h>
using namespace std;
/* When a SIGUSR1 signal arrives, set this variable. */
volatile sig_atomic_t usr_interrupt;
sem_t *mutex;
char* SEM_NAME;
void
synch_signal (int sig)
{
// sem_wait(mutex);
usr_interrupt++;
// sem_post(mutex);
}
/* The child process executes this function. */
void
child_function (void)
{
/* Perform initialization. */
cerr << "I'm here!!! My pid is " << (int)getpid() << " my usr_int=" << usr_interrupt << endl;
/* Let parent know you're done. */
kill (getppid (), SIGUSR1);
/* Continue with execution. */
cerr << "Bye, now...." << endl;
exit(0);
}
int
main (void)
{
usr_interrupt = 0;
string s_sem_name = "lir";
SEM_NAME = new char[s_sem_name.size()+1];
memcpy(SEM_NAME, s_sem_name.c_str(), s_sem_name.size());
SEM_NAME[s_sem_name.size()] = '\0';
mutex = sem_open (SEM_NAME,O_CREAT,0644,1);
if(mutex == SEM_FAILED) {
perror("unable to create semaphore");
sem_unlink(SEM_NAME);
exit(-1);
}
struct sigaction usr_action;
sigset_t mask, oldmask;
pid_t child_id, child_id2;
/* Set up the mask of signals to temporarily block. */
sigemptyset (&mask);
sigaddset (&mask, SIGUSR1);
/* Establish the signal handler.*/
usr_action.sa_handler = synch_signal;
usr_action.sa_flags = 0;
sigaction (SIGUSR1, &usr_action, NULL);
/* Create the 2 children processes. */
child_id = fork ();
if (child_id == 0)
child_function ();
child_id2 = fork();
if (child_id2 == 0)
child_function ();
/* Wait for a signal to arrive. */
sigprocmask (SIG_BLOCK, &mask, &oldmask);
while (usr_interrupt != 2) {
sigsuspend (&oldmask);
}
sigprocmask (SIG_UNBLOCK, &mask, NULL);
/* Now continue execution. */
puts ("That's all, folks!");
return 0;
}
Can anyone suggest a fix? (I cannot use threads)
Best,
-- Liron
You can't count signals. Two signals of the same type has the same semantic meaning as one signal of that type. You could use two different signal types like USR1 and USR2. But honestly, you shouldn't use signals as a communication mechanism. Use something sensible like a pipe.