【问题标题】:Can someone help me to analyze these valgrind output?有人可以帮我分析这些 valgrind 输出吗?
【发布时间】:2012-03-23 11:30:22
【问题描述】:

我在 linux 上写了一个 C 程序来处理大量数据,它大部分时间都运行良好。但是在处理一组特定数据时,它总是告诉我“分段错误”错误,我尝试使用 gdb 没有运气(请参阅我的另一个问题 How to deal segmentation fault with GDB under particular circumstance?),所以我尝试使用 valgrind。使用 valgrind 运行时,它没有告诉我“分段错误”错误。那么如何根据这些valgrind的输出找到bug呢?

==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)

【问题讨论】:

    标签: c linux debugging valgrind


    【解决方案1】:

    这里有很多输出。你应该把它更多地浓缩到你感兴趣的领域。不过,我会尝试给出一些一般性的指示。

    ==2441== Invalid write of size 4
    

    打开一个“块”,告诉您有关已分配内存及其分配的堆栈回溯和错误站点的详细信息。 ==2441== 是进程的 PID,这在多个进程并行运行的情况下很有用。

    错误站点(使用# 添加的cmets)。堆栈回溯总是以相反的顺序排列,这意味着崩溃(或通常会成为崩溃的)站点位于列表的顶部,并且导致该位置的调用在下面以相反的顺序列出:

    # 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)
    

    受影响的内存块。第一行告诉我们分配了正好一个 MiB 的块,并且(连同上面的输出)您正在读取该块的最后一个分配字节之后的前 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 manual(我知道这听起来很傲慢,但这是值得的)并利用它的许多选项。我创建了一些在我的开发机器上使用的函数:

    # 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 附加到正在运行的程序,从而让您以交互方式调试手头的问题,包括正确检查堆栈帧、值等 - if 你说的是 GDB。

    【讨论】:

    • 并为您花时间深入挖掘数据而 +1。因为那里有很多信息而且我很长时间没有使用 valgrind,所以我真的要采用一般方法。随着时间的推移调试段错误,我发现未初始化的变量往往会朝那个方向发展,当然覆盖缓冲区可以做各种有趣的事情。
    【解决方案2】:

    我会先看看关于未初始化值的错误。我还会查看无效写入。段错误通常是使用未初始化值的结果。它们也可能是由导致堆损坏的无效写入引起的。那里的输出为您提供行号。开始寻找那些领域。那里的输出还显示了几个内存泄漏。遵循输出建议并使用 --leak-check=full 再次运行它,以获得对内存泄漏的更详细分析,以便您可以追踪并处理它们。

    【讨论】:

    • 好吧,为了获得 OP 的输出,不需要任何此类错误(未初始化)。而那些低于实际误差的往往往往是最初的误差的结果。虽然不可否认,它也会反过来发生。大方向仍然 +1。
    • 感谢您的回答,我会仔细检查
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多