Move constructor of unrestricted union crashes with invalid_pointer - c++

An example with unrestricted union class that holds either a map of ints or a vector of ints:
#include <iostream>
#include <string>
#include <vector>
#include <map>
typedef std::vector<int> int_vec;
typedef std::map<std::string, int> int_map;
struct Vec {
bool is_map;
union {
int_vec int_vec_val;
int_map int_map_val;
};
// MOVE CONSTRUCTORS
Vec(int_vec&& val) : is_map(false), int_vec_val(std::move(val)) {
std::cout << "move vec" << std::endl;
}
Vec(int_map&& val) : is_map(true), int_map_val(std::move(val)) {
std::cout << "move map" << std::endl;
}
Vec(Vec&& rhs) : is_map(rhs.is_map) {
if (is_map) {
int_map_val = std::move(rhs.int_map_val);
} else {
std::cout << "Crashing now ... " << std::endl;
int_vec_val = std::move(rhs.int_vec_val); // <--- how to do this correctly?
}
}
// DESTRUCTOR
~Vec() noexcept {
if (is_map) {
int_map_val.~int_map();
} else {
int_vec_val.~int_vec();
}
}
};
Vec gen_Vec() {
Vec v1(int_vec({1, 2, 3}));
return Vec(std::move(v1));
}
int main() {
Vec v2 = gen_Vec();
}
This code crashes with *** Error in ./tmp2: munmap_chunk(): invalid pointer: 0x0000000000400f6d *** in the Vec(Vec&&) move constructor:
g++ -std=c++11 -O2 tmp2.cpp -lm -o tmp2 && ./tmp2
move vec
Crashing now ...
*** Error in `./tmp2': munmap_chunk(): invalid pointer: 0x0000000000400f6d ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7fba03ab47e5]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x1a8)[0x7fba03ac0ae8]
./tmp2[0x400d0d]
./tmp2[0x400a7c]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7fba03a5d830]
./tmp2[0x400af9]
======= Memory map: ========
00400000-00402000 r-xp 00000000 08:11 13240011 /store/Dropbox/dev/jamr/src/tmp2
00601000-00602000 r--p 00001000 08:11 13240011 /store/Dropbox/dev/jamr/src/tmp2
00602000-00603000 rw-p 00002000 08:11 13240011 /store/Dropbox/dev/jamr/src/tmp2
006ce000-00700000 rw-p 00000000 00:00 0 [heap]
7fba03734000-7fba0383c000 r-xp 00000000 08:01 1065106 /lib/x86_64-linux-gnu/libm-2.23.so
7fba0383c000-7fba03a3b000 ---p 00108000 08:01 1065106 /lib/x86_64-linux-gnu/libm-2.23.so
7fba03a3b000-7fba03a3c000 r--p 00107000 08:01 1065106 /lib/x86_64-linux-gnu/libm-2.23.so
7fba03a3c000-7fba03a3d000 rw-p 00108000 08:01 1065106 /lib/x86_64-linux-gnu/libm-2.23.so
My questions are:
What is the correct way to move those vectors and maps?
Is there a way to define Vec(Vec&& rhs) move constructor entirely in the mem initializer list?
Many thanks.

The assignment int_vec_val = std::move(rhs.int_vec_val); implies that int_vec_val denotes an existing, live object of type int_vec and you want to change its value by assigning to it. This is not the case: since the members of the anonymous union don't have default member initializers and don't have corresponding mem-initializers either, no initialization is performed on them, so their lifetimes don't start.
This means that none of int_map_val and int_vec_val is alive when the constructor's block is entered. You have to actually construct a new object of the right type in the right place using placement new:
Vec(Vec&& rhs) : is_map(rhs.is_map) {
if (is_map) {
std::cout << "move contained map\n";
new(&int_map_val) int_map(std::move(rhs.int_map_val));
} else {
std::cout << "move contained vec\n";
new(&int_vec_val) int_vec(std::move(rhs.int_vec_val));
}
}
The answer to your second question is: no, not really, since rhs.is_map is generally only known at run time and the contents of the mem-initializer-list needs to be known at compile time. However, in this case there's no problem with doing the initialization in the constructor's block (and no real benefit to be gained by doing it in the ctor-initializer), since no initialization is performed on the union members by default.

Related

mmap error : segmentation fault/invalid pointer error

I am new to mmap and still learning it . Based on my understanding i have created class for mmap which will be used to map a file in memory . The entire class is working fine but problem is coming when destructor is called ..the problem is segmentation fault or invalid pointer error is coming at the end of main function ...I have posted code of my class and main function which is using that class ...
Map.h
class MapData
{
public :
MapData();
~MapData();
MapData(char []);
bool OPEN();
void fnClose();
long fnGetSize();
char * fnGetFileRef();
char * ReadNextData(int );
private :
char * ptrRecord;
char ptrFileNm[250+1];
int fd;
struct stat sbuf;
bool bSuccess;
long sTotalSize;
char acData[2000+1];
long lCurrRead;
};
MapData.cpp
MapData::MapData()
{
}
MapData::~MapData()
{
printf("Inside MADATA Destructor \n ");
}
MapData::MapData(char acInput[])
{
strcpy(ptrFileNm,acInput);
sTotalSize=0;
lCurrRead=0;
bSuccess=false;
}
bool MapData::OPEN()
{
// if failed return false flg
if ((fd = open(ptrFileNm, O_RDONLY)) == -1) {
return bSuccess;
}
if (stat(ptrFileNm, &sbuf) == -1) {
return bSuccess;
}
// copy in local variable
sTotalSize = sbuf.st_size;
ptrRecord = (char * )mmap( (caddr_t)0, sTotalSize, PROT_READ, MAP_SHARED, fd, 0) ;
if (ptrRecord == (char *)(caddr_t)(-1) ) {
perror("Fail to Map Data ");
return bSuccess;
}
else
{
printf("Successfully Map Data***[%ld] \n",sTotalSize);
bSuccess=true;
}
return bSuccess;
}
char * MapData::fnGetFileRef()
{
return ptrRecord;
}
char * MapData::ReadNextData(int iX)
{
if((lCurrRead+iX)<sTotalSize)
{
memset(acData,0x00,sizeof(acData));
strncpy(acData,ptrRecord+lCurrRead,iX);
acData[iX+1]='\0';
lCurrRead+=iX;
}else{
strcpy(acData,"ZZZ");
}
return acData;
}
long MapData::fnGetSize()
{
return sTotalSize;
}
void MapData::fnClose()
{
// Don't forget to free the mmapped memory
if(munmap(ptrRecord, sTotalSize) == -1)
{
close(fd);
perror("Error un-mmapping the file");
exit(EXIT_FAILURE);
}
// Un-mmaping doesn't close the file, so we still need to do that.
close(fd);
printf("CLOSED SUCCESSFULLY \n ");
}
Main.cpp
int main()
{
char acFileNm[500+1];
MEMSET(acFileNm); // clean the variable
// file name to be read
strcpy(acFileNm,"ABDFILE.txt");
long lProcCnt=0; // no of byte read by program
char acLine[MAX_LINE_LENGTH+1]; // hold current read line
bool bFlag=true; // main flag
DEBUG_PRINT("File to be processed:%s \n",acFileNm);
// create object of mmap
MapData * pt1 = NULL;
pt1 = new MapData(acFileNm);
if(!pt1)
{
cout<<"Error creating object so quit ..."<<endl;
return 0 ;
}
auto_ptr<MapData> ptrMap( pt1 ); // pass ownership to auto deletor to delete memory
DEBUG_PRINT("STEP1:%s \n","OBJECT CREATION FOR FILE MAPPED IN MEMORY");
// try to open the file
if(ptrMap->OPEN())
{
// on success..get pointer to first char of file
char * ptrData = ptrMap->fnGetFileRef();
long lCompSize=ptrMap->fnGetSize(); // total no of bytes = fiexed line size * no of row + (no of row * EOL)
short int iEOL=0;
// logic to identify file generated on ewhich OS
if( (*(ptrData+MAX_LINE_LENGTH) == '\r') && (*(ptrData+MAX_LINE_LENGTH+1) == '\n'))
{
// DOS format CRLF
iEOL = 2;
}else if(*(ptrData+MAX_LINE_LENGTH) == '\n'){
// Unix format LF
iEOL = 1;
}
DEBUG_PRINT("STEP2: SIZEOFFILE%ld FILESYSTEM FORMAT:%d \n",lCompSize,iEOL);
// here read till it reaches maximum limit of file
while(lProcCnt<lCompSize)
{
//DEBUG_PRINT("PROC COUNTER[%ld] MAX_COUNTER[%ld] \n",lProcCnt,lCompSize);
lProcCnt+=MAX_LINE_LENGTH+iEOL; // increement no of bytes read at initial
MEMSET(acLine);
strncpy(acLine,ptrData+lProcCnt,MAX_LINE_LENGTH); // read line
acLine[MAX_LINE_LENGTH+1]='\0';
// process the line :function is called here to process the line
}
}else{
DEBUG_PRINT("MAP DATA FAILED OF FILE[%s] \n",acFileNm);
bFlag=false;
}
// at the end check if all the controls are matched
if(bFlag)
DEBUG_PRINT("END OF FILE PROCESSING SUCCESS \n");
else
DEBUG_PRINT("END OF FILE PROCESSING FAILED \n");
// close the memory map
ptrMap->fnClose();
MapData * ptr5 = ptrMap.release(); // release the ownership
delete ptr5; **// segmentation fault comes here ...**
}
Please suggest me where i am going wrong since gdb is also not helping ...detailed explanation will be good for me to understand ...
Stacktrace generated by gdb:
*** glibc detected *** DemoMap: free(): invalid pointer: 0x0804c000 ***
======= Backtrace: =========
/lib/libc.so.6[0x9bbc81]
/lib/libc.so.6[0x9be562]
/usr/lib/libstdc++.so.6(_ZdlPv+0x22)[0x544552]
DemoMap[0x80491e6]
/lib/libc.so.6(__libc_start_main+0xe6)[0x961d36]
DemoMap[0x8048d91]
======= Memory map: ========
00110000-00111000 r-xp 00000000 00:00 0 [vdso]
0044c000-00469000 r-xp 00000000 08:03 1237 /lib/libgcc_s-4.4.7-20120601.so.1
00469000-0046a000 rw-p 0001d000 08:03 1237 /lib/libgcc_s-4.4.7-20120601.so.1
00495000-00576000 r-xp 00000000 08:02 132841 /usr/lib/libstdc++.so.6.0.13
00576000-0057a000 r--p 000e0000 08:02 132841 /usr/lib/libstdc++.so.6.0.13
0057a000-0057c000 rw-p 000e4000 08:02 132841 /usr/lib/libstdc++.so.6.0.13
0057c000-00582000 rw-p 00000000 00:00 0
00929000-00947000 r-xp 00000000 08:03 1065 /lib/ld-2.12.so
00947000-00948000 r--p 0001d000 08:03 1065 /lib/ld-2.12.so
00948000-00949000 rw-p 0001e000 08:03 1065 /lib/ld-2.12.so
0094b000-00adb000 r-xp 00000000 08:03 1067 /lib/libc-2.12.so
00adb000-00adc000 ---p 00190000 08:03 1067 /lib/libc-2.12.so
00adc000-00ade000 r--p 00190000 08:03 1067 /lib/libc-2.12.so
00ade000-00adf000 rw-p 00192000 08:03 1067 /lib/libc-2.12.so
00adf000-00ae2000 rw-p 00000000 00:00 0
00b29000-00b51000 r-xp 00000000 08:03 1211 /lib/libm-2.12.so
00b51000-00b52000 r--p 00027000 08:03 1211 /lib/libm-2.12.so
00b52000-00b53000 rw-p 00028000 08:03 1211 /lib/libm-2.12.so
08048000-0804b000 r-xp 00000000 08:08 2883976 DemoMap
0804b000-0804c000 rw-p 00002000 08:08 2883976 DemoMap
0804c000-0806d000 rw-p 00000000 00:00 0 [heap]
b7e00000-b7e21000 rw-p 00000000 00:00 0
b7e21000-b7f00000 ---p 00000000 00:00 0
b7f9b000-b7fe5000 r--s 00000000 08:08 4326707 ABCDEF.TXT
b7fe5000-b7fe8000 rw-p 00000000 00:00 0
b7ffd000-b8000000 rw-p 00000000 00:00 0
bffeb000-c0000000 rw-p 00000000 00:00 0 [stack]
may be here.
char ptrFileNm[250+1];
char acFileNm[500+1];
MapData::MapData(char acInput[])
{
strcpy(ptrFileNm,acInput);//segmentation fault
sTotalSize=0;
lCurrRead=0;
bSuccess=false;
}

Error in `main': free(): invalid pointer (though no free or delete used)

I have this simple code that i m trying to run in tutorialspoint.com
#include <iostream>
using namespace std;
class Vehicle {
string vehicleNo;
string color;
protected:
string getVehicleNo()
{
return vehicleNo;
}
string setVehicleNo(string num)
{
vehicleNo = num;
}
string getColor()
{
return color;
}
string setColor(string someColor)
{
color = someColor;
}
};
class Car: public Vehicle {
private:
int distance;
public:
void setDistance(int a)
{
distance = a;
}
int calculateFare(int)
{
return distance * 5;
}
void displayInformation()
{
cout << distance << endl;
}
void useSetVehicleNo(string num)
{
setVehicleNo(num);
}
string useSetColor(string someColor)
{
setColor(someColor);
}
string useGetVehicleNo()
{
return getVehicleNo();
}
string useGetColor()
{
return getColor();
}
};
int main()
{
//string exit=n;
string vehicleNo;
string color;
Car car;
cout << "Enter car number : " << endl;
cin >> vehicleNo;
car.useSetVehicleNo(vehicleNo);
cout << "Enter car color : " << endl;
cin >> color;
car.useSetColor(color);
//vehicleNo = car.useGetColor();
//color = car.useGetVehicleNo();
//cout << vehicleNo;
//cout << color;
return 0;
}
Running this is giving me the following output
Enter car number :
1
Enter car color :
g
* Error in `main': free(): invalid pointer: 0x00007ff3aa205ba8 *
======= Backtrace: ========= /lib64/libc.so.6(+0x7850e)[0x7ff3a969450e]
/lib64/libc.so.6(cfree+0x5b5)[0x7ff3a96a0165]
main[0x400e97]
main[0x400c79]
/lib64/libc.so.6(__libc_start_main+0xf0)[0x7ff3a963bfe0]
main[0x400ac9]
======= Memory map: ======== 00400000-00402000 r-xp 00000000 fd:11f 59330668
/home/cg/roo t/main
00601000-00602000 r--p 00001000 fd:11f 59330668
/home/cg/roo t/main
00602000-00603000 rw-p 00002000 fd:11f 59330668
/home/cg/roo t/main
0140c000-0142d000 rw-p 00000000 00:00 0
[heap]
7ff3a961c000-7ff3a97d0000 r-xp 00000000 fd:11f 37749826
/usr/lib64/l
ibc-2.20.so
7ff3a97d0000-7ff3a99cf000 ---p 001b4000 fd:11f 37749826
/usr/lib64/l
ibc-2.20.so
7ff3a99cf000-7ff3a99d3000 r--p 001b3000 fd:11f 37749826
/usr/lib64/l
ibc-2.20.so
7ff3a99d3000-7ff3a99d5000 rw-p 001b7000 fd:11f 37749826
/usr/lib64/l
ibc-2.20.so
7ff3a99d5000-7ff3a99d9000 rw-p 00000000 00:00 0
7ff3a99d9000-7ff3a99ef000 r-xp 00000000 fd:11f 37749844
/usr/lib64/l
ibgcc_s-4.9.2-20141101.so.1 7ff3a99ef000-7ff3a9bee000 ---p
00016000 fd:11f 37749844 /usr/lib64/l
ibgcc_s-4.9.2-20141101.so.1
7ff3a9bee000-7ff3a9bef000 r--p 00015000 fd:11f 37749844
/usr/lib64/l
ibgcc_s-4.9.2-20141101.so.1
7ff3a9bef000-7ff3a9bf0000 rw-p 00016000 fd:11f 37749844
/usr/lib64/l
ibgcc_s-4.9.2-20141101.so.1
7ff3a9bf0000-7ff3a9cf7000 r-xp 00000000 fd:11f 37749280
/usr/lib64/l
ibm-2.20.so
7ff3a9cf7000-7ff3a9ef6000 ---p 00107000 fd:11f 37749280
/usr/lib64/l
ibm-2.20.so
7ff3a9ef6000-7ff3a9ef7000 r--p 00106000 fd:11f 37749280
/usr/lib64/l
ibm-2.20.so
7ff3a9ef7000-7ff3a9ef8000 rw-p 00107000 fd:11f 37749280
/usr/lib64/l
ibm-2.20.so
7ff3a9ef8000-7ff3a9fe8000 r-xp 00000000 fd:11f 37749829
/usr/lib64/l
ibstdc++.so.6.0.20
7ff3a9fe8000-7ff3aa1e8000 ---p 000f0000 fd:11f 37749829
/usr/lib64/l
ibstdc++.so.6.0.20
7ff3aa1e8000-7ff3aa1f0000 r--p 000f0000 fd:11f 37749829
/usr/lib64/l
ibstdc++.so.6.0.20
7ff3aa1f0000-7ff3aa1f2000 rw-p 000f8000 fd:11f 37749829
/usr/lib64/l
ibstdc++.so.6.0.20
7ff3aa1f2000-7ff3aa207000 rw-p 00000000 00:00 0
7ff3aa207000-7ff3aa228000 r-xp 00000000 fd:11f 37856921
/usr/lib64/l d-2.20.so
7ff3aa412000-7ff3aa417000 rw-p 00000000 00:00 0
7ff3aa424000-7ff3aa428000 rw-p 00000000 00:00 0
7ff3aa428000-7ff3aa429000 r--p 00021000 fd:11f 37856921
/usr/lib64/l d-2.20.so
7ff3aa429000-7ff3aa42a000 rw-p 00022000 fd:11f 37856921
/usr/lib64/l 7ff3aa429000-7ff3aa42a000 rw-p 00022000 fd:11f
37856921 /usr/lib64/l
d-2.20.so
7ff3aa42a000-7ff3aa42b000 rw-p 00000000 00:00 0
7fff1dddb000-7fff1ddfc000 rw-p 00000000 00:00 0
[stack]
7fff1ddfe000-7fff1de00000 r-xp 00000000 00:00 0
[vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0
[vsyscall] Aborted
(core dumped)
You have three functions that have a return type different than void where you don't have a valid return statement.
If you turn your warning level up, your compiler will tell you about them. When using g++ -Wall, I get the following messages:
socc.cc: In member function ‘std::string Vehicle::setVehicleNo(std::string)’:
socc.cc:19:4: warning: no return statement in function returning non-void [-Wreturn-type]
}
^
socc.cc: In member function ‘std::string Vehicle::setColor(std::string)’:
socc.cc:29:4: warning: no return statement in function returning non-void [-Wreturn-type]
}
^
socc.cc: In member function ‘std::string Car::useSetColor(std::string)’:
socc.cc:60:7: warning: no return statement in function returning non-void [-Wreturn-type]
}
^
Calling such functions leads to undefined behavior.
From the C++11 Standard:
6.6.3 return statement
2 ...
...
Flowing off the end of a function is equivalent to a return with no value; this results in undefined
behavior in a value-returning function.
You can fix the problem by adding a suitable return statement. E.g.
The first function:
string setVehicleNo(string num)
{
vehicleNo = num;
return vehicleNo; // Add this, maybe?
}
The second function:
string setColor(string someColor)
{
color = someColor;
return color; // Add this, maybe
}
The third function:
string useSetColor(string someColor)
{
return setColor(someColor); // Add the return, maybe?
}
Your problems are here:
string setVehicleNo(string num)
// ^^^^^^
{
vehicleNo = num;
}
You are defining a return type but don't return a value actually (you should have gotten a compiler warning about this).
To fix either specify a void return type, or return a value.
Analogous for your other functions. See a fixed demo here.
Do the following changes in your code :
first -
string setVehicleNo(string num)
// ^^^^^^
{
vehicleNo = num;
}
second -
string setColor(string someColor)
// ^^^^^^
{
color = someColor;
}
third -
string useSetColor(string someColor)
//^^^^^^
{
setColor(someColor);
}
You have assign return type to string but not returning any value. changed it to void. see the changes made here http://ideone.com/n1Wg15

*** glibc detected *** {binary pathway}: double free or corruption (out): 0x0000000000639310 ***

I know a lot of people met this problem and I have gone through a lot of them. But I still can't solve my problem. Here is it:
My code is c++ code. But I need to call a shared library made by c (ODE solver) for my problem.
int Reaction::cvodedensewrapper()
This is where the functions of ODE solver are called. My class is Reaction and cvodedenseWrapper() is a class function. I define a struct for data transfer from c++ to c as:
typedef struct {
unsigned int exp_ID, nExp,nRec, nComp;
realtype *Ts;
realtype *dTs;
realtype *ts;
realtype *vkp;
realtype Tr;
} User;
typedef User *UserData;
Here realtype is a name for double type. I define a UserData type variable in my code, allocate memory and initialize it as:
User data;
UserData udata=& data;
udata->Ts=new realtype[numExp];
udata->dTs=new realtype[numExp];
udata->ts=new realtype[numExp];
udata->vkp=new realtype[2*numRec];
udata->nExp=numExp;
udata->nRec=numRec;
udata->nComp=numComp;
udata->Tr=Tref;
for(i=0;i!=numExp;i++)
{
udata->Ts[i]=Tstart[i];
udata->dTs[i]=dT[i];
udata->ts[i]=tstart[i];
}
for(i=0;i!=2*numRec;i++)
{
udata->vkp[i]=vk[i];
}
The udata will be passed to ODE solver six times in a loop. At each time, I monitor the address of the dynamic arrays and its content with the code:
printf("udata->Ts: %p\n",udata->Ts);
for(i=0;i!=numExp;i++)
printf(" Ts[%d]=%.5f ",i,udata->Ts[i]);
printf("\n");
printf("udata->dTs: %p\n",udata->dTs);
for(i=0;i!=numExp;i++)
printf(" dTs[%d]=%.5f ",i,udata->dTs[i]);
printf("\n");
printf("udata->ts: %p\n",udata->ts);
for(i=0;i!=numExp;i++)
printf(" ts[%d]=%.5f ",i,udata->ts[i]);
printf("\n");
printf("udata->vkp: %p\n",udata->vkp);
for(i=0;i!=2*numRec;i++)
printf(" vkp[%d]=%.5f ",i,udata->vkp[i]);
printf("\n");
The output at the first time:
m = 0
udata->Ts: 0x62c430
Ts[0]=673.00000 Ts[1]=698.00000 Ts[2]=723.00000 Ts[3]=748.00000 Ts[4]=773.00000 Ts[5]=798.00000
udata->dTs: 0x638f30
dTs[0]=0.00000 dTs[1]=0.00000 dTs[2]=0.00000 dTs[3]=0.00000 dTs[4]=0.00000 dTs[5]=0.00000
udata->ts: 0x638f70
ts[0]=316.09846 ts[1]=283.41932 ts[2]=253.00015 ts[3]=224.61435 ts[4]=198.06463 ts[5]=173.17842
udata->vkp: 0x62e150
vkp[0]=-4.22868 vkp[1]=-2.73312 vkp[2]=2.80980 vkp[3]=-1.65961 vkp[4]=27.23419 vkp[5]=25.96871vkp[6]=16.03558 vkp[7]=10.69316
As comparison, here is the sixth output,
udata->Ts: 0x62c430
Ts[0]=673.00000 Ts[1]=698.00000 Ts[2]=723.00000 Ts[3]=748.00000 Ts[4]=773.00000 Ts[5]=798.00000
udata->dTs: 0x638f30
dTs[0]=0.00000 dTs[1]=0.00000 dTs[2]=0.00000 dTs[3]=0.00000 dTs[4]=0.00000 dTs[5]=0.00000
udata->ts: 0x638f70
ts[0]=316.09846 ts[1]=283.41932 ts[2]=253.00015 ts[3]=224.61435 ts[4]=198.06463 ts[5]=173.17842
udata->vkp: 0x62e150
vkp[0]=-4.22868 vkp[1]=-2.73312 vkp[2]=2.80980 vkp[3]=-1.65961 vkp[4]=27.23419 vkp[5]=25.96871vkp[6]=16.03558 vkp[7]=10.69316
After the loop, I just use the following syntax to release memory,
delete [] udata->Ts;
delete [] udata->dTs;
delete [] udata->ts;
delete [] udata->vkp;
udata=NULL;
It can be seen the pointer and the content pointer points to keeps the same. Nothing changed. So the problems other met is excluded. And this is the only place I use delete.
ERROR information is as follows:
*** glibc detected *** /home/fenglei/mopso_oil_shale_cvode/mopso: munmap_chunk(): invalid pointer: 0x000000000062e150 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7eb96)[0x7ffff7286b96]
/home/fenglei/mopso_oil_shale_cvode/mopso[0x405890]
/home/fenglei/mopso_oil_shale_cvode/mopso[0x404b28]
/home/fenglei/mopso_oil_shale_cvode/mopso[0x407482]
/home/fenglei/mopso_oil_shale_cvode/mopso[0x409da5]
/home/fenglei/mopso_oil_shale_cvode/mopso[0x40ba63]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7ffff722976d]
/home/fenglei/mopso_oil_shale_cvode/mopso[0x401a09]
======= Memory map: ========
00400000-00429000 r-xp 00000000 08:06 4209122 {directory}/example
00628000-00629000 r--p 00028000 08:06 4209122 {directory}/example
00629000-0062a000 rw-p 00029000 08:06 4209122 {directory}/example
0062a000-0064b000 rw-p 00000000 00:00 0 [heap]
7ffff7208000-7ffff73bd000 r-xp 00000000 08:06 131963 /lib/x86_64- linux-gnu/libc-2.15.so
7ffff73bd000-7ffff75bd000 ---p 001b5000 08:06 131963 /lib/x86_64-linux-gnu/libc-2.15.so
7ffff75bd000-7ffff75c1000 r--p 001b5000 08:06 131963 /lib/x86_64-linux-gnu/libc-2.15.so
7ffff75c1000-7ffff75c3000 rw-p 001b9000 08:06 131963 /lib/x86_64-linux-gnu/libc-2.15.so
7ffff75c3000-7ffff75c8000 rw-p 00000000 00:00 0
7ffff75c8000-7ffff75dd000 r-xp 00000000 08:06 134855 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff75dd000-7ffff77dc000 ---p 00015000 08:06 134855 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff77dc000-7ffff77dd000 r--p 00014000 08:06 134855 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff77dd000-7ffff77de000 rw-p 00015000 08:06 134855 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff77de000-7ffff78d9000 r-xp 00000000 08:06 131976 /lib/x86_64-linux-gnu/libm-2.15.so
7ffff78d9000-7ffff7ad8000 ---p 000fb000 08:06 131976 /lib/x86_64-linux-gnu/libm-2.15.so
7ffff7ad8000-7ffff7ad9000 r--p 000fa000 08:06 131976 /lib/x86_64-linux-gnu/libm-2.15.so
7ffff7ad9000-7ffff7ada000 rw-p 000fb000 08:06 131976 /lib/x86_64-linux-gnu/libm-2.15.so
7ffff7ada000-7ffff7bbc000 r-xp 00000000 08:06 5250632 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7ffff7bbc000-7ffff7dbb000 ---p 000e2000 08:06 5250632 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7ffff7dbb000-7ffff7dc3000 r--p 000e1000 08:06 5250632 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7ffff7dc3000-7ffff7dc5000 rw-p 000e9000 08:06 5250632 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7ffff7dc5000-7ffff7dda000 rw-p 00000000 00:00 0
7ffff7dda000-7ffff7dfc000 r-xp 00000000 08:06 131977 /lib/x86_64-linux-gnu/ld-2.15.so
7ffff7fdc000-7ffff7fe1000 rw-p 00000000 00:00 0
7ffff7ff6000-7ffff7ffa000 rw-p 00000000 00:00 0
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00022000 08:06 131977 /lib/x86_64-linux-gnu/ld-2.15.so
7ffff7ffd000-7ffff7fff000 rw-p 00023000 08:06 131977 /lib/x86_64-linux-gnu/ld-2.15.so
7ffffffdd000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Program received signal SIGABRT, Aborted.
0x00007ffff723e425 in raise () from /lib/x86_64-linux-gnu/libc.so.6
This is the first time I post my questions here, although i got a lot of stuff from this website. I hope I made my problem clear.
Code:
/*
---------------------------------
*ODE problem solver definition
---------------------------------
*/
#include <stdio.h>
/* Header files with a description of contents used */
#include <cvode/cvode.h> /* prototypes for CVODE fcts., consts. */
#include <nvector/nvector_serial.h> /* serial N_Vector types, fcts., macros */
#include <cvode/cvode_dense.h> /* prototype for CVDense */
#include <sundials/sundials_dense.h> /* definitions DlsMat DENSE_ELEM */
#include <sundials/sundials_types.h> /* definition of type realtype */
/* User-defined vector and matrix accessor macros: Ith, IJth */
/* These macros are defined in order to write code which exactly matches
the mathematical problem description given above.
Ith(v,i) references the ith component of the vector v, where i is in
the range [1..NEQ] and NEQ is defined below. The Ith macro is defined
using the N_VIth macro in nvector.h. N_VIth numbers the components of
a vector starting from 0.
IJth(A,i,j) references the (i,j)th element of the dense matrix A, where
i and j are in the range [1..NEQ]. The IJth macro is defined using the
DENSE_ELEM macro in dense.h. DENSE_ELEM numbers rows and columns of a
dense matrix starting from 0. */
#define Ith(v,i) NV_Ith_S(v,i-1) /* Ith numbers components 1..NEQ */
#define IJth(A,i,j) DENSE_ELEM(A,i-1,j-1) /* IJth numbers rows,cols 1..NEQ */
/* Problem Constants */
#define RTOL RCONST(1.0e-4) /* scalar relative tolerance */
#define ATOL1 RCONST(1.0e-8) /* vector absolute tolerance components */
#define ATOL2 RCONST(1.0e-8)
#define ATOL3 RCONST(1.0e-8)
#define ATOL4 RCONST(1.0e-8)
#define Y(i) yt[i-1]
#define K(i) kt[i-1]
typedef struct {
unsigned int exp_ID, nExp,nRec, nComp;
realtype *Ts;
realtype *dTs;
realtype *ts;
realtype *vkp;
realtype Tr;
} User;
typedef User *UserData;
/* Functions Called by the Solver */
static int f(realtype t, N_Vector y, N_Vector ydot, void *user_data);
static int Jac(long int N, realtype t,
N_Vector y, N_Vector fy, DlsMat J, void *user_data,
N_Vector tmp1, N_Vector tmp2, N_Vector tmp3);
/* Private function to check function return values */
static int check_flag(void *flagvalue, const char *funcname, int opt);
int Reaction::cvodedensewrapper()
{
int i=0,j=0,k=0,m=0,numt;
realtype reltol,t,tout,ts;
N_Vector y, abstol;
void *cvode_mem;
int iout, flag;
User data;
UserData udata=& data;
/*Allocation and initialization*/
udata->Ts=new realtype[numExp];
udata->dTs=new realtype[numExp];
udata->ts=new realtype[numExp];
udata->vkp=new realtype[2*numRec];
udata->nExp=numExp;
udata->nRec=numRec;
udata->nComp=numComp;
udata->Tr=Tref;
for(i=0;i!=numExp;i++)
{
udata->Ts[i]=Tstart[i];
udata->dTs[i]=dT[i];
udata->ts[i]=tstart[i];
}
for(i=0;i!=2*numRec;i++)
{
udata->vkp[i]=vk[i];
}
/*for debugging*/
printf("udata->Ts: %p\n",udata->Ts);
for(i=0;i!=numExp;i++)
printf(" Ts[%d]=%.5f ",i,udata->Ts[i]);
printf("\n");
printf("udata->dTs: %p\n",udata->dTs);
for(i=0;i!=numExp;i++)
printf(" dTs[%d]=%.5f ",i,udata->dTs[i]);
printf("\n");
printf("udata->ts: %p\n",udata->ts);
for(i=0;i!=numExp;i++)
printf(" ts[%d]=%.5f ",i,udata->ts[i]);
printf("\n");
printf("udata->vkp: %p\n",udata->vkp);
for(i=0;i!=2*numRec;i++)
printf(" vkp[%d]=%.5f ",i,udata->vkp[i]);
printf("\n");
/*debugging end*/
y = abstol = NULL;
cvode_mem = NULL;
/* Create serial vector of length numRec for I.C. and abstol */
y = N_VNew_Serial(numComp);
if (check_flag((void *)y, "N_VNew_Serial", 0)) return(1);
abstol = N_VNew_Serial(numComp);
if (check_flag((void *)abstol, "N_VNew_Serial", 0)) return(1);
/* Initialize y */
for(i=0;i!=numComp;i++)
{
//Ith(y,i)=Yinitial[0][i-1];
NV_Ith_S(y,i)=Yinitial[0][i];
}
/*Initialize tstart*/
ts=tstart[0];
/* Set the scalar relative tolerance */
reltol = RTOL;
/* Set the vector absolute tolerance */
Ith(abstol,1)=ATOL1;
Ith(abstol,2)=ATOL2;
Ith(abstol,3)=ATOL3;
Ith(abstol,4)=ATOL3;
/* Call CVodeCreate to create the solver memory and specify the
* Backward Differentiation Formula and the use of a Newton iteration */
cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON);
if (check_flag((void *)cvode_mem, "CVodeCreate", 0)) return(1);
/* Set the pointer to user-defined data*/
flag=CVodeSetUserData(cvode_mem,udata);
if(check_flag((void *) cvode_mem,"CVodeCreate",0)) return(1);
/* Call CVodeInit to initialize the integrator memory and specify the
* user's right hand side function in y'=f(t,y), the inital time T0, and
* the initial dependent variable vector y. */
flag = CVodeInit(cvode_mem, f, ts, y);
if (check_flag(&flag, "CVodeInit", 1)) return(1);
/* Call CVodeSVtolerances to specify the scalar relative tolerance
* and vector absolute tolerances */
flag = CVodeSVtolerances(cvode_mem, reltol, abstol);
if (check_flag(&flag, "CVodeSVtolerances", 1)) return(1);
/* Call CVDense to specify the CVDENSE dense linear solver */
flag = CVDense(cvode_mem, numComp);
if (check_flag(&flag, "CVDense", 1)) return(1);
/* Set the Jacobian routine to Jac (user-supplied) */
flag = CVDlsSetDenseJacFn(cvode_mem, Jac);
if (check_flag(&flag, "CVDlsSetDenseJacFn", 1)) return(1);
/* In loop, call CVode, print results, and test for error.
Break out of loop when NOUT preset output times have been reached. */
for (m=0;m!=numExp;m++) {
numt=(int)(tend[m]-tstart[m])/dtsave[m]+1;
udata->exp_ID=m;
Yt[m].tvector[0]=tstart[m];
Yt[m].Tvector[0]=Tstart[m];
for(i=0;i!=numComp;i++)
{
Yt[m].resp[i][0]=Yinitial[m][i];
}
for(i=0;i!=numComp;i++)
{
//Ith(y,i)=Yinitial[m][i-1];
NV_Ith_S(y,i)=Yinitial[m][i];
}
ts=tstart[m];
flag = CVodeReInit(cvode_mem,ts, y);
iout = 0;
tout = tstart[m]+dtsave[m];
while(1) {
flag = CVode(cvode_mem, tout, y, &t, CV_NORMAL);
if (check_flag(&flag, "CVodeInit", 1)) return(1);
if (flag == CV_SUCCESS) {
iout++;
tout=t+dtsave[m];
}
Yt[m].tvector[iout]=t;
Yt[m].Tvector[iout]=Tstart[m]+(Yt[m].tvector[iout]-Yt[m].tvector[0])*dT[m];
for(i=0;i!=numComp;i++)
{
//Yt[m].resp[i-1][iout]=Ith(y,i);
Yt[m].resp[i][iout]=NV_Ith_S(y,i);
}
if (iout == numt) break;
}
/*for debugging*/
printf("udata->Ts: %p\n",udata->Ts);
for(i=0;i!=numExp;i++)
printf(" Ts[%d]=%.5f ",i,udata->Ts[i]);
printf("\n");
printf("udata->dTs: %p\n",udata->dTs);
for(i=0;i!=numExp;i++)
printf(" dTs[%d]=%.5f ",i,udata->dTs[i]);
printf("\n");
printf("udata->ts: %p\n",udata->ts);
for(i=0;i!=numExp;i++)
printf(" ts[%d]=%.5f ",i,udata->ts[i]);
printf("\n");
printf("udata->vkp: %p\n",udata->vkp);
for(i=0;i!=2*numRec;i++)
printf(" vkp[%d]=%.5f ",i,udata->vkp[i]);
printf("\n");
/*debugging end*/
}
/*Free userdata*/
delete [] udata->Ts;
delete [] udata->dTs;
delete [] udata->ts;
delete [] udata->vkp;
udata=NULL;
/*Free ODE solver array*/
N_VDestroy_Serial(y);
N_VDestroy_Serial(abstol);
/* Free integrator memory */
CVodeFree(&cvode_mem);
return(0);
}
/*
*-------------------------------
* Functions called by the solver
*-------------------------------
*/
/*
* f routine. Compute function f(t,y).
*/
/*
* Jacobian routine. Compute J(t,y) = df/dy. *
*/
Functions with CV initils are from shared libraries.
Your problem is almost certainly in the code you didn't show.
According to documentation for CVodeSetUserData, it simply passes UserData through to the function that the solver will eventually invoke (f in this case).
In any case, the tool that will point you straight at your bug is Valgrind. Just run your program under it, and it will tell you exactly how you are corrupting your heap.

Glibc Error: double free or corruption

I have been looking around at the meaning of this error and it seems to mean that I am freeing the same object more than once. I can't seem to figure out how to prevent this. Any help or suggestions would be much appreciated.
File(randname)
File(a.out)
~File(a.out)
~Directory(randname)
~File(null)
~File()
*** glibc detected *** a.out: double free or corruption (fasttop): 0x0804b048 ***
======= Backtrace: =========
/lib/libc.so.6(+0x6ff0b)[0xb74baf0b]
/usr/local/gcc/gcc-cilk/lib/libstdc++.so.6(_ZdlPv+0x1f)[0xb7671b4f]
/usr/local/gcc/gcc-cilk/lib/libstdc++.so.6(_ZdaPv+0x1b)[0xb7671b9b]
a.out[0x8048983]
a.out[0x8048b12]
a.out[0x80487d7]
/lib/libc.so.6(__libc_start_main+0xf3)[0xb7464003]
a.out[0x8048701]
======= Memory map: ========
08048000-08049000 r-xp 00000000 00:25 268562602 /home/user/test/a.out
08049000-0804a000 r--p 00000000 00:25 268562602 /home/user/test/a.out
0804a000-0804b000 rw-p 00001000 00:25 268562602 /home/user/test/a.out
0804b000-0806c000 rw-p 00000000 00:00 0 [heap]
b7448000-b744b000 rw-p 00000000 00:00 0
b744b000-b75b2000 r-xp 00000000 08:01 1365267 /lib/libc-2.14.1.so
b75b2000-b75b4000 r--p 00167000 08:01 1365267 /lib/libc-2.14.1.so
b75b4000-b75b5000 rw-p 00169000 08:01 1365267 /lib/libc-2.14.1.so
b75b5000-b75b8000 rw-p 00000000 00:00 0
b75b8000-b75d3000 r-xp 00000000 08:01 1179017 /usr/local/gcc/gcc-cilk/lib/libgcc_s.so.1
b75d3000-b75d4000 r--p 0001a000 08:01 1179017 /usr/local/gcc/gcc-cilk/lib/libgcc_s.so.1
b75d4000-b75d5000 rw-p 0001b000 08:01 1179017 /usr/local/gcc/gcc-cilk/lib/libgcc_s.so.1
b75d5000-b75fe000 r-xp 00000000 08:01 1365275 /lib/libm-2.14.1.so
b75fe000-b75ff000 r--p 00028000 08:01 1365275 /lib/libm-2.14.1.so
b75ff000-b7600000 rw-p 00029000 08:01 1365275 /lib/libm-2.14.1.so
b7622000-b7624000 rw-p 00000000 00:00 0
b7624000-b770b000 r-xp 00000000 08:01 1179021 /usr/local/gcc/gcc-cilk/lib/libstdc++.so.6.0.19
b770b000-b770f000 r--p 000e7000 08:01 1179021 /usr/local/gcc/gcc-cilk/lib/libstdc++.so.6.0.19
b770f000-b7710000 rw-p 000eb000 08:01 1179021 /usr/local/gcc/gcc-cilk/lib/libstdc++.so.6.0.19
b7710000-b7718000 rw-p 00000000 00:00 0
b7718000-b7737000 r-xp 00000000 08:01 1365260 /lib/ld-2.14.1.so
b7737000-b7738000 r--p 0001f000 08:01 1365260 /lib/ld-2.14.1.so
b7738000-b7739000 rw-p 00020000 08:01 1365260 /lib/ld-2.14.1.so
bfa18000-bfa39000 rw-p 00000000 00:00 0 [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0 [vdso]
Aborted
And here is the code:
#include <unistd.h>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
class File
{
protected:
unsigned char recordLen;
unsigned location;
unsigned fileSize;
unsigned char filenameLen;
char* filename;
public:
File(){filename = NULL;}
File(FILE* readFromHere, const char* name)
{
recordLen = 152;
location = 20003;
fileSize = 16348;
filenameLen = strlen(name);
filename = new char[filenameLen + 1];
strcpy(filename, name);
cout << "File(" << filename << ")\n";
}
File(const File& o)
{
if (o.filename == NULL)
filename = o.filename;
else
{
filename = new char[o.filenameLen + 1];
strcpy(filename, o.filename);
}
}
~File()
{
if (filename)
cout << "~File(" << filename << ")\n";
else
cout << "~File(null)\n";
if (filename != NULL)
delete[] filename;
}
};
class Directory : public File
{
protected:
int numContents;
File* contents;
public:
Directory(FILE* readFromHere, const char* name)
: File(readFromHere, name)
{
numContents = 2;
contents = new File[numContents];
contents[0] = File(readFromHere, "a.out");
//~ contents[1] = File(readFromHere, "otherfile.cpp");
}
~Directory()
{
if (filename)
cout << "~Directory(" << filename << ")\n";
else
cout << "~Directory(null)\n";
if (contents != NULL)
delete[] contents;
}
};
int main()
{
Directory d(NULL, "randname");
sleep(2);
return 0;
}
Your class doesn't follow the Rule of Three even though it owns resources. You have a copy constructor and a destructor, but not a copy assignment operator. Which means that this line:
contents[0] = File(readFromHere, "a.out");
invokes the default copy assignment operator, which happily copies pointers. There's your double-deletion problem.

Stack Smashing Using Message Queues

i have the following main code:
#include "ComHandler.h"
#include "socketMessage.h"
#define THIS_IP "localhost"
#define C_PORT 32456
#define S_PORT 25465
#define S_PORT_UDP 22548
int main(int argc, char* argv[]) {
conOptions opts;
strncpy(opts.password, "PASS", sizeof("PASS"));
opts.retryQty = 5;
opts.timeout = 300;
char dir[INET6_ADDRSTRLEN];
strncpy(dir, THIS_IP, sizeof(THIS_IP));
if (argv[1][0] == 'C') {
opts.connType = CLIENT_HANDLER;
opts.thisID = 2;
ComHandler comH(opts);
char buffer[10];
strncpy(buffer, "Testing", 10);
int rtnValue = comH.sendMsg(buffer, 10, 1, TCP_C);
std::cout << "Returned Value: " << rtnValue << std::endl;
} else {
opts.connType = SERVER_HANDLER;
opts.thisID = 1;
ComHandler comH(opts);
comH.addConnectionData(2, dir, C_PORT);
comH.addConnectionData(comH.getID(), dir, S_PORT);
char rcvdTxt[MINIDATA_DATA_SIZE];
comH.receiveMsg(rcvdTxt, MINIDATA_DATA_SIZE, 2, TCP_C);
std::cout << "Received: " << rcvdTxt << std::endl;
comH.closeCommunications();
}
}
The code is for testing my communication platform. The platform works well, but the problem appears when the messages are received by the Handler (ComHandler). When i call the method "receiveMsg" from ComHandler, i get a "stack smashing detected" in the "return" of the method.
This is the "ComHandler" class:
#ifndef COMHANDLER_H_
#define COMHANDLER_H_
#include "Constants.h"
#include "ComConstants.h"
#include "DataLogger.h"
#include <list>
#include <math.h>
#define CLIENT_HANDLER 1
#define SERVER_HANDLER 2
#define COMMENT_LINE '#'
#define TXT_SEPARATOR ';'
#define MINIDATA_DATA_SIZE (COMDATA_MAX_SIZE - 4* sizeof(int))
enum CON_TYPE {
TCP_C, UDP_C
};
#pragma pack(push)
#pragma pack(1)
typedef struct {
int totalPackets;
int sequenceNumber;
int sequenceID;
int dataSize;
char data[MINIDATA_DATA_SIZE];
} miniData;
#pragma pack(pop)
typedef struct connectionOptions {
unsigned int timeout;
unsigned int retryQty;
id_t thisID;
char password[PASSWORD_MAX_SIZE];
int connType;
connectionOptions() :
timeout(CON_TIMEOUT), retryQty(SOCKET_RETRIES), connType(
SERVER_HANDLER) {
memset(password, 0, PASSWORD_MAX_SIZE);
}
connectionOptions(connectionOptions& opt) {
timeout = opt.timeout;
retryQty = opt.retryQty;
thisID = opt.thisID;
connType = opt.connType;
memcpy(password, opt.password, PASSWORD_MAX_SIZE);
}
} conOptions;
class ComHandler {
private:
int dataForwarder_ReceiverMsgQueue;
int dataForwarder_SenderMsgQueue;
conOptions opts;
int sequenceID;
Semaphore ch_mux;
SharedMemory<comHandlerGlOp> ch_shm;
void cpyMiniData(miniData* to, miniData* from);
void createIPCs();
public:
ComHandler();
ComHandler(conOptions options);
ComHandler(id_t thisID);
virtual ~ComHandler();
int receiveMsg(char* buffer, int bufferSize, id_t originID,
CON_TYPE type = TCP_C);
int sendMsg(char* buffer, std::size_t bufferSize, id_t destinationID,
CON_TYPE type = TCP_C);
void configListenersData(char addr[INET6_ADDRSTRLEN], int port,
CON_TYPE type);
void addConnectionData(id_t id, char addr[INET6_ADDRSTRLEN], int port);
void addConnectionData(const char* file);
void modifyConnectionData(id_t id, char addr[INET6_ADDRSTRLEN], int port);
void removeConnectionData(id_t id);
int getID();
void closeCommunications();
};
#endif /* COMHANDLER_H_ */
The comData structure:
typedef struct {
long type;
int requestType;
char destination[INET6_ADDRSTRLEN];
char origin[INET6_ADDRSTRLEN];
id_t originID;
id_t destinationID;
int port;
pid_t senderPid;
pid_t originPid;
char data[COMDATA_MAX_SIZE];
} comData;
And the method with the problem:
int ComHandler::receiveMsg(char* buffer, int bufferSize, id_t originID,
CON_TYPE type) {
comData aux;
aux.type = DATA_RECEIVE;
int qtyReceived = 0;
if (originID != ANY_MSG_ORIGIN) {
if (type == TCP_C)
aux.requestType = RECEIVE_DATA_FROM_DESTINATION_TCP;
else
aux.requestType = RECEIVE_DATA_FROM_DESTINATION_UDP;
} else {
if (type == TCP_C)
aux.requestType = RECEIVE_ANY_DATA_TCP;
else
aux.requestType = RECEIVE_ANY_DATA_UDP;
}
aux.originID = originID;
aux.senderPid = getpid();
aux.originPid = getpid();
msgsnd(dataForwarder_ReceiverMsgQueue, &aux, sizeof(comData), 0);
msgrcv(dataForwarder_ReceiverMsgQueue, &aux, sizeof(comData), getpid(), 0);
/* More Code */
return qtyReceived;
}
The stack smashing error appears after "return qtyReceived;" is called. And the /* More Code */ in the middle is the non important code, because if a delete that part, the stack smashing stills appears.
After much debugging i found that the smashing appears if i call:
`msgrcv(dataForwarder_ReceiverMsgQueue, &aux, sizeof(comData), getpid(), 0);`
if i comment that line, i don't get the error.
Also with the debugger, i was able to see that the messages from the queue arrive with good format and size, exactly as they should.
The console output is:
*** stack smashing detected ***: /media/blackhole/workspace/Final/bin/ComTest terminated
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x45)[0xb7df88d5]
/lib/i386-linux-gnu/libc.so.6(+0xe7887)[0xb7df8887]
/media/blackhole/workspace/Final/bin/ComTest[0x804dc6b]
/media/blackhole/workspace/Final/bin/ComTest[0x804a002]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb7d2a113]
/media/blackhole/workspace/Final/bin/ComTest[0x8049d11]
======= Memory map: ========
08048000-08054000 r-xp 00000000 08:05 256373 /media/blackhole/workspace/Final/bin/ComTest
08054000-08055000 r--p 0000b000 08:05 256373 /media/blackhole/workspace/Final/bin/ComTest
08055000-08056000 rw-p 0000c000 08:05 256373 /media/blackhole/workspace/Final/bin/ComTest
08056000-08077000 rw-p 00000000 00:00 0 [heap]
b7d0f000-b7d11000 rw-p 00000000 00:00 0
b7d11000-b7e87000 r-xp 00000000 08:06 525221 /lib/i386-linux-gnu/libc-2.13.so
b7e87000-b7e89000 r--p 00176000 08:06 525221 /lib/i386-linux-gnu/libc-2.13.so
b7e89000-b7e8a000 rw-p 00178000 08:06 525221 /lib/i386-linux-gnu/libc-2.13.so
b7e8a000-b7e8d000 rw-p 00000000 00:00 0
b7e8d000-b7ea9000 r-xp 00000000 08:06 525242 /lib/i386-linux-gnu/libgcc_s.so.1
b7ea9000-b7eaa000 r--p 0001b000 08:06 525242 /lib/i386-linux-gnu/libgcc_s.so.1
b7eaa000-b7eab000 rw-p 0001c000 08:06 525242 /lib/i386-linux-gnu/libgcc_s.so.1
b7eab000-b7eac000 rw-p 00000000 00:00 0
b7eac000-b7ed4000 r-xp 00000000 08:06 525251 /lib/i386-linux-gnu/libm-2.13.so
b7ed4000-b7ed5000 r--p 00028000 08:06 525251 /lib/i386-linux-gnu/libm-2.13.so
b7ed5000-b7ed6000 rw-p 00029000 08:06 525251 /lib/i386-linux-gnu/libm-2.13.so
b7ed6000-b7fb4000 r-xp 00000000 08:06 5514 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7fb4000-b7fb5000 ---p 000de000 08:06 5514 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7fb5000-b7fb9000 r--p 000de000 08:06 5514 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7fb9000-b7fba000 rw-p 000e2000 08:06 5514 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7fba000-b7fc1000 rw-p 00000000 00:00 0
b7fdc000-b7fdd000 rw-s 00000000 00:04 163119127 /SYSV02056f32 (deleted)
b7fdd000-b7fdf000 rw-p 00000000 00:00 0
b7fdf000-b7fe0000 r-xp 00000000 00:00 0 [vdso]
b7fe0000-b7ffe000 r-xp 00000000 08:06 525208 /lib/i386-linux-gnu/ld-2.13.so
b7ffe000-b7fff000 r--p 0001d000 08:06 525208 /lib/i386-linux-gnu/ld-2.13.so
b7fff000-b8000000 rw-p 0001e000 08:06 525208 /lib/i386-linux-gnu/ld-2.13.so
bffdf000-c0000000 rw-p 00000000 00:00 0 [stack]
So, any ideas? If you need something about the code, just ask me.
According to this, the msgsz parameter of msgrcv() should be the size of the mtext member of the mymsg struct:
struct mymsg {
long int mtype; /* message type */
char mtext[1]; /* message text */
}
The problem is that you include the size of the mtype member (4 bytes) so msgrcv() writes four bytes past the end of your struct which trashes the stack.