简体   繁体   English

调用 free() 时发生混合语言程序崩溃

[英]Mixed-language program crash occurs when free() called

I have a program where code in C, C++ and Fortran has been compiled and linked together.我有一个程序,其中 C、C++ 和 Fortran 中的代码已被编译并链接在一起。 The main function is written in C++ and is found in file testQ.cpp . main 函数是用 C++ 编写的,可以在文件testQ.cpp找到。 The C++ code calls a Fortran subroutine in file getqpf.F . C++ 代码调用文件getqpf.F的 Fortran 子例程。 The subroutine in getqpf.F calls C functions in a number of other files. getqpf.F的子例程调用许多其他文件中的 C 函数。

Using gcc and gfortran on GNU/Linux I have successfully linked together the program:在 GNU/Linux 上使用gccgfortran我已经成功地将程序链接在一起:

 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()时在终止之前崩溃:

free(x1);

This is the last statement in the program, and the program will only crash when free() is called.这是程序中的最后一条语句,只有在调用free()时程序才会崩溃。 Now x1 is created using the following malloc :现在x1是使用以下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. x1指针传递给 Fortran 代码,Fortran 子例程将其传递给 C 代码函数。

Here is the output of the crash.这是崩溃的输出。 What could be going wrong here, and how might I debug this?这里可能出了什么问题,我该如何调试? I've recently installed valgrind .我最近安装了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.运行valgrind --tool=memcheck --leak-check=full --log-file=memcheck.log ./test-Q ,我得到了一个看起来很奇怪的日志文件。 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.正如 mux 在下面的答案中敏锐地建议的那样,超出数组范围的写入确实是一个问题。 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.我修改了向量以保存float类型的元素,但真正的问题确实是超出数组范围的写入。

The C-style array was created using malloc() , but the sizeof() function had to be used to create adequate space. C 风格的数组是使用malloc()创建的,但必须使用sizeof()函数来创建足够的空间。

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.看起来您的程序中某处存在内存泄漏,您提供的输出根本没有帮助,您应该使用valgrind运行程序来解决问题。 Try:尝试:

valgrind --tool=memcheck --leak-check=full --log-file=memcheck.log <binary>

If you fork any child processes you may want to add:如果您fork任何子进程,您可能需要添加:

--trace-children=yes

Then post the memcheck.log and the relevant code if you still can't fix it.还是不行就把memcheck.log和相关代码贴出来。

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.你应该先解决这个问题,这可能是问题所在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 两次调用时为什么会崩溃? - Why does free crash when called twice? 如何从通用块-全局结构别名重新设计Fortran和C ++混合语言库? - How to re-engineer Fortran and C++ mixed-language library from common blocks - global struct aliasing? 智能指针如何知道何时在程序崩溃时释放资源? - How do smart pointers know when to free the resources on program crash? 当选项字符串包含混合语言字符时,boost :: program_option :: store抛出异常 - boost::program_option::store throws exception when option string contains mixed language characters 调用 free() 有时会导致程序崩溃 - Calling free() sometimes causes program to crash 移植到Windows时程序崩溃 - Program crash when ported to windows 发生段错误时何时不调用信号处理程序? - When signal handler is not called when segment fault occurs? 为什么析构函数被两次调用时我的程序不会崩溃 - Why my program does not crash if destructor is called twice 强行迫使程序因输入不同而崩溃的策略是什么? - What's the strategy called of brute forcing a program to crash with different inputs? 在IMMDeviceEnumerator上调用SAFE_RELEASE时崩溃 - Crash when SAFE_RELEASE is called on IMMDeviceEnumerator
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM