Note that there are some explanatory texts on larger screens.

plurals
  1. POMixed-language program crash occurs when free() called
    primarykey
    data
    text
    <p>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 <code>testQ.cpp</code>. The C++ code calls a Fortran subroutine in file <code>getqpf.F</code>. The subroutine in <code>getqpf.F</code> calls C functions in a number of other files.</p> <p>Using <code>gcc</code> and <code>gfortran</code> on GNU/Linux I have successfully linked together the program:</p> <pre><code> 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 </code></pre> <p>The program appears to run normally. However, it crashes before terminating when <code>free()</code> is called: </p> <pre><code>free(x1); </code></pre> <p>This is the last statement in the program, and the program will only crash when <code>free()</code> is called. Now <code>x1</code> is created using the following <code>malloc</code>:</p> <pre><code>double *x1; x1 = (double*)malloc(iXget); </code></pre> <p>The <code>x1</code> pointer is passed in to the Fortran code, and the Fortran subroutine passes it into a C code function.</p> <p>Here is the output of the crash. What could be going wrong here, and how might I debug this? I've recently installed <code>valgrind</code>. How can I use this to debug my program?</p> <pre><code>*** 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 </code></pre> <p><strong>UPDATE</strong></p> <p>After running <code>valgrind --tool=memcheck --leak-check=full --log-file=memcheck.log ./test-Q</code>, I get a rather curious-looking log file. Perhaps something isn't set up properly? Here it is:</p> <pre><code>==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&lt;double, std::allocator&lt;double&gt; &gt;) (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&lt;double, std::allocator&lt;double&gt; &gt;) (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&lt;double, std::allocator&lt;double&gt; &gt;) (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. </code></pre> <p><strong>UPDATE</strong></p> <p>Here is the function in question with the array.</p> <pre><code>// main function int main() { run_experiment(); } void run_experiment() { const int MAX_VAL = 1001; std::string line; std::ifstream myfile ("s1.txt"); std::vector&lt;double&gt;data(MAX_VAL); int cnt = 0; double val; if (myfile.is_open()) { while ( myfile.good() &amp;&amp; cnt &lt; MAX_VAL) { std::getline (myfile,line); val = boost::lexical_cast&lt;double&gt;(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 &lt;&lt; "Unable to open file"; } // end </code></pre> <p>Here is the function declaration. The vector is being passed by value.</p> <pre><code>void call_function(std::vector&lt;double&gt; v); </code></pre> <p><strong>UPDATE</strong></p> <p>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 <code>float</code>, but the real issue was indeed writing beyond the bounds of an array.</p> <p>The C-style array was created using <code>malloc()</code>, but the <code>sizeof()</code> function had to be used to create adequate space.</p> <p>Changing this one line of code causes the error to go away.</p> <pre><code> // function to call code in the q analysis function void call_function(std::vector&lt;float&gt; 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 &lt; nsamp; i++) tri[i] = v[i]; std::cout &lt;&lt; "Done copying data to the vector" &lt;&lt; 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&lt;float&gt;data(MAX_VAL); int cnt = 0; float val; if (myfile.is_open()) { while ( myfile.good() &amp;&amp; cnt &lt; MAX_VAL) { std::getline (myfile,line); val = boost::lexical_cast&lt;double&gt;(line); data[cnt++] = val; } myfile.close(); /* for (int i = 0; i &lt; 1001; i++) std::cout &lt;&lt; data[i] &lt;&lt; std::endl; */ // call the function to do the data processing call_function(data); } else std::cout &lt;&lt; "Unable to open file"; } // end int main() { run_experiment(); } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload