簡體   English   中英

Valgrind for C program report報告令人難以置信的無效寫入

[英]Valgrind for C program reporting unbelievable invalid write

任何人都有Valgrind錯誤報告無效寫入的問題? 我有一個帶有這個循環的C程序:

void myfunc4(int *myData, ...) 
{
 int *variable1, *variable2, ii, ss, bb, jj;
 ...
 bb = 0;
 for (ii=0; ii<ss; ii++) {  
   for (jj=0; jj<(variable2[ii]-variable1[ii]+1); jj++) {
       myData[bb] = variable1[ii] + jj; /* valgrind reports error is on this line */
       bb = bb+1;
   }
   printf("ss = %d, ii = %d, bb = %d \n", ss, ii, bb);
 }
}

我用Valgrind跑,

valgrind --log-file=./logfile --leak-check=full ./myProgram

它列出的第一個也是唯一的“無效”錯誤是:

==6135== Invalid write of size 4
==6135==    at 0x4090AA: myfunc4 (myfunc4.c:170)
==6135==    by 0x408527: myfunc3 (myfunc3.c:168)
==6135==    by 0x406CA1: myfunc2 (myfunc2.c:84)
==6135==    by 0x410163: myfunc1 (myfunc1.c:133)
==6135==    by 0x413726: main (myProgram.c:511)
==6135==  Address 0x1077c250 is 209,712 bytes inside a block of size 209,715 alloc'd
==6135==    at 0x4A05FDE: malloc (vg_replace_malloc.c:236)
==6135==    by 0x408248: myfunc3 (myfunc3.c:119)
==6135==    by 0x406CA1: myfunc2 (myfunc2.c:84)
==6135==    by 0x410163: myfunc1 (myfunc1.c:133)
==6135==    by 0x413726: main (myProgram.c:511)
==6135== 
==6135== More than 10000000 total errors detected.  I'm not reporting any more.
==6135== Final error counts will be inaccurate.  Go fix your program!

Valgrind聲明錯誤發生在代碼行中:

myData[bb] = variable1[ii] + jj;

如果我使用gdb在那一步完成程序,它運行正常。 循環完成之前顯示的最后一個printf是:

ss = 687, ii = 686, bb = 2690

我似乎無法觀察到Valgrind以外的任何問題。 Valgrind一直給出這個錯誤,但gdb始終沒有問題。

正如Valgrind正確報告的那樣,為myData分配的內存是209712字節,這是209712/4 = 52428整數的空間(我使用的是Linux 64位機器)。 printf語句中,我可以看到for循環以bb = 2690退出。 所以用於數組myData[bb]的最大索引(Valgrind抱怨)是myData[2689]

任何人都可以在我可以看到的地方找到一些亮點? 我一整天都在盯着這個。 我沒有多多使用Valgrind,我不想把它稱為lier,但我在這里做錯了嗎? 任何建議都非常感謝。

更新1

要將呼叫myfunc4()myfunc3()是:

int *myData, lengthA; 
...
myData = malloc( sizeof(int) * lengthA / 10); 
myfunc4(myData);

更新2

如果我修改循環以包含if (bb>10000)語句,gdb永遠不會測試true,但是Valgrind會這樣做。 編譯后的程序是一樣的。 任何人都有任何洞察力發生了什么?

void myfunc4(int *myData, ...) 
{
 int *variable1, *variable2, ii, ss, bb, jj;
 ...
 bb = 0;
 for (ii=0; ii<ss; ii++) {  
   for (jj=0; jj<(variable2[ii]-variable1[ii]+1); jj++) {
       myData[bb] = variable1[ii] + jj; 
       bb = bb+1;
       if (bb>10000) {
          printf("bb=%d \n", bb); /* valgrind executes this line but gdb does not */
          exit(1);
       }
   }
   printf("ss = %d, ii = %d, bb = %d \n", ss, ii, bb);
 }
}

我終於找到了這個bug。 當然,Malloc沒有初始化為零,我有一個if語句(上面沒有顯示)設置了一些數組值,但是沒有else語句來捕獲另一個路徑來設置相同的數組值,所以其他路徑使用了導致不良行為的單一化值。

在這個調試工作中,與Valgrind相比,gdb在將數組​​初始化為零(通過malloc)方面做得更好。 不應該依賴於那個,但這似乎是至少在gdb和Valgrind獲得的結果之間的差異。

獲取為數據分配的實際字節數並將其傳遞給函數:

size_t szData = sizeof(int) * lengthA / 10; 
myData = malloc(szData);
myfunc4(myData, szData);

並檢查訪問以驗證valgrind:

/* .... */
assert((bb +1) * sizeof(int) < szData);
myData[bb] = variable1[ii] + jj;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM