что вызовет segfault при вызове mxCreateDoubleMatrix ()? - PullRequest
1 голос
/ 01 апреля 2011

Я связываюсь с matlab для записи matfiles из моего кода C.
При запуске следующего кода я получаю segfault (в первой строке):

pPressure_a = mxCreateDoubleMatrix((MWSIZE)2, (MWSIZE)dim, mxREAL);
if(pPressure_a == NULL){
    fatal("Memory alocation error.");
}
copyDoubleToPtr2D(temp2D_a, mxGetPr(pPressure_a), dim, 2);
matPutVariable(matfile, "p", pPressure_a);
mxDestroyArray(pPressure_a);

В приведенном вышеФрагмент, "MWSIZE" # определяется как int32_t, так как я компилирую это с помощью matlab R14, но #define позволяет легко изменить это для использования с другими версиями.Используя gdb, я подтвердил, что когда первая строка называется pPressure_a = 0x0;и dim = 501, которые являются совершенно допустимыми значениями.

Вот обратный след:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff73eeb5d in ?? () from /lib/libc.so.6

(gdb) bt
#0  0x00007ffff73eeb5d in ?? () from /lib/libc.so.6
#1  0x00007ffff73f103e in malloc () from /lib/libc.so.6
#2  0x00007ffff7730e35 in ?? () from /usr/local/matlabr14/bin/glnxa64/libut.so
#3  0x00007ffff7731600 in ?? () from /usr/local/matlabr14/bin/glnxa64/libut.so
#4  0x00007ffff7730046 in utCalloc () from /usr/local/matlabr14/bin/glnxa64/libut.so
#5  0x00007ffff7236c76 in mxCreateNumericMatrix () from /usr/local/matlabr14/bin/glnxa64/libmx.so
#6  0x00007ffff7237620 in mxCreateDoubleMatrix () from /usr/local/matlabr14/bin/glnxa64/libmx.so
#7  0x0000000000412c28 in calcCohAcoustPress (settings=0x646ab0) at /home/eey/models/cTraceo/./calcCohAcoustPress.c:324
#8  0x0000000000413736 in main (argc=2, argv=0x7fffffffe038) at cTraceo.c:137

(gdb) f 7
#7  0x0000000000412c28 in calcCohAcoustPress (settings=0x646ab0) at /home/eey/models/cTraceo/./calcCohAcoustPress.c:324
324            pPressure_a = mxCreateDoubleMatrix((MWSIZE)2, (MWSIZE)dim, mxREAL);

Я вызываю mxCreateDoubleMatrix () таким же образом (несколько раз) ранеев коде, и никогда не было проблем.

Что может быть причиной этого?

EDIT : Запуск valgrind создает несколько блоков, подобных этому:

==17538== Conditional jump or move depends on uninitialised value(s)
==17538==    at 0x4E560B8: csqrt (s_csqrt.c:66)
==17538==    by 0x40E149: solveDynamicEq (in cTraceo/bin/cTraceo-64b.bin)
==17538==    by 0x411BA5: calcCohAcoustPress (in cTraceo/bin/cTraceo-64b.bin)
==17538==    by 0x413555: main (in cTraceo/bin/cTraceo-64b.bin)

И заканчивается этим:

Invalid read of size 8
==17538==    at 0x412A3F: calcCohAcoustPress (in cTraceo/bin/cTraceo-64b.bin)
==17538==    by 0x413555: main (in cTraceo/bin/cTraceo-64b.bin)
==17538==  Address 0x86a3050 is 0 bytes after a block of size 16 alloc'd
==17538==    at 0x4C2815C: malloc (vg_replace_malloc.c:236)
==17538==    by 0x401781: mallocDouble2D (in cTraceo/bin/cTraceo-64b.bin)
==17538==    by 0x41296D: calcCohAcoustPress (in cTraceo/bin/cTraceo-64b.bin)
==17538==    by 0x413555: main (in cTraceo/bin/cTraceo-64b.bin)
==17538== 
==17538== Invalid write of size 8
==17538==    at 0x412A43: calcCohAcoustPress (in cTraceo/bin/cTraceo-64b.bin)
==17538==    by 0x413555: main (in cTraceo/bin/cTraceo-64b.bin)
==17538==  Address 0x0 is not stack'd, malloc'd or (recently) free'd

==17538== Process terminating with default action of signal 11 (SIGSEGV)
==17538==  Access not within mapped region at address 0x0
==17538==    at 0x412A43: calcCohAcoustPress (in cTraceo/bin/cTraceo-64b.bin)
==17538==    by 0x413555: main (in cTraceo/bin/cTraceo-64b.bin)
==17538==  If you believe this happened as a result of a stack
==17538==  overflow in your program's main thread (unlikely but
==17538==  possible), you can try to increase the size of the
==17538==  main thread stack using the --main-stacksize= flag.
==17538==  The main thread stack size used in this run was 8388608.
==17538== Invalid free() / delete / delete[]
==17538==    at 0x4C27D71: free (vg_replace_malloc.c:366)
==17538==    by 0x58FAA0A: free_mem (in /lib/libc-2.12.1.so)
==17538==    by 0x58FA5A1: __libc_freeres (in /lib/libc-2.12.1.so)
==17538==    by 0x4A2366B: _vgnU_freeres (vg_preloaded.c:62)
==17538==    by 0x7FEFFFD27: ???
==17538==    by 0x413555: main (in cTraceo/bin/cTraceo-64b.bin)
==17538==  Address 0x41508a0 is not stack'd, malloc'd or (recently) free'd

К сожалению, я новичок в valgrind и на самом деле не знаю, что это значит ...: p

Ответы [ 2 ]

1 голос
/ 02 апреля 2011

Возможно ли, что фактический сбой происходит не при вызове mxCreateDoubleMatrix (), а при вызове copyDoubleToPtr2D ()? Если это так, то это может быть связано с внутренним [чрезвычайно раздражающим и трудно отслеживаемым] ограничением MEX, упомянутым здесь . Решение состоит в том, чтобы просто использовать memcpy (), а не copyDoubleToPtr2D ().

0 голосов
/ 02 апреля 2011

Согласно справочной странице mxCreateDoubleMatrix () ... "Функция не работает, если недостаточно свободного пространства кучи для создания mxArray."

попробуйте эти флаги для gcc -Wl, - heap= large_enough_value

...