I have a program where code in C, C++ and Fortran has been compiled and linked together. The main function is written in C++ and is found in file testQ.cpp. The C++ code calls a Fortran subroutine in file getqpf.F. The subroutine in getqpf.F calls C functions in a number of other files.
Using gcc and gfortran on GNU/Linux I have successfully linked together the program:
g++ -c test-Q.cpp -I./boost/boost_1_52_0/ -g
gcc -c paul2.c -g
gcc -c paul2_L1.c -g
gcc -c paul6.c -g
gcc -c paul6_L1.c -g
gcc -c fit_slope.c -g
gfortran -c getqpf.F -g
g++ -o test-Q test-Q.o paul2.o paul2_L1.o paul6.o paul6_L1.o fit_slope.o getqpf.o -g -lgfortran
The program appears to run normally. However, it crashes before terminating when free() is called:
free(x1);
This is the last statement in the program, and the program will only crash when free() is called. Now x1 is created using the following malloc:
double *x1;
x1 = (double*)malloc(iXget);
The x1 pointer is passed in to the Fortran code, and the Fortran subroutine passes it into a C code function.
Here is the output of the crash. What could be going wrong here, and how might I debug this? I've recently installed valgrind. How can I use this to debug my program?
*** glibc detected *** ./test-Q: free(): invalid next size (normal): 0x0000000000f50aa0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7ae16)[0x7feabf64de16]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x6c)[0x7feabf6520fc]
./test-Q[0x402520]
./test-Q[0x4026b2]
./test-Q[0x401dbd]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7feabf5f430d]
./test-Q[0x401cf9]
======= Memory map: ========
00400000-0040b000 r-xp 00000000 08:11 9714095 /media/RESEARCH/SAS2-version2/test-Q/test-Q
0060a000-0060b000 r--p 0000a000 08:11 9714095 /media/RESEARCH/SAS2-version2/test-Q/test-Q
0060b000-0060c000 rw-p 0000b000 08:11 9714095 /media/RESEARCH/SAS2-version2/test-Q/test-Q
00f39000-00f5a000 rw-p 00000000 00:00 0 [heap]
7feab8000000-7feab8021000 rw-p 00000000 00:00 0
7feab8021000-7feabc000000 ---p 00000000 00:00 0
7feabf39d000-7feabf3d2000 r-xp 00000000 08:01 18881806 /usr/lib/x86_64-linux-gnu/libquadmath.so.0.0.0
7feabf3d2000-7feabf5d1000 ---p 00035000 08:01 18881806 /usr/lib/x86_64-linux-gnu/libquadmath.so.0.0.0
7feabf5d1000-7feabf5d2000 r--p 00034000 08:01 18881806 /usr/lib/x86_64-linux-gnu/libquadmath.so.0.0.0
7feabf5d2000-7feabf5d3000 rw-p 00035000 08:01 18881806 /usr/lib/x86_64-linux-gnu/libquadmath.so.0.0.0
7feabf5d3000-7feabf76c000 r-xp 00000000 08:01 16515356 /lib/x86_64-linux-gnu/libc-2.13.so
7feabf76c000-7feabf96b000 ---p 00199000 08:01 16515356 /lib/x86_64-linux-gnu/libc-2.13.so
7feabf96b000-7feabf96f000 r--p 00198000 08:01 16515356 /lib/x86_64-linux-gnu/libc-2.13.so
7feabf96f000-7feabf970000 rw-p 0019c000 08:01 16515356 /lib/x86_64-linux-gnu/libc-2.13.so
7feabf970000-7feabf976000 rw-p 00000000 00:00 0
7feabf976000-7feabf98b000 r-xp 00000000 08:01 16518820 /lib/x86_64-linux-gnu/libgcc_s.so.1
7feabf98b000-7feabfb8a000 ---p 00015000 08:01 16518820 /lib/x86_64-linux-gnu/libgcc_s.so.1
7feabfb8a000-7feabfb8b000 r--p 00014000 08:01 16518820 /lib/x86_64-linux-gnu/libgcc_s.so.1
7feabfb8b000-7feabfb8c000 rw-p 00015000 08:01 16518820 /lib/x86_64-linux-gnu/libgcc_s.so.1
7feabfb8c000-7feabfc0f000 r-xp 00000000 08:01 16515346 /lib/x86_64-linux-gnu/libm-2.13.so
7feabfc0f000-7feabfe0e000 ---p 00083000 08:01 16515346 /lib/x86_64-linux-gnu/libm-2.13.so
7feabfe0e000-7feabfe0f000 r--p 00082000 08:01 16515346 /lib/x86_64-linux-gnu/libm-2.13.so
7feabfe0f000-7feabfe10000 rw-p 00083000 08:01 16515346 /lib/x86_64-linux-gnu/libm-2.13.so
7feabfe10000-7feabfef8000 r-xp 00000000 08:01 18881835 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7feabfef8000-7feac00f8000 ---p 000e8000 08:01 18881835 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7feac00f8000-7feac0100000 r--p 000e8000 08:01 18881835 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7feac0100000-7feac0102000 rw-p 000f0000 08:01 18881835 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7feac0102000-7feac0117000 rw-p 00000000 00:00 0
7feac0117000-7feac022b000 r-xp 00000000 08:01 18883022 /usr/lib/x86_64-linux-gnu/libgfortran.so.3.0.0
7feac022b000-7feac042a000 ---p 00114000 08:01 18883022 /usr/lib/x86_64-linux-gnu/libgfortran.so.3.0.0
7feac042a000-7feac042b000 r--p 00113000 08:01 18883022 /usr/lib/x86_64-linux-gnu/libgfortran.so.3.0.0
7feac042b000-7feac042d000 rw-p 00114000 08:01 18883022 /usr/lib/x86_64-linux-gnu/libgfortran.so.3.0.0
7feac042d000-7feac044e000 r-xp 00000000 08:01 16515354 /lib/x86_64-linux-gnu/ld-2.13.so
7feac0630000-7feac0636000 rw-p 00000000 00:00 0
7feac064a000-7feac064d000 rw-p 00000000 00:00 0
7feac064d000-7feac064e000 r--p 00020000 08:01 16515354 /lib/x86_64-linux-gnu/ld-2.13.so
7feac064e000-7feac0650000 rw-p 00021000 08:01 16515354 /lib/x86_64-linux-gnu/ld-2.13.so
7fff2940a000-7fff2942b000 rw-p 00000000 00:00 0 [stack]
7fff2952c000-7fff2952d000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted
UPDATE
After running valgrind --tool=memcheck --leak-check=full --log-file=memcheck.log ./test-Q, I get a rather curious-looking log file. Perhaps something isn't set up properly? Here it is:
==15621== Memcheck, a memory error detector
==15621== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==15621== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==15621== Command: ./test-Q
==15621== Parent PID: 14623
==15621==
==15621== Invalid write of size 4
==15621== at 0x401EE2: call_function(std::vector<double, std::allocator<double> >) (test-Q.cpp:183)
==15621== by 0x4026B1: run_experiment() (test-Q.cpp:346)
==15621== by 0x401DBC: main (test-Q.cpp:120)
==15621== Address 0x5ecba78 is 1,000 bytes inside a block of size 1,001 alloc'd
==15621== at 0x4C2A66F: malloc (vg_replace_malloc.c:270)
==15621== by 0x401E9A: call_function(std::vector<double, std::allocator<double> >) (test-Q.cpp:179)
==15621== by 0x4026B1: run_experiment() (test-Q.cpp:346)
==15621== by 0x401DBC: main (test-Q.cpp:120)
==15621==
--15621-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
--15621-- si_code=80; Faulting address: 0x0; sp: 0x4030e0df0
valgrind: the 'impossible' happened:
Killed by fatal signal
==15621== at 0x380624A6: vgPlain_arena_malloc (m_mallocfree.c:291)
==15621== by 0x380294E4: vgMemCheck_new_block (mc_malloc_wrappers.c:263)
==15621== by 0x3802967A: vgMemCheck_malloc (mc_malloc_wrappers.c:301)
==15621== by 0x3809D05D: vgPlain_scheduler (scheduler.c:1665)
==15621== by 0x380AC715: run_a_thread_NORETURN (syswrap-linux.c:103)
sched status:
running_tid=1
Thread 1: status = VgTs_Runnable
==15621== at 0x4C2A66F: malloc (vg_replace_malloc.c:270)
==15621== by 0x401FB9: call_function(std::vector<double, std::allocator<double> >) (test-Q.cpp:217)
==15621== by 0x4026B1: run_experiment() (test-Q.cpp:346)
==15621== by 0x401DBC: main (test-Q.cpp:120)
Note: see also the FAQ in the source distribution.
It contains workarounds to several common problems.
In particular, if Valgrind aborted or crashed after
identifying problems in your program, there's a good chance
that fixing those problems will prevent Valgrind aborting or
crashing, especially if it happened in m_mallocfree.c.
If that doesn't help, please report this bug to: www.valgrind.org
In the bug report, send all the above text, the valgrind
version, and what OS and version you are using. Thanks.
UPDATE
Here is the function in question with the array.
// main function
int main()
{
run_experiment();
}
void run_experiment()
{
const int MAX_VAL = 1001;
std::string line;
std::ifstream myfile ("s1.txt");
std::vector<double>data(MAX_VAL);
int cnt = 0;
double val;
if (myfile.is_open())
{
while ( myfile.good() && cnt < MAX_VAL)
{
std::getline (myfile,line);
val = boost::lexical_cast<double>(line);
data[cnt++] = val;
}
myfile.close();
// data vector seems to be OK here
// call the function to do the data processing
// this is the line 346 called into question by Valgrind
// run_experiment() (test-Q.cpp:346)
call_function(data);
}
else std::cout << "Unable to open file";
} // end
Here is the function declaration. The vector is being passed by value.
void call_function(std::vector<double> v);
UPDATE
As astutely suggested by mux in an answer below, it is indeed a problem with writing beyond the bounds of an array. Here is the version of the code that works, with the wrong code shown in the comments. I modified the vector to hold elements of type float, but the real issue was indeed writing beyond the bounds of an array.
The C-style array was created using malloc(), but the sizeof() function had to be used to create adequate space.
Changing this one line of code causes the error to go away.
// function to call code in the q analysis function
void call_function(std::vector<float> v)
{
// create all of the inputs
float *tri = NULL;
int nsamp;
int lwin;
int nfreqfit; // calculated below
float dt;
float null;
int L2;
float df; // calculated below
float *qq = NULL;
float *pf = NULL;
float *ampls;
double *work1;
double *work2;
double *work3;
double *work4;
int mem;
int morder;
int nfs; // calculated below
double *xReal = NULL;
double *xImag = NULL;
double *xAbs = NULL;
double *x1 = NULL;
int cen;
int top;
int bot;
float cut;
int nfst; // calculated below
int raw;
float fst; // low frequency to fit; replaces fpeak frequency
nsamp = v.size();
lwin = 101;
dt = 0.0042;
null = 100;
L2 = 1;
mem = 0; // keep this as is
morder = 5;
cen = 1;
top = 0;
bot = 0;
cut = 0.50;
raw = 1;
fst = 0.0; // lowest frequency to fit
// this is the line that was changed
tri = (float*)malloc(nsamp * sizeof(float));
// This is the line that needed changing
// tri = (float*)malloc(nsamp);
// copy the data into the vector
for (int i = 0; i < nsamp; i++)
tri[i] = v[i];
std::cout << "Done copying data to the vector" << std::endl;
// more code here...
} // end of function
void run_experiment()
{
const int MAX_VAL = 1001;
std::string line;
std::ifstream myfile ("s1.txt");
std::vector<float>data(MAX_VAL);
int cnt = 0;
float val;
if (myfile.is_open())
{
while ( myfile.good() && cnt < MAX_VAL)
{
std::getline (myfile,line);
val = boost::lexical_cast<double>(line);
data[cnt++] = val;
}
myfile.close();
/*
for (int i = 0; i < 1001; i++)
std::cout << data[i] << std::endl;
*/
// call the function to do the data processing
call_function(data);
}
else std::cout << "Unable to open file";
} // end
int main()
{
run_experiment();
}
It looks like you have a memory leak somewhere in your program, the output you provided isn't really helpful at all, you should run the program with valgrind to figure the problem. Try:
valgrind --tool=memcheck --leak-check=full --log-file=memcheck.log <binary>
If you fork any child processes you may want to add:
--trace-children=yes
Then post the memcheck.log and the relevant code if you still can't fix it.
Edit: it seems that you're writing beyond the bounds of some array here:
call_function(std::vector<double, std::allocator<double> >) (test-Q.cpp:183)
You should fix that first, it could be the problem.
Related
I came from this link: Force gdb to load shared library at randomized address and I learned that gdb will disable ASLR for the current process.
But the only way I know to disable ASLR is to do it globally via echo 0 > /proc/sys/kernel/randomize_va_space.
Now I'm wondering how does gdb disable ASLR on startup, and only for the current process?
EDIT
As ssbssa suggested, I wrote a program to test it:
#include <stdio.h>
#include <unistd.h>
#include <sys/personality.h>
int main(int argc, char **argv)
{
char *argv2[] = { argv[0], "test", "\0" };
if (argc == 1)
{
char *data = malloc(20);
printf("pid %d\n", getpid());
printf("heap allocated at %p\n", data);
printf("system() at %p\n", system);
puts("exit in 100s");
sleep(100);
exit(0);
}
personality(ADDR_NO_RANDOMIZE);
execvp(argv2[0], argv2);
}
And the process map is:
# cat /proc/1997932/maps
00400000-00401000 r--p 00000000 fc:01 430424 /root/no-aslr
00401000-00402000 r-xp 00001000 fc:01 430424 /root/no-aslr
00402000-00403000 r--p 00002000 fc:01 430424 /root/no-aslr
00403000-00404000 r--p 00002000 fc:01 430424 /root/no-aslr
00404000-00405000 rw-p 00003000 fc:01 430424 /root/no-aslr
01352000-01373000 rw-p 00000000 00:00 0 [heap]
7f222f928000-7f222f94a000 r--p 00000000 fc:01 394264 /usr/lib/x86_64-linux-gnu/libc-2.31.so
7f222f94a000-7f222fac2000 r-xp 00022000 fc:01 394264 /usr/lib/x86_64-linux-gnu/libc-2.31.so
7f222fac2000-7f222fb10000 r--p 0019a000 fc:01 394264 /usr/lib/x86_64-linux-gnu/libc-2.31.so
7f222fb10000-7f222fb14000 r--p 001e7000 fc:01 394264 /usr/lib/x86_64-linux-gnu/libc-2.31.so
7f222fb14000-7f222fb16000 rw-p 001eb000 fc:01 394264 /usr/lib/x86_64-linux-gnu/libc-2.31.so
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;
}
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
I have one problem. I am trying to get stack offset range from /proc/self/maps pseudofile. But I have sometime weird things.
Here is my code
fp = fopen("/proc/self/maps", "r");
if (fp == NULL) {
perror("Error opening file");
return NULL;
}
while (fgets(line, 2048, fp) != NULL) {
if (strstr(line, "stack") != NULL) {
printf("%s", line);
}
}
If you start the programm with one or multiple thread you can view this pseudo file and get something like this
7f20423a6000-7f2042ba6000 rw-p 00000000 00:00 0 [stack:3936]
7fffbe95e000-7fffbe97f000 rw-p 00000000 00:00 0 [stack]
the first line here is stack of thread , the second line is the stack of the process.
But the problem is that sometimes I cannot get stack of thread. It can be from the first time or appear on some next execution so it is not determined. On some distos it doesn't show stack of thread at all, I don't think the problem is in different implementation of pseudo file in distros but in something other.
Please help to solve this problem
EDIT
I actually call this function inside thread , so I create thread through pthread_create(&tid, NULL, proc_stack, NULL);I have been also thinking about this. Maybe it needs some time to update this pseudofile after thread start, this is only one reason I see here.
EDIT2
I've tried to call sleep forcely , but this didn't help, but the most weird is that on one distro it shows thread stack, on another doesn't.
On my system Your program also dosn't show second stack segment, but it seems 5 segments are allocated above [heap] and one of them is used for thread stack (local variables of proc_stack() are stored in this segment).
Code I used to check for it (test.c):
#include <stdio.h>
#include <string.h>
#include <pthread.h>
void* proc_stack(void* p){
FILE *fp;
char line[2048];
fp = fopen("/proc/self/maps", "r");
if (fp == NULL) {
perror("Error opening file");
return NULL;
}
while (fgets(line, 2048, fp) != NULL) {
// if (strstr(line, "stack") != NULL) {
printf("%s", line);
// }
}
printf("addr = %p %p\n", &fp, &line);
return NULL;
}
int main(){
pthread_t tid;
void *rv;
proc_stack( NULL );
puts("main");
pthread_create( &tid, NULL, proc_stack, NULL );
pthread_join( tid, &rv );
return 0;
}
Compiled with gcc -Wall test.c -pthread. Results (some lines removed):
...
01933000-01954000 rw-p 00000000 00:00 0 [heap]
...
7fff75be3000-7fff75c04000 rw-p 00000000 00:00 0 [stack]
7fff75d97000-7fff75d98000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
addr = 0x7fff75c00e68 0x7fff75c00e70
main
...
01933000-01954000 rw-p 00000000 00:00 0 [heap]
7f3be0000000-7f3be0021000 rw-p 00000000 00:00 0
7f3be0021000-7f3be4000000 ---p 00000000 00:00 0
7f3be6b79000-7f3be6b7a000 rw-p 00000000 00:00 0
7f3be6b7a000-7f3be6b7b000 ---p 00000000 00:00 0
7f3be6b7b000-7f3be737b000 rw-p 00000000 00:00 0
...
7fff75be3000-7fff75c04000 rw-p 00000000 00:00 0 [stack]
7fff75d97000-7fff75d98000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
addr = 0x7f3be73796c8 0x7f3be73796d0
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.