Why do I keep getting segmentation fault in my C program - c

I've been trying to implement thread synchronization on C. However, I keep getting the segmentation fault when my invoke the function that I want the thread to execute. So anyone can suggest the solution on for this problem?
Here is my code
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#define N 5
#define M 3
#define LEFT (robot_id - 1) % N
#define RIGHT (robot_id + 1) % N
pthread_t robots_id[N];
sem_t simulations[M];
pthread_mutex_t sever_mutex;
void Learning(int robot_id)
{
printf("learning robot = %d\n", robot_id);
}
void *robotAct(void *id)
{
int *robot_id = id;
printf("robot id = %d\n", robot_id);
Learning(*robot_id);
}
int main(int argc, char *argv[])
{
int E, T;
E = atoi(argv[1]);
T = atoi(argv[2]);
printf("Initializing Robot!\n");
//Initializes the simulations
for (int i = 0; i < M; i++)
{
sem_init(&simulations[i], 0, 0);
}
//Initializes the robots
for (int i = 0; i < N; i++)
{
printf("Robot %d is created\n", i + 1);
pthread_create(&robots_id[i], NULL, robotAct, (void *)i + 1);
}
sleep(T);
printf("Terminating Robots\n");
for (int i = 0; i < N; i++)
{
pthread_cancel(robots_id[i]);
}
printf("Termination is completed!\n");
printf("-------Report-------------\n");
//getReport();
return 0;
}
Here is my result that I keep getting
Initializing Robot!
Robot 1 is created
Robot 2 is created
Robot 3 is created
robot id = 1
robot id = 2
Robot 4 is created
robot id = 3
[1] 54477 segmentation fault ./project 5 10

The main issue is explained in my comment:
You're not passing a valid pointer to the thread function. You sort of, mostly, almost get away with the misuse of it in the printf() call in robotAct(); you emphatically do not get away with it in the call to Learning() where you dereference the invalid non-pointer.
A solution is to create an array of integers in the main program which holds robot ID numbers (int id[N];). Then, initialize each element and pass &id[i] to pthread_create().
You should not print addresses with the %d format (even though it works on 32-bit systems; it does not work on 64-bit systems). The correct technique is to use %p to format the address. Or, in this case, print the integer and not the address using *robot_id.
The code that follows has minimal adaptations to the original code and has not been compiled or tested (there could be problems outside the lines changed):
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#define N 5
#define M 3
#define LEFT (robot_id - 1) % N
#define RIGHT (robot_id + 1) % N
pthread_t robots_id[N];
sem_t simulations[M];
pthread_mutex_t sever_mutex;
void Learning(int robot_id)
{
printf("learning robot = %d\n", robot_id);
}
void *robotAct(void *id)
{
int *robot_id = id;
printf("robot id = %d\n", *robot_id); // Changed
Learning(*robot_id);
return 0; // Added
}
int main(int argc, char *argv[])
{
int E, T;
int id[N]; // Added
E = atoi(argv[1]);
T = atoi(argv[2]);
printf("Initializing Robot!\n");
//Initializes the simulations
for (int i = 0; i < M; i++)
{
sem_init(&simulations[i], 0, 0);
}
//Initializes the robots
for (int i = 0; i < N; i++)
{
printf("Robot %d is created\n", i + 1);
id[i] = i + 1; // Added
pthread_create(&robots_id[i], NULL, robotAct, &id[i]); // Changed
}
sleep(T);
printf("Terminating Robots\n");
for (int i = 0; i < N; i++)
{
pthread_cancel(robots_id[i]);
}
printf("Termination is completed!\n");
printf("-------Report-------------\n");
//getReport();
return 0;
}
Avoid using pthread_cancel() for ending the threads; the threads should terminate under control. For example, there might be a flag that you set in the main thread to indicate that the threads should cease, and they'd check that periodically. Normally, pthread_join() is used to clean up the completed threads.
For future posts, please read about how to create an MCVE (Minimal, Complete, Verifiable Example). There are parts of the code shown that are not relevant to the problem — the mutex and the semaphores, for example, are not really used.

Related

Printf with multiple threads (for real-time logging) in C

I have written a code for real-time logging. Here's the pseudo-code:
initialize Q; //buffer structure stores values to be printed
log(input)
{
push input to Q;
}
printLog() //infinte loop
{
loop(1)
{
if(Q is not empty)
{
values = pop(Q);
msg = string(values); //formating values into a message string
print(msg);
}
}
}
mainFunction()
{
loop(1)
{
/*
insert operations to be performed
*/
log(values); //log function called
}
}
main()
{
Create 4 threads; //1 mainFunction and 3 printLog
Bind them to CPUs;
}
I'm using atomic operations instead of locks.
When I print the output to the console, I see that each thread prints consecutively for a while. This must mean that once a thread enters printLog(), the other threads are inactive for a while.
What I want instead is while one thread is printing, another thread formats the next value popped from Q and prints it right after. How can this be achieved?
EDIT: I've realized the above information isn't sufficient. Here are some other details.
Buffer structure Q is a circular array of fixed size.
Pushing information to Q is faster than popping+printing. So by the time the Buffer structure is full, I want most of the information to be printed.
NOTE: mainFunction thread shouldn't wait to fill Buffer when it is full.
I'm trying to utilize all the threads at a given time. Currently, after one thread prints, the same thread reads and prints the next value (this means the other 2 threads are inactive).
Here's the actual code:
//use gcc main.c -o run -pthread
#define _GNU_SOURCE
#include <unistd.h>
#include <stdint.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <pthread.h>
#include <math.h>
#include <signal.h>
#include <stdlib.h>
#define N 3
/* Buffer size */
#define BUFFER_SIZE 1000
struct values
{
uint64_t num;
char msg[20];
};
struct values Q[BUFFER_SIZE];
int readID = -1;
int writeID = -1;
int currCount = 0;
void Log(uint64_t n, char* m)
{
int i;
if (__sync_fetch_and_add(&currCount,1) < BUFFER_SIZE)
{
i = __sync_fetch_and_add(&writeID,1);
i = i%BUFFER_SIZE;
Q[i].num = n;
strcpy(Q[i].msg, m);
}
else __sync_fetch_and_add(&currCount,-1);
}
void *printLog(void *x)
{
int thID = *((int*)(x));
int i;
while(1)
{
if(__sync_fetch_and_add(&currCount,-1)>=0)
{
i = __sync_fetch_and_add(&readID,1);
i = i%BUFFER_SIZE;
printf("ThreadID: %2d, count: %10d, message: %15s\n",thID,Q[i].num,Q[i].msg);
}
else __sync_fetch_and_add(&currCount,1);
}
}
void *mainFunction()
{
uint64_t i = 0;
while(1)
{
Log(i,"Custom Message");
i++;
usleep(50);
}
}
int main()
{
/* Set main() Thread CPU */
cpu_set_t cpusetMain;
CPU_ZERO(&cpusetMain);
CPU_SET(0, &cpusetMain);
if(0 != pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpusetMain))
printf("pthread_setaffinity_np failed for CPU: 0\n");
int LogThID[N+1];
pthread_t LogThreads[N+1];
/* Create Threads */
if (pthread_create(&LogThreads[0], NULL, &mainFunction, NULL) != 0){return 0;}
for(int i=1; i<N+1 ; i++)
{
LogThID[i] = i;
if (pthread_create(&LogThreads[i], NULL, &printLog, &LogThID[i]) != 0){return i;}
}
/* Set CPUs */
cpu_set_t cpuset[N+1];
for(int i=0; i<N+1; i++)
{
CPU_ZERO(&cpuset[i]);
CPU_SET(i+1, &cpuset[i]);
if(0 != pthread_setaffinity_np(LogThreads[i], sizeof(cpu_set_t), &cpuset[i]))
printf("pthread_setaffinity_np failed for CPU: %d\n", i+1);
}
struct sched_param param[N+1];
for(int i=0; i<N+1; i++)
{
param[i].sched_priority = 91;
if(0 != pthread_setschedparam(LogThreads[i],SCHED_FIFO,&param[i]))
printf("pthread_setschedparam failed for CPU: %d\n", i);
}
/* Join threads */
for(int i=0; i<N+1; i++)
{
pthread_join(LogThreads[i], NULL);
}
return 0;
}

multithreading program to perform word count frequency- Segmentation fault

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
pthread_mutex_t lock;
//typedef struct for a word
typedef struct {
char word[101];
int frequency;
}Word;
//struct for thread
struct ft{
char* fileName;
int start;
int stop;
};
//compare frequency of 2 words
int compareWords(const void *f1, const void *f2){
Word *a = (Word *)f1;
Word *b = (Word *)f2;
return (b->frequency - a->frequency);
}
//count frequency of a word
void countFrequency(void *arg){
pthread_mutex_lock(&lock);
int i, c;
struct ft* fi = (struct ft*)arg;
FILE *file = fopen(fi->fileName,"r");
fseek(file,fi->start,SEEK_SET);
for(i = 0; i < fi->stop - fi->start; i++){
c = getc(file);
//printf("%d\n", c);
//frequency count
}
fclose(file);
pthread_mutex_unlock(&lock);
}
int main (int argc, char **argv){
//variabies for <time.h>
struct timespec startTime;
struct timespec endTime;
clock_gettime(CLOCK_REALTIME, &startTime);
/*------------main------------------*/
//variables
int nthreads; //number of threads
int chunkSize; //each threas processing size
//if user input is not correct, inform
if(argc < 3){
printf("./a.out text_file #ofthreads \n");
exit(-1);
}
nthreads = atoi(argv[2]);
chunkSize = sizeof(argv[1])/nthreads;
//declare threads and default attributes
pthread_t threads[nthreads];
pthread_attr_t attr;
pthread_attr_init(&attr);
//run threads in parallel
int i;
for (i = 0; i < nthreads; i++){
struct ft data[nthreads];
data[i].start = i*chunkSize;
data[i].stop = data[i].start+chunkSize;
data[i].fileName = argv[1];
// Create a new thread for every segment, and count word frequency for each
pthread_create(&threads[i], &attr, (void*) countFrequency, (void*) &data[i]);
}
//wait for results (all threads)
for (i = 0; i < nthreads; i++){
pthread_join(threads[i], NULL);
}
//func of <time.h>
clock_gettime(CLOCK_REALTIME, &endTime);
time_t sec = endTime.tv_sec - startTime.tv_sec;
long n_sec = endTime.tv_nsec - startTime.tv_nsec;
if (endTime.tv_nsec < startTime.tv_nsec)
{
--sec;
n_sec = n_sec + 1000000000L;
}
printf("Total Time was %ld.%09ld seconds\n", sec, n_sec);
}
I'm working on this program to use multiple threads to read and process a large text file and perform a word count frequency of the top 10 most frequent words in the text that are longer than 6 characters long. But I keep getting the segmentation fault error im not sure why, does anybody have any idea.?
This code:
for (i = 0; i < nthreads; i++){
struct ft data[nthreads];
declares data that is live (legal to use) for the duration of this for loop. This code:
pthread_create(&threads[i], &attr, (void*) countFrequency, (void*) &data[i]);
}
passes the address of data into the threads, and then exits the loop. Once the loop is done, data is no longer live, and all access to it leads to undefined behavior.
The compiler is free to write anything else to the memory where data used to be.
The immediate cause of the crash is that if one of the threads doesn't execute fopen before data is overwritten, then fopen may fail, and you don't check for the failure in fopen.
P.S.
As Eraklon noted, this code: chunkSize = sizeof(argv[1])/nthreads; will divide sizeof(char*) (either 4 or 8 depending on whether you build for 32-bit or for 64-bit) by number of threads. That is unlikely to be what you want, and will yield chinkSize==0 for nthreads > 4 on 32-bit and nthreads > 8 on 64-bit machines.
P.P.S.
There is a concurrency bug in your program as well: since each of the countFrequency invocations locks the same lock for the entire duration, they will all run in sequence (one after another), never in parallel. Thus your program will be slower than if you just did all the work in your main thread.

Pass an int array in pthread function in C

I'm coding a multithreaded program for exercise. Given an array (100 positions) of random numbers, I have to divide it by 5 arrays and give them to 5 pthreads in order to find the maximum and return these values to the main function that find the maximum between them. These is my code so far:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define NUM_THREADS 5
#define DIM_VETTORE 100
void *Calcola_max(void* args){
}
int main(){
int vettore[DIM_VETTORE];
int t;
int i;
srand(time(NULL));
/*riempio il vettore con numeri random*/
for (i=0; i<DIM_VETTORE; i++){
vettore[i]=rand() % 500 + 1;
printf("Numero in posizione %d: %d\n", i,vettore[i]);
}
/*indico le dimensioni di ogni array splittato*/
int dimensione_split=DIM_VETTORE/NUM_THREADS;
printf("Dimensione degli array splittati: %d\n", dimensione_split);
/*creo tutti i thread*/
pthread_t thread[NUM_THREADS];
for (t=0;t<NUM_THREADS; t++){
printf("Main: creazione thread %d\n", t);
int rc;
rc=pthread_create(&thread[t], NULL, Calcola_max, &vettore);
if (rc) {
printf("ERRORE: %d\n", rc);
exit(-1);
}
}
}
My question are: how can I split the array? And how can I pass each array to each pthread? Thanks in advance
So, I've edited my code but this time it gives me segmentation fault after the pthread creation. IMO I'm wrong to pass the argument of thread function in this way:
...
pthread_create(&thread[t], NULL, Calcola_max, (void *)&start[i]);
...
void *Calcola_max(void *a){
...
s = *(int *)a;
...
Here is my entire code:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define NUM_THREADS 5
#define DIM_VETTORE 100
int vettore[DIM_VETTORE];
int start[100];
int max[100]; //vettore dove vanno tutti i minimi calcolati dai pthread
void *Calcola_max(void *a){
int array;
int n=DIM_VETTORE/NUM_THREADS;
int s, i;
int start, stop;
int massimo;
s = *(int *)a;
start = s * n;
if ( s != (NUM_THREADS-1) )
{
stop = start + n;
}
else
{
stop = DIM_VETTORE;
}
massimo=vettore[start];
for (i = start+1; i < stop; i++ )
{
if ( vettore[i] > massimo )
massimo = vettore[i];
}
max[s] = massimo;
//array = (int) a;
int k;
int max=0;
for (k=0; k<DIM_VETTORE; k++){ //qui devo mettere il range corrente del vettore, o mettere uno split di vettore
printf("Massimo corrente: %d\n",max);
if (vettore[k]>max) max=vettore[k];
}
//return(NULL); /* Thread exits (dies) */
pthread_exit;
}
int main(){
//int vettore[DIM_VETTORE];
int massimo; //vettore dei minimi finale in cui opero confronto e calcolo il minimo
int t;
int i, j;
srand(time(NULL));
/*riempio il vettore con numeri random*/
for (i=0; i<DIM_VETTORE; i++){
//int num; //contenitore numero random
vettore[i]=rand() % 500 + 1;
//printf("Numero in posizione %d: %d\n", i,vettore[i]);
}
/*indico le dimensioni di ogni array splittato*/
int dimensione_split=DIM_VETTORE/NUM_THREADS;
printf("Dimensione degli array splittati: %d\n", dimensione_split);
/*creo tutti i thread*/
pthread_t thread[NUM_THREADS];
for (t=0;t<NUM_THREADS; t++){
start[i] = i;
printf("Main: creazione thread %d\n", t);
int rc;
//int pos_vettore;
//for (pos_vettore=0; pos_vettore<100; pos_vettore+20){
rc=pthread_create(&thread[t], NULL, Calcola_max, (void *)&start[i]);
if (rc) {
printf("ERRORE: %d\n", rc);
exit(-1);
}
//}
}
/*joino i threads*/
for (i = 0; i < NUM_THREADS; i++)
pthread_join(thread[i], NULL);
massimo= max[0];
sleep(3);
for (i = 1; i < NUM_THREADS; i++)
if ( max[i] > massimo )
massimo = max[i];
printf("Il massimo è: %d\n", massimo);
}
Your pthreads can access the array in your main program easily. You won't need to split the array for that. Just make sure that the pthreads are modifiying different parts of the main array. Use a struct or typedef to pass the relevant information to the pthread functions.
As mentioned, you don't split or copy the array.
Threads share the same regions of memory as the process that creates them, so you could just pass around the array.
If the aim of the game is to find some perf gain from using threads, then you almost certainly don't want to use heap allocated memory.
It's got to be said that there are probably better ways, I would probably look to SIMD or some other SSE extension before threads, but whatever ...
The following example, which has had about 5 minutes thought, and requires better error checking, and verification of the logic (because it's 9am on Sunday), demonstrates how I think the most efficient way to thread the calculations might be.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <pthread.h>
#define THREADS 5
#define DATA 100
typedef struct _pthread_arg_t {
pthread_t thread;
int *data;
unsigned int end;
int max;
} pthread_arg_t;
void* pthread_routine(void *arg) {
pthread_arg_t *info = (pthread_arg_t*) arg;
int *it = info->data,
*end = info->data + info->end;
while (it < end) {
if (*it > info->max) {
info->max = *it;
}
it++;
}
pthread_exit(NULL);
}
int main(int argc, char *argv[]) {
pthread_arg_t threads[THREADS];
int data[DATA],
thread = 0,
limit = 0,
result = 0;
memset(&threads, 0, sizeof(pthread_arg_t) * THREADS);
memset(&data, 0, sizeof(int) * DATA);
while (limit < DATA) {
/* you can replace this with randomm number */
data[limit] = limit;
limit++;
}
limit = DATA/THREADS;
while (thread < THREADS) {
threads[thread].data = &data[thread * limit];
threads[thread].end = limit;
if (pthread_create(&threads[thread].thread, NULL, pthread_routine, &threads[thread]) != 0) {
/* do something */
return 1;
}
thread++;
}
thread = 0;
while (thread < THREADS) {
if (pthread_join(threads[thread].thread, NULL) != 0) {
/* do something */
return 1;
}
thread++;
}
thread = 0;
result = threads[0].max;
printf("result:\n");
while (thread < THREADS) {
printf("\t%d - %d: %d\n",
thread * limit,
thread * limit + limit - 1,
threads[thread].max);
if (threads[thread].max > result) {
result = threads[thread].max;
}
thread++;
}
printf("max\t%d\n", result);
return 0;
}
Notice that this is lock and malloc free, you could probably reduce instructions further with more fiddling ...

breaking out of a double after an elapsed time in C

I have a question I am writing a code that find the perfect number by brute forcing the algorithm which is required by my assignment. I want to see how far the ranges goes in 15 seconds. I tried using a while loop and an alarm but it seems to not work at all. How would I go from there?
Thanks
Heres my code:
#define _POSIX_SOURCE
#define _BSD_SOURCE
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
volatile int stop=0;
void sigalrm_handler( int sig ){
stop = 1;
}
int main(int argc, char **argv){
struct sigaction sact;
int num_sent = 0;
sigemptyset(&sact.sa_mask);
sact.sa_flags = 0;
sact.sa_handler = sigalrm_handler;
sigaction(SIGALRM, &sact, NULL);
alarm(15); /* Request SIGALRM in 60 seconds */
while (!stop) {
for (;;){
for (;;){
}
}
}
printf("%d \n", num_sent);
exit(0);
}
Even if the alarm gets triggered and set stop to a non-zero value you won't notice since your for loop doesn't return to the outer while. You need to apply the condition to all loops that should be stopped:
while (!stop) {
for (;!stop;){
for (;!stop;){
}
}
}
An alternative to alarm is simply checking whether you crossed a certain timepoint:
time_t end = time(0) + 15;
while (end < time(0)) {
for (;end < time(0);){
for (;end < time(0);){
}
}
}

c cygwin- abored(core dumped)

I have tried for a long time and cannot figure out where this 'core dumped' is coming from. I am using c on cygwin. Commenting out the threads gets rid of the problem but commenting out the entire code in the thread does nothing. Could this have something to do with the calling of the thread?? It appeared to be working then this suddenly happened. I have deleted most of the code and this is what is left-
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <stdint.h>
#include <pthread.h>
#include <string.h>
typedef enum {true=1, false=0} bool;
void *piThread(void *arg);
int finished;
int main(int argc, char *argv[])
{
int i;
int threads;
bool display = false;
long double pI = 0.0;
void *status = malloc(sizeof(int));
pthread_t thread_id[threads];
if(argc < 2) {printf("not enough arguments"); exit(1);
}else threads = atoi(argv[1]);
if(argc == 3)
if (strcmp(argv[2], "b") == 0)
display = true;
for(i=0; i<threads; i++)
{
pthread_create(&thread_id[i], NULL, piThread, NULL);
pthread_join(thread_id[i], &status);
printf("pi: %Lf\n", pI);
}
return 0;
}
void *piThread(void *arg)
{
int number = 0;
number = 74;
pthread_exit((void*)number);
}
This is causing an aborted error.
Stack trace:
Frame Function Args
0028A6A4 76821184 (000000D0, 0000EA60, 00000000, 0028A7D8)
0028A6B8 76821138 (000000D0, 0000EA60, 000000A4, 0028A7B4)
0028A7D8 610DBE29 (00000000, FFFFFFFE, 77403B23, 77403B4E)
0028A8C8 610D915E (00000000, 0028A918, 00000001, 00000000)
0028A928 610D962E (76D709CD, 7427AED9, 00000003, 00000006)
0028A9D8 610D9780 (000011E8, 00000006, 002B002B, 800483D8)
0028A9F8 610D97AC (00000006, 0028CE80, FFFDE000, 00000000)
0028AA28 610D9A85 (000000D0, 0028ABF0, 0028AA58, 610FA223)
End of stack trace
I have no idea what is wrong!!
command line is-
gcc pi.exe 100
any combination ABOVE 26 causes this fault.
Thank you for any insight
You are allocating thread_id before 'threads' is defined. This should fix that problem at least.
if(argc < 2) {printf("not enough arguments"); exit(1);
}else threads = atoi(argv[1]);
pthread_t thread_id[threads];

Resources