Может ли кто-нибудь помочь мне проанализировать эти результаты valgrind? - PullRequest
4 голосов
/ 23 марта 2012

Я написал программу на C для Linux, которая обрабатывает большой объем данных, большую часть времени она работает нормально.Но при обработке набора конкретных данных всегда сообщалось об ошибке «Ошибка сегментации», я безуспешно пытался использовать GDB (см. Другой мой вопрос Как устранить ошибку сегментации с GDB при определенных обстоятельствах? )поэтому я попытался использовать valgrind.Это не сообщало мне об ошибке «ошибка сегментации» при запуске с valgrind.Итак, как найти ошибку в соответствии с этими выводами valgrind?

==2441== Invalid write of size 4
==2441==    at 0x404893: nodes_term32_flush (tyn_indexer.c:227)
==2441==    by 0x407B77: tyn_exsorter_sort (tyn_exsorter.c:131)
==2441==    by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==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==
==2441== Invalid write of size 4
==2441==    at 0x4048D8: nodes_term32_flush (tyn_indexer.c:254)
==2441==    by 0x407B77: tyn_exsorter_sort (tyn_exsorter.c:131)
==2441==    by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==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==
==2441== Invalid read of size 4
==2441==    at 0x40450D: nodes_term32_flush (tyn_indexer.c:260)
==2441==    by 0x407B77: tyn_exsorter_sort (tyn_exsorter.c:131)
==2441==    by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==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==
==2441== Invalid read of size 4
==2441==    at 0x404878: nodes_term32_flush (tyn_indexer.c:224)
==2441==    by 0x407B77: tyn_exsorter_sort (tyn_exsorter.c:131)
==2441==    by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==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==
==2441== Invalid write of size 4
==2441==    at 0x40487F: nodes_term32_flush (tyn_indexer.c:224)
==2441==    by 0x407B77: tyn_exsorter_sort (tyn_exsorter.c:131)
==2441==    by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==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==
==2441== Invalid read of size 4
==2441==    at 0x4048BD: nodes_term32_flush (tyn_indexer.c:251)
==2441==    by 0x407B77: tyn_exsorter_sort (tyn_exsorter.c:131)
==2441==    by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==2441==  Address 0x1233c094 is not stack'd, malloc'd or (recently) free'd
==2441==
==2441== Invalid write of size 4
==2441==    at 0x4048C4: nodes_term32_flush (tyn_indexer.c:251)
==2441==    by 0x407B77: tyn_exsorter_sort (tyn_exsorter.c:131)
==2441==    by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==2441==  Address 0x1233c094 is not stack'd, malloc'd or (recently) free'd
==2441==
==2441== Invalid read of size 4
==2441==    at 0x4093A0: tyn_p4d_encode32 (tyn_coder.c:645)
==2441==    by 0x4045F0: nodes_term32_flush (tyn_indexer.c:132)
==2441==    by 0x407B77: tyn_exsorter_sort (tyn_exsorter.c:131)
==2441==    by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==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==
==2441== Invalid read of size 4
==2441==    at 0x409490: tyn_p4d_encode32 (tyn_coder.c:669)
==2441==    by 0x4045F0: nodes_term32_flush (tyn_indexer.c:132)
==2441==    by 0x407B77: tyn_exsorter_sort (tyn_exsorter.c:131)
==2441==    by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==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==
==2441== Invalid read of size 4
==2441==    at 0x4094A7: tyn_p4d_encode32 (tyn_coder.c:667)
==2441==    by 0x4045F0: nodes_term32_flush (tyn_indexer.c:132)
==2441==    by 0x407B77: tyn_exsorter_sort (tyn_exsorter.c:131)
==2441==    by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==2441==  Address 0x1233c088 is 8 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==
==2441== Invalid read of size 4
==2441==    at 0x409574: tyn_p4d_encode32 (tyn_coder.c:694)
==2441==    by 0x4045F0: nodes_term32_flush (tyn_indexer.c:132)
==2441==    by 0x407B77: tyn_exsorter_sort (tyn_exsorter.c:131)
==2441==    by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==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==
==2441== Invalid read of size 4
==2441==    at 0x4095A6: tyn_p4d_encode32 (tyn_coder.c:708)
==2441==    by 0x4045F0: nodes_term32_flush (tyn_indexer.c:132)
==2441==    by 0x407B77: tyn_exsorter_sort (tyn_exsorter.c:131)
==2441==    by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==2441==  Address 0x1233c088 is 8 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==
==2441== Invalid read of size 4
==2441==    at 0x409524: tyn_p4d_encode32 (tyn_coder.c:697)
==2441==    by 0x4045F0: nodes_term32_flush (tyn_indexer.c:132)
==2441==    by 0x407B77: tyn_exsorter_sort (tyn_exsorter.c:131)
==2441==    by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==2441==  Address 0x1233c08c is 12 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==
==2441== Invalid read of size 4
==2441==    at 0x40953A: tyn_p4d_encode32 (tyn_coder.c:700)
==2441==    by 0x4045F0: nodes_term32_flush (tyn_indexer.c:132)
==2441==    by 0x407B77: tyn_exsorter_sort (tyn_exsorter.c:131)
==2441==    by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==2441==  Address 0x1233c08c is 12 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==
==2441== Invalid read of size 4
==2441==    at 0x409552: tyn_p4d_encode32 (tyn_coder.c:702)
==2441==    by 0x4045F0: nodes_term32_flush (tyn_indexer.c:132)
==2441==    by 0x407B77: tyn_exsorter_sort (tyn_exsorter.c:131)
==2441==    by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==2441==  Address 0x1243c2fc is 12 bytes after a block of size 16 alloc'd
==2441==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==2441==    by 0x40785B: tyn_exsorter_sort (tyn_exsorter.c:106)
==2441==    by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==2441==
==2441== Invalid read of size 4
==2441==    at 0x407CB7: tyn_iS16_encode32 (tyn_coder.c:96)
==2441==    by 0x409621: tyn_p4d_encode32 (tyn_coder.c:725)
==2441==    by 0x4045F0: nodes_term32_flush (tyn_indexer.c:132)
==2441==    by 0x407B77: tyn_exsorter_sort (tyn_exsorter.c:131)
==2441==    by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==2441==  Address 0x1243d880 is 0 bytes after a block of size 16 alloc'd
==2441==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==2441==    by 0x40785B: tyn_exsorter_sort (tyn_exsorter.c:106)
==2441==    by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==2441==
==2441== Invalid read of size 4
==2441==    at 0x407D20: tyn_iS16_encode32 (tyn_coder.c:109)
==2441==    by 0x409621: tyn_p4d_encode32 (tyn_coder.c:725)
==2441==    by 0x4045F0: nodes_term32_flush (tyn_indexer.c:132)
==2441==    by 0x407B77: tyn_exsorter_sort (tyn_exsorter.c:131)
==2441==    by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==2441==  Address 0x1243d880 is 0 bytes after a block of size 16 alloc'd
==2441==    at 0x4A074CD: malloc (vg_replace_malloc.c:236)
==2441==    by 0x40785B: tyn_exsorter_sort (tyn_exsorter.c:106)
==2441==    by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==2441==
==2441== Invalid read of size 4
==2441==    at 0x407D37: tyn_iS16_encode32 (tyn_coder.c:108)
==2441==    by 0x409621: tyn_p4d_encode32 (tyn_coder.c:725)
==2441==    by 0x4045F0: nodes_term32_flush (tyn_indexer.c:132)
==2441==    by 0x407B77: tyn_exsorter_sort (tyn_exsorter.c:131)
==2441==    by 0x406DDE: tyn_build_index (tyn_indexer.c:731)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==2441==  Address 0x1243d8a8 is not stack'd, malloc'd or (recently) free'd
==2441==

==2441== Use of uninitialised value of size 8
==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)
==2441==    by 0x4071EF: tyn_build_index (tyn_indexer.c:888)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==2441==
==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)
==2441==
document id: 0
==2441== Conditional jump or move depends on uninitialised value(s)
==2441==    at 0x3AE9C4774E: vfprintf (in /lib64/libc-2.14.90.so)
==2441==    by 0x3AE9C51FE8: printf (in /lib64/libc-2.14.90.so)
==2441==    by 0x4073AD: tyn_build_index (tyn_indexer.c:900)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==2441==
==2441== Use of uninitialised value of size 8
==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)
==2441==    by 0x4073AD: tyn_build_index (tyn_indexer.c:900)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==2441==
==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 0x4073AD: tyn_build_index (tyn_indexer.c:900)
==2441==    by 0x40384F: main (tyn_indexer.c:943)
==2441==
int32_t category: 0
bytes_collected: 972467429
196220 bytes/s
tyn_config->indexer->dl_directory: /dragon/tyan
tyn_config->indexer->memory_limit: 10240000
==2441==
==2441== HEAP SUMMARY:
==2441==     in use at exit: 214,695,668 bytes in 399,272 blocks
==2441==   total heap usage: 401,095 allocs, 1,823 frees, 219,225,806 bytes allocated
==2441==
==2441== LEAK SUMMARY:
==2441==    definitely lost: 9,442,580 bytes in 27 blocks
==2441==    indirectly lost: 34,682,771 bytes in 81 blocks
==2441==      possibly lost: 170,557,809 bytes in 399,140 blocks
==2441==    still reachable: 12,508 bytes in 24 blocks
==2441==         suppressed: 0 bytes in 0 blocks
==2441== Rerun with --leak-check=full to see details of leaked memory
==2441==
==2441== For counts of detected and suppressed errors, rerun with: -v
==2441== Use --track-origins=yes to see where uninitialised values come from
==2441== ERROR SUMMARY: 32680 errors from 23 contexts (suppressed: 2 from 2)

Ответы [ 2 ]

11 голосов
/ 23 марта 2012

Это большой выход, который вы получили здесь.Вы должны были сжать это больше в областях, которые вас интересуют.Однако я попытаюсь дать несколько общих указателей.

==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, то есть.

2 голосов
/ 23 марта 2012

Сначала я бы посмотрел на ошибки, говоря о неинициализированных значениях. Я бы тоже посмотрел на недействительные записи. Сегфоуты часто могут быть результатом использования неинициализированного значения. Они также могут быть вызваны неправильными записями, которые вызывают повреждение кучи. Выходные данные дают вам номера строк. Начните искать в этих областях. Вывод также показывает несколько утечек памяти. Следуйте рекомендациям по выводу и запустите его снова с параметром --leak-check = full, чтобы получить более подробный анализ утечек памяти, чтобы вы могли отследить их и позаботиться о них.

...