global static boolean pointer causes segmentation fault using pthread - c++

New to pthread programming, and stuck on this error when working on a C++&C mixed code.
What I have done is to call the c code in the thread created by the c++ code. There is a static boolean pointer is_center used in the thread and should got free when the thread finishes.
However I noticed that every time when the program processed into the c function, the value of the boolean pointer would be changed and the segmentation fault then happened due to the free(). And the problem only happens when the c code is used. Remove the c code and the multi-thread c++ part works well.
Detail code is as follows:
static bool *is_center;
// omit other codes in between ...
void streamCluster( PStream* stream)
{
// some code here ...
while(1){
// some code here ...
is_center = (bool*)calloc(points.num,sizeof(bool));
// start the parallel thread here.
// the c code is invoked in this function.
localSearch(&points,kmin, kmax,&kfinal); // parallel
free(is_center);
}
And the function using parallel is as follows (my c code is invoked in each thread):
void localSearch( Points* points, long kmin, long kmax, long* kfinal ) {
pthread_barrier_t barrier;
pthread_t* threads = new pthread_t[nproc];
pkmedian_arg_t* arg = new pkmedian_arg_t[nproc];
pthread_barrier_init(&barrier,NULL,nproc);
for( int i = 0; i < nproc; i++ ) {
arg[i].points = points;
arg[i].kmin = kmin;
arg[i].kmax = kmax;
arg[i].pid = i;
arg[i].kfinal = kfinal;
arg[i].barrier = &barrier;
pthread_create(threads+i,NULL,localSearchSub,(void*)&arg[i]);
}
for ( int i = 0; i < nproc; i++) {
pthread_join(threads[i],NULL);
}
delete[] threads;
delete[] arg;
pthread_barrier_destroy(&barrier);
}
Finally the function calling my c code:
void* localSearchSub(void* arg_) {
int eventSet = PAPI_NULL;
begin_papi_thread(&eventSet);
pkmedian_arg_t* arg= (pkmedian_arg_t*)arg_;
pkmedian(arg->points,arg->kmin,arg->kmax,arg->kfinal,arg->pid,arg->barrier);
end_papi_thread(&eventSet);
return NULL;
}
And from gdb, what I have got for the is_center is:
Breakpoint 2, localSearchSub (arg_=0x600000000000bc40) at streamcluster.cpp:1711
1711 end_papi_thread(&eventSet);
(gdb) s
Hardware watchpoint 1: is_center
Old value = (bool *) 0x600000000000bba0
New value = (bool *) 0xa93f3
0x400000000000d8d1 in localSearchSub (arg_=0x600000000000bc40) at streamcluster.cpp:1711
1711 end_papi_thread(&eventSet);
Any suggestions? Thanks in advance!
Some new information about the code: for the c code, I am using the PAPI package. I write my own papi wrapper to initialize and read system counters. The code is as follows:
void begin_papi_thread(int* eventSet)
{
int thread_id = pthread_self();
// Events
if (PAPI_create_eventset(eventSet)) {
PAPI_perror(return_value, error_string, PAPI_MAX_STR_LEN);
printf("*** ERROR *** Failed to create event set for thread %d: %s\n.", thread_id, error_string);
}
if((return_value = PAPI_add_events(*eventSet, event_code, event_num)) != PAPI_OK)
{
printf("*** ERROR *** Failed to add event for thread %d: %d.\n", thread_id, return_value);
}
// Start counting
if ((return_value = PAPI_start(*eventSet)) != PAPI_OK) {
PAPI_perror(return_value, error_string, PAPI_MAX_STR_LEN);
printf("*** ERROR *** PAPI failed to start the event for thread %d: %s.\n", thread_id, error_string);
}
}
void end_papi_thread(int* eventSet)
{
int thread_id = pthread_self();
int i;
long long * count_values = (long long*)malloc(sizeof(long long) * event_num);
if (PAPI_read(*eventSet, count_values) != PAPI_OK)
printf("*** ERROR *** Failed to load count values.\n");
if (PAPI_stop(*eventSet, &dummy_values) != PAPI_OK) {
PAPI_perror(return_value, error_string, PAPI_MAX_STR_LEN);
printf("*** ERROR *** PAPI failed to stop the event for thread %d: %s.\n", thread_id, error_string);
return;
}
if(PAPI_cleanup_eventset(*eventSet) != PAPI_OK)
printf("*** ERROR *** Clean up failed for the thread %d.\n", thread_id);
}

I don't think you've posted enough code to really understand your problem, but it looks suspicious that you've declared is_center global. I assume you're using it in more than one place, possibly by multiple threads (localSearchSub mentions it, which is your worker thread function).
If is_center is being read or written by multiple threads, you probably want to protect it with a pthread mutex. You say it is "freed when the thread finishes", but you should be aware that there are nprocs threads, and it looks like they're all working on an array of is_center[points] bools. If points != nproc, this could b e a bad thing[1]. Each thread should probably work on its own array, and localSearch should aggregate the results.
The xxx_papi_thread functions don't get any hits on Google, so I can only imagine it's your own... unlikely we'll be able to help you, if the problem is in there :)
[1]: Even if points == nproc, it is not necessarily OK to write to different elements of an array from multiple threads (it's compiler and processor dependent). Be safe, use a mutex.
Also, this is tagged C++. Can you replace the calloc and dynamic arrays (using new) with vectors? It might end up easier to debug, and it certainly ends up easier to maintain. Why do you hate and want to punish the readers of your code? ;)

Related

How to use signals in C++ and How they react?

I am trying to learn all interactions about signals and I discovered a funny interaction in it I can't understand.
Here's an abstract of the program, Im instructed to do execvp with grandchild, while child needs to wait for grandchild to finish. It runs correctly when without any signal interactions.
void say_Hi(int num) { printf("Finished\n"); }
int main() {
int i = 2;
char *command1[] = {"sleep", "5", NULL};
char *command2[] = {"sleep", "10", NULL};
signal(SIGCHLD, SIG_IGN);
signal(SIGUSR1, say_Hi);
while(i > 0) {
pid_t pid = fork();
if (pid == 0) {
pid_t pidChild = fork();
if (pidChild == 0) {
if (i == 2) {
execvp(command1[0], command1);
} else {
execvp(command2[0], command2);
}
} else if (pidChild > 0) {
waitpid(pidChild, 0, 0);
// kill(pid, SIGUSR1);
printf("pid finished: %d\n", pidChild);
exit(EXIT_FAILURE);
}
exit(EXIT_FAILURE);
} else {
//parent immediately goes to next loop
i--;
}
}
cin >> i; //just for me to pause and observate answers above
return 0;
}
As shown above, kill(pid, SIGUSR1); is commented, the program runs correctly.
Output:
pid finished: 638532 //after 5 sec
pid finished: 638533 //after 10 sec
However, when it is uncommented. Output becomes:
Finished
pid finished: 638610 //after 5 sec
Finished
Finished
Finished
Finished
pid finished: 638611 //after 5 sec too, why?
Finished
I would like to ask:
The whole program finished at once after 5 secs and a total of 6 "Finished" is printed out. Why is so?
Is there a way for me to modify it so that say_Hi function run in a total of two times only, in a correct time interval?
Please forgive me if my code looks stupid or bulky, I'm a newbie in programming. Any Comments about my code and help are appreciated!
void say_Hi(int num) { printf("Finished\n"); }
printf cannot be called in a signal handler. None of the C or the C++ library functions (with few exceptions) can be called in the signal handler. You can't even allocate or delete any memory from a signal handler (using either the C or the C++ library), except by using low-level OS calls like brk() or sbrk(). This is because of a very simple reason: that none of the C or the C++ library functions are signal-safe (with very few exceptions). Only function calls that are explicitly designated as "signal-safe" can be called from a signal handler. None of the C or C++ library functions or classes (with few exceptions) are signal-safe. The End.
The only thing that can be called from a signal handler are low-level operating system calls, like read() and write(), that operate directly on file handles. They are, by definition, signal-safe.
For this simple reason the shown code, when it comes to signals, is undefined behavior. Trying to analyze or figure out your programs behavior, from that respect, such as why or why not you see this message, is completely pointless. It cannot be logically analyzed. This is undefined behavior.
Answer:
kill(getpid(), SIG_USR1);

terminate called without an active exception when calling pthread_exit in segmentation fault handler

How are you?
I am going to fix the segmentation fault in a worker thread on Ubuntu 18.04.
My code is the following.
#include <thread>
#include <signal.h>
#include <string.h>
#include <pthread.h>
#include <opencv2/opencv.hpp>
void sigsegv_handler(int signum, siginfo_t *info, void *data)
{
printf("The thread was crashed\n");
pthread_exit(NULL);
}
void sleep_ms(int milliseconds)
{
#ifdef WIN32
Sleep(milliseconds);
#elif _POSIX_C_SOURCE >= 199309L
struct timespec ts;
ts.tv_sec = milliseconds / 1000;
ts.tv_nsec = (milliseconds % 1000) * 1000000;
nanosleep(&ts, NULL);
#else
usleep(milliseconds * 1000);
#endif
}
void thread_func(int i)
{
if(i == 3)
{
int *p = 0;
*p = 10;
}
printf("A new thread ran successfully\n");
}
int main()
{
/* Set SIGSEGV handler. */
struct sigaction handler;
sigemptyset(&handler.sa_mask);
handler.sa_sigaction = &sigsegv_handler;
handler.sa_flags = SA_SIGINFO;
if (sigaction(SIGSEGV, &handler, NULL) == -1)
fprintf(stderr, "Cannot set SIGSEGV handler: %s.\n", strerror(errno));
int i = 0;
while(1)
{
std::thread writer_thread(thread_func, i);
writer_thread.detach();
sleep_ms(1000);
printf("%d\n", i++);
}
return 0;
}
The code works well.
The output of this code are following.
A new thread ran successfully
0
A new thread ran successfully
1
A new thread ran successfully
2
The thread was crashed
3
A new thread ran successfully
4
A new thread ran successfully
5
A new thread ran successfully
6
A new thread ran successfully
7
But if I change the function "thread_func" as the following, the program is crashed.
void thread_func(int i)
{
if(i == 3)
{
int *p = 0;
*p = 10;
}
cv::Mat img(100, 100, CV_8UC3); // newly inserted
cv::resize(img, img, cv::Size(200, 200)); //newly inserted
printf("A new thread ran successfully\n");
}
The error messages are the following.
A new thread ran successfully
0
A new thread ran successfully
1
A new thread ran successfully
2
The thread was crashed
terminate called without an active exception
Aborted (core dumped)
Of course, I am sure there is no issue in OpenCV module.
Could u help me to fix this issue?
Thanks
The simple answer is you can't do this:
void sigsegv_handler(int signum, siginfo_t *info, void *data)
{
printf("The thread was crashed\n");
pthread_exit(NULL);
}
First, per 7.1.4 Use of library functions, paragraph 4 of the C 11 standard:
The functions in the standard library are not guaranteed to be reentrant and may modify objects with static or thread storage duration.
Or, as summarized by footnote 188:
Thus, a signal handler cannot, in general, call standard library functions.
So, absent specific guarantees from your platform about what functions you can safely call from a signal handler, you can not make any function calls from within a signal handler.
But since you are calling pthread_exit(), assuming you're using a POSIX system, POSIX does provide some guarantees about what functions you can call, termed "async-signal-safe, at https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03. The Linux-specific list can be found at https://man7.org/linux/man-pages/man7/signal-safety.7.html
Note that neither printf() nor pthread_exit() are on either list.
Calling printf() from within a SIGSEGV signal handler is going to be dangerous - most implementations of printf() will use some form of malloc()/free(), and SIGSEGV is often a result of a malloc()/new/free()/delete operation encountering that corrupted heap. Heap operations tend to happen under a lock of some sort to protect against simultaneous modification of heap state, so calling printf() in a SIGSEGV handler of all things creates a huge deadlock risk.
And pthread_exit() will also cause huge problems - it's not only trying to change process state in the process's address space, it's trying to make changes to the process state in kernel space. From within a signal handler, that's simply not going to work.

Capture value from infinite thread c++

I have created a thread that is running parrallel with main thread. Both threads are doing something infinitely (both have while(true) statement). Main thread while(true) is creating game logic in frames, and second thread is receiveing messages from socket.
Is it possible to get string value of message received from second thread into main thread each frame without returning from second thread?
In c#, I would do it with method invoker but I didn't find anything helpful for c++. Is it possible to perform in c++?
Function which creates thread:
void ReceiveMessage() {
//std::promise<int> p;
//auto f = p.get_future();
char buf[1024];
string usernput;
int bytesReceived = 0;
std::thread receiveMessage(&FactoredThread::ThreadFunction, *this);
receiveMessage.detach();
//pokusajporuke = f.get();
}
ThreadFunction:
void ThreadFunction() {
bytesReceived = 0;
while (true) {
bytesReceived = recv(sock, buf, 1024, 0);
if (bytesReceived > 0) {
string primljeniString = "";
for (int i = 0; i < sizeof(buf); i++) {
if (buf[i] != 0)
{
primljeniString += buf[i];
}
}
ZeroMemory(buf, 1024);
pokusajporuke = primljeniString;
}
}
}
So how to get "pokusajporuke" string for main thread?
Yes, sure. There are many ways of solving this problem.
One way is to use signals and slots, like in Qt. For pure C++ you could use Boost.Signals2, which is thread safe.
Or you can realize pattern producer-consumer. One thread(producer) puts values into buffer(it should be thread-safe buffer), second takes them from there.
I think, for your problem second way is better.
Actually what I needed was global static variable. And then with another method from main thread I put that global variable into class property

Returning code from pthread creation in C++ is 11

I have thread creation problem using Pthread. My code is as follows. I show only some portion due to space constraints.
Main.c create Detectdirection instance and send to the function.
d = new Detectdirection();
while(run)
{
int ret = d->run_parallel(d);
if(ret == -1)
run = false;
}
My Detectdirection Class has two functions to run in parallel:
class Detectdirection{
public:
int run_parallel(void*p);
void *Tracking(void *p);
static void *Tracking_helper(void * p);
void *ReadImage(void *p );
static void *ReadImage_helper(void *p );
private:
pthread_t thread[2];
}
void *Detectdirection::ReadImage(void *p){
Detectdirection *app = (Detectdirection*)p;
while(run){
}
pthread_exit(NULL);
}
void *Detectdirection::Tracking(void *p){
Detectdirection *app = (Detectdirection*)p;
while(run){
}
pthread_exit(NULL);
}
void *Detectdirection::Tracking_helper(void *p){
Detectdirection *app = (Detectdirection*)p;
return ((Detectdirection*)p)->Tracking(app);
}
void *Detectdirection::ReadImage_helper(void *p ){
Detectdirection *app = (Detectdirection*)p;
return ((Detectdirection*)p)->ReadImage(app);
}
int Detectdirection::run_parallel(void* p){
Detectdirection *app = (Detectdirection*)p;
int rc = pthread_create(&thread[0], NULL, app->ReadImage_helper, app);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
return -1;
}
rc = pthread_create(&thread[1], NULL, app->Tracking_helper, app);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
return -1;
}
return 0;
}
Compile is ok and when I run, I have thread creation error. That sort of return type 11 happens only when many threads are created. But now I create only two thread and I have that error. What could be wrong?
I believe your are getting EAGAIN (based on the error code 11). That (obivously) means your system doesn't have enough resources to create threads anymore.
POSIX documentation says:
[EAGAIN] The system lacked the necessary resources to create another
thread, or the system-imposed limit on the total number of threads in
a process {PTHREAD_THREADS_MAX} would be exceeded.
I am not quite sure the following is true.
But now I create only two thread and I have that error. What could be wrong?
Here,
while(run)
{
int ret = d->run_parallel(d);
if(ret == -1)
run = false;
}
You are creating in a loop and each call d->run_parallel() creates two threads. So, you are potentially creating infinite number of threads
as the loop only breaks when pthread_create() fails. So, you may want to look at this loop carefully whether you really want to do as it is right now.
You don't seem to join with the threads you create. So, you could detach the threads so that thread-specific resources are released immediately when the thread(s) exit.
You can do:
pthread_detach(pthread_self());
in both ReadImage_helper() and Tracking_helper() functions to detach them. This could potentially solve your resource issue.
If it's still present then you have to look at ways to limit the number of threads that are simultaneously running on your system. One possible option is to use thread pools -- create a fixed number of threads and assign them new tasks as the threads complete their current task(s).

pthread_attr_setstacksize and pthread_exit

I have a question about C concurrency programming in Embedded System with about 64Mb Ram.
Especially, I want to reduce the default memory used by a Thread, so I have defined:
pthread_attr_t attr_test;
size_t stacksize = 0x186A0; // 100Kbyte
pthread_attr_init(&attr_test);
pthread_attr_setdetachstate(&attr_test, PTHREAD_CREATE_DETACHED);
pthread_attr_setstacksize(&attr_test, stacksize);
So, When the Thread starts, it uses only 100Kbyte of virtual Memory.
BUT when the Thread ends and calls pthread_exit, the virtual Memory used by the process, increases rapidly!....
Why? What can I do?
Thanks!
UPDATE:
Thread ->
void *thread_test(void *arg1) {
int *param;
param = (int*)arg1;
printf("Thread %d start\n", *param);
pthread_cond_wait(&condition[*param], &mutex[*param]);
printf("Thread %d stop\n",*param);
pthread_exit(0);
}
Main ->
int main(void) {
pthread_t IDthread[MAX_THREADS];
int param[MAX_THREADS];
int pointer;
int i, keyb;
void *stkaddr;
size_t stacksize;
puts("!!! THREAD TEST !!!");
printf("Process ID %d\n\n", getpid());
for(i=0; i<MAX_THREADS; i++)
{
pthread_cond_init(&condition[i], NULL);
pthread_mutex_init(&mutex[i], NULL);
IDthread[i] = 0;
param[i] = i;
}
stacksize = 0x186A0; // 100Kbyte
pthread_attr_init(&attr_test);
pthread_attr_setdetachstate(&attr_test, PTHREAD_CREATE_DETACHED);
/* setting the size of the stack also */
pthread_attr_setstacksize(&attr_test, stacksize);
pointer = 0;
do {
keyb = getchar();
if (keyb == '1')
{
if (pointer < MAX_THREADS)
{
pthread_create(&IDthread[pointer], &attr_test, thread_test, &param[pointer]);
sleep(1);
pointer++;
}
else
puts("MAX Threads Number");
}
if (keyb == '2')
{
if (pointer != 0)
{
pointer--;
pthread_cond_signal(&condition[pointer]);
sleep(1);
}
else
puts("0 Thread is running");
}
} while (keyb != '0');
printf("FINE\n");
return EXIT_SUCCESS;
}
There is a known issue with the joinable or detached threads, quoting from the manual:
Only when a
terminated joinable thread has been joined are the last of its
resources released back to the system. When a detached thread
terminates, its resources are automatically released back to the
system
you can make the thread detachable with:
pthread_attr_setdetachstate(3)
There are some problems with your test.
At first, pthread_attr_setstacksize has the following documentation:
The stack size attribute determines the minimum size (in bytes) that will be allocated for threads created using the thread attributes object attr.
So each thread could use more than what you have set. But more than that, threads may allocate memory from the OS to use as stack. And this also applies to the main thread.
Therefore I don't think there is a way to achieve what you want by looking at the result of top command, since this information is only visible from within the thread itself.
Also note that the virtual memory used by the process is not related to the amount of RAM used by the process.
Here is something you can try to check the total stack of a thread.