Segmentation fault / glibc detected when creating shared library - c++

EDITS----------------I tried with gcc-4.8.1 and still the same error.-------------I am trying to implement a simple matrix multiplication example using pthreads via a shared library. But I get this error when I try to create a shared library:
g++ -shared -o libMatmul.so matmul.o
collect2: ld terminated with signal 11 [Segmentation fault], core dumped
Here is the code I am using:
matmul.h:
#ifndef matmul_h__
#define matmul_h__
#define SIZE 10
typedef struct {
int dim;
int slice;
} matThread;
int num_thrd;
int A[SIZE][SIZE], B[SIZE][SIZE], C[SIZE][SIZE];
int m[SIZE][SIZE];
extern void init_matrix(int m[SIZE][SIZE]);
extern void print_matrix(int m[SIZE][SIZE]);
extern void* multiply(void* matThread);
#endif
matmul.c:
extern "C"
{
#include <pthread.h>
#include <unistd.h>
}
#include <iostream>
#include "matmul.h"
using namespace std ;
matThread* s=NULL;
// initialize a matrix
void init_matrix(int m[SIZE][SIZE])
{
int i, j, val = 0;
for (i = 0; i < SIZE; i++)
for (j = 0; j < SIZE; j++)
m[i][j] = val++;
}
void print_matrix(int m[SIZE][SIZE])
{
int i, j;
for (i = 0; i < SIZE; i++) {
cout<<"\n\t|" ;
for (j = 0; j < SIZE; j++)
cout<<m[i][j] ;
cout<<"|";
}
}
// thread function: taking "slice" as its argument
void* multiply(void* param)
{
matThread* s = (matThread*)param; // retrive the slice info
int slice1=s->slice;
int D= s->dim=10;
int from = (slice1 * D)/num_thrd; // note that this 'slicing' works fine
int to = ((slice1+1) * D)/num_thrd; // even if SIZE is not divisible by num_thrd
int i,j,k;
cout<<"computing slice " << slice1<<" from row "<< from<< " to " <<to-1<<endl;
for (i = from; i < to; i++)
{
for (j = 0; j < D; j++)
{
C[i][j] = 0;
for ( k = 0; k < D; k++)
C[i][j] += A[i][k]*B[k][j];
}
}
cout<<" finished slice "<<slice1<<endl;
return NULL;
}
main.c:
extern "C"
{
#include <pthread.h>
#include <unistd.h>
}
#include <iostream>
#include "matmul.h"
using namespace std;
// Size by SIZE matrices
// number of threads
matThread* parm=NULL;
int main(int argc, char* argv[])
{
pthread_t* thread; // pointer to a group of threads
int i;
if (argc!=2)
{
cout<<"Usage:"<< argv[0]<<" number_of_threads"<<endl;
exit(-1);
}
num_thrd = atoi(argv[1]);
init_matrix(A);
init_matrix(B);
thread = (pthread_t*) malloc(num_thrd*sizeof(pthread_t));
matThread *parm = new matThread();
for (i = 0; i < num_thrd; i++)
{
parm->slice=i;
// creates each thread working on its own slice of i
if (pthread_create (&thread[i], NULL, multiply, (void*)parm) != 0)
{
cerr<<"Can't create thread"<<endl;
free(thread);
exit(-1);
}
}
for (i = 1; i < num_thrd; i++)
pthread_join (thread[i], NULL);
cout<<"\n\n";
print_matrix(A);
cout<<"\n\n\t *"<<endl;
print_matrix(B);
cout<<"\n\n\t="<<endl;
print_matrix(C);
cout<<"\n\n";
free(thread);
return 0;
}
The commands that I use are:
g++ -c -Wall -fPIC matmul.cpp -o matmul.o and
g++ -shared -o libMatmul.so matmul.o
The code might look little off because I am passing SIZE(dim) in a struct when its already in #define, but this is how I want it to be implemented. Its a test program for a bigger project that I am doing.
Any help is greatly appreciated! Thanks in advance.

First, you're mixing a lot of C and C++ idioms (calling free and new for instance) and you're not using any C++ library/STL features (like a std::vector or std::list instead of a C array), so while your code is 'technically' valid (minus some bugs) it's not good practice to mix C and C++ like that, there are many small idiosyncratic differences between C and C++ (syntax, compilation and linkage differences for example) that can add confusion to the code if it's not explicitly clear to the intentions.
That being said, I've made some changes to your code to make it C++98 compatible (and fix the bugs):
start matmul.h:
#ifndef matmul_h__
#define matmul_h__
#define SIZE 10
#include <pthread.h>
typedef struct matThread {
int slice;
int dim;
pthread_t handle;
matThread() : slice(0), dim(0), handle(0) {}
matThread(int s) : slice(s), dim(0), handle(0) {}
matThread(int s, int d) : slice(s), dim(d), handle(0) {}
} matThread;
// explicitly define as extern (for clarity)
extern int num_thrd;
extern int A[SIZE][SIZE];
extern int B[SIZE][SIZE];
extern int C[SIZE][SIZE];
extern void init_matrix(int m[][SIZE]);
extern void print_matrix(int m[][SIZE]);
extern void* multiply(void* matThread);
#endif
start matmul.cpp:
#include <iostream> // <stdio.h>
#include "matmul.h"
int num_thrd = 1;
int A[SIZE][SIZE];
int B[SIZE][SIZE];
int C[SIZE][SIZE];
// initialize a matrix
void init_matrix(int m[][SIZE])
{
int i, j, val;
for (i = 0, val = -1; i < SIZE; i++) {
for (j = 0; j < SIZE; j++) {
m[i][j] = ++val;
}
}
}
void print_matrix(int m[][SIZE])
{
int i, j;
for (i = 0; i < SIZE; i++) {
std::cout << "\n\t|"; // printf
for (j = 0; j < SIZE; j++) {
std::cout << m[i][j];
}
std::cout << "|"; // printf
}
}
// thread function: taking "slice" as its argument
void* multiply(void* param)
{
matThread* s = (matThread*)param; // retrive the slice info
int slice1 = s->slice;
int D = s->dim = 10;
int from = (slice1 * D) / num_thrd; // note that this 'slicing' works fine
int to = ((slice1+1) * D) / num_thrd; // even if SIZE is not divisible by num_thrd
int i, j, k;
std::cout << "computing slice " << slice1 << " from row " << from << " to " << (to-1) << std::endl; // printf
for (i = from; i < to; i++) {
for (j = 0; j < D; j++) {
C[i][j] = 0;
for ( k = 0; k < D; k++) {
C[i][j] += A[i][k]*B[k][j];
}
}
}
std::cout << " finished slice " << slice1 << std::endl; // printf
return NULL;
}
start main.cpp:
#include <iostream>
#include <cstdlib> // atoi .. if C++11, you could use std::stoi in <string>
#include "matmul.h"
int main(int argc, char** argv)
{
if (argc != 2) {
std::cout << "Usage: " << argv[0] << " number_of_threads" << std::endl;
return -1;
} else {
num_thrd = std::atoi(argv[1]);
}
matThread mt[num_thrd];
int i = 0;
init_matrix(A);
init_matrix(B);
for (i = 0; i < num_thrd; i++) {
mt[i].slice = i;
// creates each thread working on its own slice of i
if (pthread_create(&mt[i].handle, NULL, &multiply, static_cast<void*>(&mt[i])) != 0) {
printf("Can't create thread\n");
return -1;
}
}
for (i = 0; i < num_thrd; i++) {
pthread_join(mt[i].handle, NULL);
}
std::cout << "\n\n";
print_matrix(A);
std::cout << "\n\n\t *\n";
print_matrix(B);
std::cout << "\n\n\t=\n";
print_matrix(C);
std::cout << "\n\n";
return 0;
}
To compile and use it you'll need to do the following commands:
g++ -c -Wall -fPIC matmul.cpp -o matmul.o
g++ -shared -Wl,-soname,libMatmul.so -o libMatmul.so.1 matmul.o
ln /full/path/to/libMatmul.so.1 /usr/lib/libMatmul.so
g++ main.cpp -o matmul -Wall -L. -lMatmul -pthread
Note that for your system to be able to find and link against the shared library you've just created, you'll need to ensure it's in your distro's lib folder (like /usr/lib/). You can copy/move it over, create a link to it (or a sym link via ln -s if you can't do hard links), and if you don't want to copy/move/link it, you can also ensure your LD_LIBRARY_PATH is properly set to include the build directory.
As I said; your code is NOT inherently C++ aside from the few print statements (std::cout, etc), and changing the C++ code (std::cout to printf and some other minor things for example) you could compile this as standard C99 code. I'm not 100% sure how the rest of your shared library will be designed so I didn't change the structure of the lib code (i.e. the functions you have) but if you wanted this code to be 'more C++' (i.e. with classes/namespaces, STL, etc.), you'd basically need to redesign your code, but given the context of your code, I don't think that's absolutely necessary unless you have a specific need for it.
I hope that can help.

Should
for (i = 1; i < num_thrd; i++)
not be
for (i = 0; i < num_thrd; i++)
You created num_thrd threads, but did not join all of them, therefore, a race condition is created as you're trying to read the data before the thread is finished.

Related

Unexpected number output

I'm trying to create a program that solves the problem of dining philosophers using posix threads. However, I got stuck at the very beginning, since the output of std :: cout << id + 1 << "PHILOSOPHER: thinking" << std :: endl; ++ i; is incorrect and id takes too large values. Please point out my mistake.
pthread_mutex_t mutexSpoon[PHILOSOPHERS];
pthread_t createThread(int number){
pthread_t id;
int rc = pthread_create(&id, NULL, philFunc, &number);
if(rc){
abort();
}
return id;
}
void *philFunc(void *arg){
srand(time(0));
int id = *(int*)arg;
int leftSpoon = (id>0) ? id-1 : PHILOSOPHERS;
int rightSpoon = id;
int temp;
int i = 0;
while(i < 10){
usleep((200 - 50) * ( (double)rand() / RAND_MAX ) + 50);
std::cout << id+1 << " PHILOSOPHER: thinking" << std::endl; ++i;
}
return nullptr;
}
main.cpp
using namespace std;
extern pthread_mutex_t mutexSpoon[PHILOSOPHERS];
int main(){
setlocale(LC_ALL, "rus");
for(int i = 0; i < PHILOSOPHERS; ++i)
pthread_mutex_init(&mutexSpoon[i], NULL);
vector<pthread_t> vecID(PHILOSOPHERS);
for(int i = 0; i < PHILOSOPHERS; ++i)
vecID[i] = createThread(i);
for(int i = 0; i < PHILOSOPHERS; ++i)
pthread_join(vecID[i], NULL);
for(int i = 0; i < PHILOSOPHERS; ++i)
pthread_mutex_destroy(&mutexSpoon[i]);
return 0;
}
thread function uses an address for argument, which you pass as an address to a local variable of function createThread - number. The life span of argument should be not shorter than thread, so exactly same as the mutex. Using your snippets as base, I created an example which works around the issue:
#include <iostream>
#include <cstdlib>
#include <vector>
#include <pthread.h>
#include <unistd.h>
void *philFunc(void *arg);
#define PHILOSOPHERS 10
struct Philosopher {
pthread_mutex_t mutexSpoon;
pthread_t id;
int no;
};
Philosopher philosophers[PHILOSOPHERS] = {};
pthread_t createThread(int& number){
pthread_t id;
int rc = pthread_create(&id, NULL, philFunc, &number);
if(rc){
abort();
}
return id;
}
void *philFunc(void *arg){
srand(time(0));
int id = *(int*)arg;
int leftSpoon = (id>0) ? id-1 : PHILOSOPHERS;
int rightSpoon = id;
int temp;
int i = 0;
while(i < 10){
usleep((200 - 50) * ( (double)rand() / RAND_MAX ) + 50);
std::cout << id+1 << " PHILOSOPHER: thinking" << std::endl; ++i;
}
return nullptr;
}
extern pthread_mutex_t mutexSpoon[PHILOSOPHERS];
int main(){
setlocale(LC_ALL, "rus");
for(int i = 0; i < PHILOSOPHERS; ++i) {
pthread_mutex_init(&philosophers[i].mutexSpoon, NULL);
philosophers[i].no = i;
philosophers[i].id = createThread(philosophers[i].no);
}
for(int i = 0; i < PHILOSOPHERS; ++i)
pthread_join(philosophers[i].id, NULL);
for(int i = 0; i < PHILOSOPHERS; ++i)
pthread_mutex_destroy(&philosophers[i].mutexSpoon);
return 0;
}
As you see, there is now own structure Philosopher for each thread, storing its data as it should be. While philosophers here is an array, it can be any other container as long as its elements live long enough and aren't changing their addresses (requirement for some implementations of the pthread mutex).
Note that createThread(int& number) now takes its argument by reference, so the expression &number would get address of the actual object's location, not of local variable.
This code can be simpler, if using C++ thread support and std::future.

Segmentation fault - reading array of initialized pointers

could you help me with little problem?
I have following class;
class Link
{
private:
Demand *demand_[NUMBER_OF_CORES][NUMBER_OF_SLICES];
public:
Link()
{
for (int i = 0; i < NUMBER_OF_CORES; i++)
{
for (int j = 0; j < NUMBER_OF_SLICES; j++)
{
demand_[i][j] = NULL;
}
}
}
int virtualPut();
}
There will be problem with demand_ array. In the constructor everything is fine, after initialization I can use if (demand_[i][j] == NULL).
Problem starts in virtualPut()
int Link::virtualPut()
{
for (int i = 0; i < NUMBER_OF_CORES; i++)
{
for (int j = 0; j < NUMBER_OF_SLICES; j++)
{
std::cout << "We're in " << i << " " << j << " \n" << std::flush;
if (demand_[i][j] == NULL) //SEGMENTATION FAULT
{
std::cout << "EMPTY\n";
}
}
}
}
And also - if I call virtualPut() in constructor (just for test) it works fine.
But outside Link class I use.
void someFunction(Link *tab, int links)
{
tab = new Link[links];
tab[0].virtualPut(); //also just for test
}
What could be a problem here? I know that I can use vector, but that won't help me understand this memory problem.
One more thing - Dr. Memory says:
UNADDRESSABLE ACCESS: reading 0x0000000000000009-0x0000000000000011 8 byte(s)
But why?
EDIT!
Problem solved in comments, thank you
The code you show us is okay. I ran it on my side with huge values, and there is no Segfault.
You declared a "Demand* array of array" in your Link class, and this is a valid declaration, the memory should be allocated.
What I do suspect is that NUMBER_OF_CORES and/or NUMBER_OF_SLICES doesn't have the same value in the code where you defines the Link class and in the code where you defined the virtualPut method.
Something like :
#define NUMBER_OF_CORES 10
#define NUMBER_OF_SLICES 10
class Link
{
private:
Demand *demand_[NUMBER_OF_CORES][NUMBER_OF_SLICES];
...
}
and
#define NUMBER_OF_CORES 5000
#define NUMBER_OF_SLICES 5000
int Link::virtualPut()
{
for (int i = 0; i < NUMBER_OF_CORES; i++)
{
for (int j = 0; j < NUMBER_OF_SLICES; j++)
{
// here you will have buffer overflow
...
}
What I would do :
use std::vector
probably use a single entry array, and wrap it up
don't use #define, it's messy
don't use arrays, it generates buffer overflow
That would be something like this :
class Link
{
private:
std::vector<Demand*> demand_;
const int NUMBER_OF_CORES = 10;
const int NUMBER_OF_SLICES = 50;
private:
int getIdx(int i, int j)
{
return i*NUMBER_OF_SLICES + j;
}
public:
Link()
{
demand_.resize(NUMBER_OF_CORES * NUMBER_OF_SLICES);
for (int i = 0; i < NUMBER_OF_CORES; i++)
{
for (int j = 0; j < NUMBER_OF_SLICES; j++)
{
demand_[getIdx(i,j)] = NULL;
}
}
}
int virtualPut();
};
Note : additionaly, you showed us a virtualPut() that should return an int but doesn't.

Jsoncpp - memory consumption with nested arrays

This code eats up to 1.5GB of memory and doesn't release it.
Why ? I'm expecting the memory to be freed after the call to the bigone function.
How to fix this ?
#include <iostream>
#include <jsoncpp/json/json.h>
#include <jsoncpp/json/value.h>
typedef unsigned char utiny;
void watchmem() {
char k;
std::cout << "watch memory consumption then press a key ";
std::cin >> k;
}
void bigone() {
Json::Value conf = Json::arrayValue;
for(utiny i = 0; i < 255; i++) {
for(utiny j = 0; j < 255; j++) {
for(utiny k = 0; k < 255; k++) {
conf[i][j][k] = 0;
}
}
}
}
int main(int argc, char **argv) {
bigone();
watchmem();
}
build:
g++ -std=c++11 -o chkmem chkmem.cpp -ljsoncpp && ./chkmem

POSIX pthread_create scrambles the values of variables in a struct, how to avoid that?

So I have my program here:
#include <iostream>
#include <string>
#include <pthread.h>
#include <unistd.h>
#include <math.h>
#include <stdlib.h>
using namespace std;
int const size = 3;
struct Arguments{
int array[];
float result1[];
float result2[];
};
//void calc(int arr[], float rarr1[], float rarr2[], int size);
void* calc(void *param);
int main(int argc, char *argv[]){
time_t t;
srand((unsigned) time(&t));
int arr[size][size] = {};
float rarr1[size][size-1] = {};
float rarr2[size][size-1] = {};
for(int x = 0; x < size; x++){
for(int y = 0; y < size; y++){
int number = rand()%10;
arr[x][y] = number;
}
}
for(int x = 0; x < size; x++){
for(int y = 0; y < size; y++){
cout << arr[x][y] << " ";
}
cout << endl;
}
cout << endl;
/////////////////////////////////////////
pthread_t child;
struct Arguments input;
for(int i = 0; i < size; i++){
input.array[i] = arr[0][i];
}
pthread_create(&child, NULL, calc, (void*)&input);
pthread_join(child, NULL);
//calc(&input);
for(int i = 0; i < size-1; i++){
rarr1[0][i] = input.result1[i];
cout << "Test: " << rarr1[0][i] << endl;
}
//////////////////////////////////
return 0;
}
//void calc(int arr[], float rarr1[], float rarr2[], int size){
void* calc(void *param){
struct Arguments *input = (struct Arguments*)param;
int arr1[] = {};
float rarr1[] = {};
float rarr2[] = {};
for(int i = 0; i < size; i++){
arr1[i] = input->array[i];
}
for(int i = 0; i < size; i++){
int a = arr1[i];
int b = arr1[i+1];
int difference = a-b;
if(difference < 0){
difference = difference * -1;
}
float euc = 1 + pow(difference, 2);
euc = sqrt(euc);
rarr1[i] = euc;
}
for(int i = 0; i <size-1; i++){
input->result1[i] = rarr1[i];
}
for(int i = 0; i <size-1; i++){
int a = arr1[i];
int b = arr1[i+1];
int difference = a-b;
if(difference < 0){
difference = difference * -1;
}
float apar = (difference/rarr1[i]);
float result = asin(apar);
result = result*(180/3.14);
rarr2[i] = result;
}
return NULL;
}
The important part that causes the trouble is between ////// lines but I left the rest of the code for the context, since it might be useful.
So I have the function calc(param); that does the important calculation in the program.
It is working just fine as long as I call it myself (by actually including the function call in the code) and the test loop right after it gives the correct results.
However, when I try to use pthread_create(); to create a new thread that will take care of executing that function, the test loop spits out nonsense and some random huge numbers different each time.
It's kinda weird because the code compiles either way, and literally the only thing that I change is these 2 lines.
What am I doing wrong and why the function spits out garbage when started by the Pthread? Is there a way to fix it?
Ok so if anyone's having a similar problem:
Declare the size of arrays no matter what. It turns out that my program didn't work properly because I initialized my result arrays as float result1[]; instead of float result1[size];

Why does my program give a "segmentation fault" (core dumped) error after running

I've to create a prime checker using semaphores. The code executes till the "Finding Primes from" part and after that crashes saying "Segmentation Fault (Core Dumped)". After searching about this I understand that it happens when the program tries to access a part of memory that isn't available; but I don't understand it in my code. Please do a take a look and thank you!
#include <QThread>
#include <QSemaphore>
#include <QMutex>
#include <iostream>
#include <stdlib.h>
#include <cmath>
#include <vector>
using namespace std;
#define TOTALSPACE 50
vector<int> buffer(TOTALSPACE);
QSemaphore space(TOTALSPACE), avail;
QMutex l;
int prime_from, prime_to, num_threads;
int total = 0, cnumber = 0;
int in = 0, out = 0;
bool b = false;
//-----Generator------
class Generator : public QThread
{
private:
int strt;
int end;
public:
Generator(int a, int b)
{
strt = a;
end = b;
cnumber = strt;
}
void run()
{
while (cnumber < end)
{
space.acquire();
cnumber++;
buffer[in] = cnumber;
in = (in + 1) % TOTALSPACE;
avail.release();
}
b = true;
for (int i = 0; i < num_threads; i++)
{
space.acquire();
buffer[in] = -1;
in = (in + 1) % TOTALSPACE;
avail.release();
}
}
};
//-----------Checker----------
class Checker : public QThread
{
private:
int number;
public:
Checker() {}
void run();
};
void Checker::run()
{
while (1)
{
avail.acquire();
l.lock();
number = buffer[out];
if (number == -1)
{
l.unlock();
break;
}
bool isPrime = false;
for (int i = 2; i <= sqrt(number); i++)
{
if (number%i == 0)
{
isPrime = true;
break;
}
}
out = (out + 1) % TOTALSPACE;
if (isPrime == false)
{
total++;
}
l.unlock();
space.release();
}
}
//-------------Main---------
int main(int argc, char *argv[])
{
num_threads = atoi(argv[1]);
prime_from = atoi(argv[2]);
prime_to = atoi(argv[3]);
cout << " Number of Threads = " << num_threads << endl;
cout << " Primes checking from " << prime_from << " to " << prime_to << endl;
Generator gen(prime_from, prime_to);
gen.start();
Checker* thr[num_threads];
for (int i = 1; i < num_threads; i++)
{
thr[i] = new Checker();
thr[i]->start();
}
gen.wait();
for (int i = 0; i < num_threads; i++)
{
thr[i]->wait();
}
cout << "Total Primes: " << total << endl;
return 0;
}
There's a couple of things that could cause this. For one, you never check whether there's enough parameters supplied or not (argc>3). So you could pass invalid pointers to atoi
But far more likely is that you did not initialize thr[0] because you start your initialization loop with for (int i = 1; but you access thr[0] in the loop for synchronization because you start it with or (int i = 0;.
In addition it is noteworthy that you are using Variable Length Arrays when you do Checker* thr[num_threads]; because num_threads is not a compile-time constant. That feature is not part of the C++ standard at this time (not in C++14). So, if you want to make your program portable you can do Checker** thr = new Checker*[num_threads]; and delete [] thr; at the end if you want to be diligent (and not use smart pointers).