У меня есть программа, в которой код на C, C ++ и Fortran был скомпилирован и связан вместе. Основная функция написана на C ++ и находится в файле testQ.cpp
, Код C ++ вызывает подпрограмму Fortran в файле getqpf.F
, Подпрограмма в getqpf.F
вызывает функции C в ряде других файлов.
С помощью gcc
а также gfortran
в GNU / Linux я успешно соединил программу:
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
Программа, кажется, работает нормально. Тем не менее, он падает до завершения, когда free()
называется:
free(x1);
Это последнее утверждение в программе, и программа будет аварийно завершать работу только тогда, когда free()
называется. Сейчас x1
создается с использованием следующего malloc
:
double *x1;
x1 = (double*)malloc(iXget);
x1
указатель передается в код Fortran, а подпрограмма Fortran передает его в функцию C-кода.
Вот вывод аварии. Что может быть не так, и как я могу отладить это? Я недавно установил valgrind
, Как я могу использовать это для отладки моей программы?
*** 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
ОБНОВИТЬ
После запуска valgrind --tool=memcheck --leak-check=full --log-file=memcheck.log ./test-Q
Я получаю довольно любопытный файл журнала. Возможно, что-то настроено неправильно? Вот:
==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.
ОБНОВИТЬ
Вот рассматриваемая функция с массивом.
// 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
Вот объявление функции. Вектор передается по значению.
void call_function(std::vector<double> v);
ОБНОВИТЬ
Как убедительно указывает mux в ответе ниже, это действительно проблема с записью за пределами массива. Вот версия кода, которая работает, с неправильным кодом, показанным в комментариях. Я изменил вектор для хранения элементов типа float
, но реальная проблема действительно заключалась в написании за пределами массива.
Массив в стиле C был создан с использованием malloc()
, но sizeof()
Функция должна быть использована для создания адекватного пространства.
Изменение этой строки кода приводит к исчезновению ошибки.
// 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 frequencynsamp = 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 functionvoid 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";
} // endint main()
{
run_experiment();
}
Похоже, что у вас есть утечка памяти где-то в вашей программе, предоставленный вами вывод не очень полезен, вы должны запустить программу с Valgrind чтобы понять проблему. Пытаться:
valgrind --tool=memcheck --leak-check=full --log-file=memcheck.log <binary>
если ты fork
любые дочерние процессы, которые вы можете добавить:
--trace-children=yes
Затем опубликуйте memcheck.log и соответствующий код, если вы все еще не можете это исправить.
Изменить: кажется, что вы пишете за пределами некоторого массива здесь:
call_function(std::vector<double, std::allocator<double> >) (test-Q.cpp:183)
Вы должны сначала это исправить, это может быть проблемой.
Других решений пока нет …