2012-03-23 105 views
4

我在linux上編寫了一個C程序來處理大量的數據,大部分時間運行正常。但是,當處理一組特定的數據時,它總是告訴我'分段錯誤'錯誤,我試圖使用gdb而沒有運氣(請參閱我的另一個問題How to deal segmentation fault with GDB under particular circumstance?),所以我嘗試使用valgrind。它沒有告訴我用valgrind運行時的'分段錯誤'錯誤。那麼如何根據這些valgrind輸出來找到bug呢?有人可以幫助我分析這些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) 

回答

11

這是很多你在這裏輸出的。你應該把它濃縮到你感興趣的領域。不過,我會盡量給出一些通用的指針。

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

受影響的內存塊。第一行告訴我們,分配了一個正好一個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 \ 
     "[email protected]" 
} 

vgrun只需運行具有Valgrind的命令。請注意,該命令需要使用所有參數引號才能使用。 vgtrace只是vgrun的一個變體,將--trace-children=yes添加到Valgrind命令行。到目前爲止,最有用的是vgdbg,它會要求你將GDB附加到正在運行的程序中,從而可以交互式地調試手頭的問題,包括正確檢查堆棧幀,值等 - 如果你說GDB,那就是。

+0

和+1後面的時間來深入瞭解數據。我真的想要一般的方法,因爲那裏有很多信息,而且我在很長一段時間內沒有使用過valgrind。隨着時間的推移調試segfaults,我發現未初始化的變量往往會導致這個方向,當然,覆蓋緩衝區可以做各種有趣的事情。 – pstrjds 2012-03-23 04:39:41

2

我會先看看有關未初始化值的錯誤。我也會看看無效的寫入。 Segfaults通常可能是使用未初始化值的結果。它們也可能是由導致堆損壞的無效寫入引起的。那裏的輸出給你線路號碼。開始尋找這些地區。那裏的輸出也顯示出幾個內存泄漏。按照輸出的建議,再用--leak-check = full運行它,以獲得對內存泄漏的更詳細的分析,以便您可以跟蹤這些內容並照顧它們。

+0

那麼,不需要任何這樣的錯誤(未初始化),以獲得OP的輸出。那些低於實際錯誤的人往往首先是錯誤的後果。雖然承認它也是相反的。仍然爲大方向+1。 – 0xC0000022L 2012-03-23 03:10:32

+0

謝謝你的回答,我會仔細檢查 – 2012-03-23 03:14:27

相關問題