Это большой выход, который вы получили здесь.Вы должны были сжать это больше в областях, которые вас интересуют.Однако я попытаюсь дать несколько общих указателей.
==2441== Invalid write of size 4
открывает «блок», который сообщает вам подробности о выделенной памяти и обратный след стека ее выделения и места ошибки.==2441==
- это PID процесса, который полезен в случаях, когда несколько процессов выполняются параллельно.
Сайт ошибки (комментарии добавляются с #
).Обратная трассировка стека всегда в обратном порядке, это означает, что сайт с аварийным завершением (или то, что обычно было бы аварийным) обычно находится в верхней части списка, а вызовы, которые привели к нему, перечислены в обратном порядке:
# This points to a function nodes_term32_flush() in file tyn_indexer.c on line 227
==2441== at 0x404893: nodes_term32_flush (tyn_indexer.c:227)
# the format is the same, at this line tyn_exsorter_sort() calls nodes_term32_flush()
==2441== by 0x407B77: tyn_exsorter_sort (tyn_exsorter.c:131)
# ... and so on
==2441== by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
# ... leading up to the process "entry point"
==2441== by 0x40384F: main (tyn_indexer.c:943)
Блок памяти, который был затронут.Первая строка говорит нам, что был выделен блок ровно одного МиБ и что (вместе с выводом выше) вы читали первые 4 байта (вероятно, 32-битное значение) после последнего выделенного байта этого блока.Остальная часть формата соответствует тому, что вы знаете из описанной выше трассировки стека.
==2441== Address 0x1233c080 is 0 bytes after a block of size 1,048,576 alloc'd
==2441== at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==2441== by 0x406BEB: tyn_build_index (tyn_indexer.c:663)
==2441== by 0x40384F: main (tyn_indexer.c:943)
Все последующие повторения - по опыту - чаще всего являются следствием первой ошибки.Поэтому всегда начинайте исправлять первую перечисленную проблему в последовательности сообщенных проблем.
Теперь для другого класса ошибок, который появляется в ваших выходных данных:
==2441== Use of uninitialised value of size 8
# All library functions here ...
==2441== at 0x3AE9C4726B: _itoa_word (in /lib64/libc-2.14.90.so)
==2441== by 0x3AE9C49852: vfprintf (in /lib64/libc-2.14.90.so)
==2441== by 0x3AE9C51FE8: printf (in /lib64/libc-2.14.90.so)
# ... but this one should be yours. Check out this file/line to see what can be the problem with the printf() call
==2441== by 0x4071EF: tyn_build_index (tyn_indexer.c:888)
==2441== by 0x40384F: main (tyn_indexer.c:943)
Следующеескорее всего, это просто следствие вышеприведенного вывода:
==2441== Conditional jump or move depends on uninitialised value(s)
==2441== at 0x3AE9C47275: _itoa_word (in /lib64/libc-2.14.90.so)
==2441== by 0x3AE9C49852: vfprintf (in /lib64/libc-2.14.90.so)
==2441== by 0x3AE9C51FE8: printf (in /lib64/libc-2.14.90.so)
==2441== by 0x4071EF: tyn_build_index (tyn_indexer.c:888)
==2441== by 0x40384F: main (tyn_indexer.c:943)
Я настоятельно рекомендую две вещи: прочитайте руководство Valgrind (я знаю, это звучит покровительственно, но оно того стоит) и сделайтеиспользовать его много вариантов.Я создал несколько функций, которые я использую на своих машинах для разработки:
# vim: set autoindent smartindent tabstop=2 shiftwidth=2 expandtab filetype=sh:
function vgrun
{
local COMMAND="$1"
local NAME="$2"
[[ -n "$COMMAND" ]] || { echo "Syntax: vgrun <command> <name>"; return; }
[[ -n "$NAME" ]] || { echo "Syntax vgrun <command> <name>"; return; }
valgrind \
--leak-check=full --error-limit=no --track-origins=yes \
--undef-value-errors=yes --log-file=valgrind-${NAME}.log \
--read-var-info=yes \
$COMMAND | tee valgrind-${NAME}-output.log 2>&1
}
function vgtrace
{
local COMMAND="$1"
local NAME="$2"
[[ -n "$COMMAND" ]] || { echo "Syntax: vgtrace <command> <name>"; return; }
[[ -n "$NAME" ]] || { echo "Syntax vgtrace <command> <name>"; return; }
valgrind \
--leak-check=full --error-limit=no --track-origins=yes \
--undef-value-errors=yes --log-file=valgrind-${NAME}.log \
--read-var-info=yes --trace-children=yes \
$COMMAND | tee valgrind-${NAME}-output.log 2>&1
}
function vgdbg
{
[[ -n "$*" ]] || { echo "Syntax: vgrun <command>"; return; }
valgrind \
--leak-check=full --error-limit=no --track-origins=yes \
--undef-value-errors=yes --read-var-info=yes --db-attach=yes \
"$@"
}
vgrun
просто запускает команду с Valgrind.Обратите внимание, что команда должна быть в кавычках со всеми ее параметрами, чтобы эта команда работала.vgtrace
- это просто вариант vgrun
, добавляющий --trace-children=yes
в командную строку Valgrind.На данный момент наиболее полезным является vgdbg
, который попросит вас присоединить GDB к работающей программе и, таким образом, позволит вам в интерактивном режиме отладить проблему, включая надлежащую проверку стековых фреймов, значений и т. Д. - , если вы говорите GDB, то есть.