2012-09-27 36 views
6

終止我有一個C-PROGRAMM(很多數字組成太長後),我編譯計劃年初的valgrind MEMCHECK

gcc -g -O0 program.c -o program 

我試圖用gdb和Valgrind的MEMCHECK調試它。在代碼中的一些變化後,我發現,

valgrind --tool=memcheck --log-file=output.log ./program 

==15866== Memcheck, a memory error detector 
==15866== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al. 
==15866== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info 
==15866== Command: ./program 
==15866== Parent PID: 3362 
==15866== 
==15866== Warning: client switching stacks? SP change: 0xbe88bcd8 --> 0xbe4e1f70 
==15866==   to suppress, use: --max-stackframe=3841384 or greater 
==15866== Invalid write of size 4 
==15866== at 0x804B7BE: main (program.c:1396) 
==15866== Address 0xbe4e1f74 is on thread 1's stack 
==15866== 
==15866== Invalid write of size 4 
==15866== at 0x804B7C2: main (program.c:1396) 
==15866== Address 0xbe4e1f70 is on thread 1's stack 
==15866== 
==15866== Invalid read of size 4 
==15866== at 0x4320011: on_exit (on_exit.c:34) 
==15866== by 0x43064D2: (below main) (libc-start.c:226) 
==15866== Address 0xbe4e1f70 is on thread 1's stack 
==15866== 
==15866== Invalid read of size 4 
==15866== at 0x4320022: on_exit (on_exit.c:37) 
==15866== by 0x43064D2: (below main) (libc-start.c:226) 
==15866== Address 0xbe4e1f74 is on thread 1's stack 

,還有更多這樣的。

valgrind --tool=memcheck --max-stackframe=3841384 --log-file=output.log ./program 

不顯示任何錯誤。但令我感到困惑的是,兩個valgrind調用程序都會提前退出(沒有錯誤消息),並且不執行它應該執行的計算。具有相同編譯器選項但運行時沒有使用valgrind的行爲完全不同,看起來很正常。我懷疑有內存錯誤,但想用valgrind找到它。因此我的問題是:什麼樣的錯誤可以使程序在使用valgrind執行時變得如此不同?如果這些是與內存有關的錯誤,我該如何識別它?請注意,我很清楚我可以「手動調試」來找到它。但我可以用valgrind運行gdb來查看它退出的位置。

+1

你可能會導致堆棧溢出。你在堆棧上分配「大」數組嗎?例如。 'double myArray [10000000];'如果是這樣,那麼你應該用'malloc'和'free'來替換堆內存的分配。 –

+1

_什麼樣的錯誤可以使程序在使用valgrind執行時變得如此不同?_未定義的行爲。 – Shahbaz

+0

你嘗試過'--leak-check = full'嗎? – Shahbaz

回答

3

我最初回答的評論:

你可能會導致堆棧溢出。您是否在堆棧上分配「大」 陣列?例如。 double myArray[10000000];如果是這樣,那麼你應該用mallocfree替換這種分配與堆內存。

我寫了一個C短節目故意導致堆棧溢出這樣和檢查什麼的valgrind報告:

#include <stdio.h> 

int main(){ 

    // imax*sizeof(double) is too big for the stack. 
    int imax = 10000000; 
    double test[imax]; 

    // I do a little math to prevent the stack overflow from being optimized away if -O3 is used. 
    test[0]=0; 
    test[1]=1; 
    for(int i=2; i<imax; i++) 
    test[i]=0.5*(test[i-1]+test[i-2]); 
    printf("%e\n", test[imax-1]); 

} 

果然,Valgrind的想出了:

==83869== Warning: client switching stacks? SP change: 0x104802930 --> 0xffbb7520 
==83869==   to suppress, use: --max-stackframe=80000016 or greater 
==83869== Invalid write of size 8 
==83869== at 0x100000ED0: main (in ./a.out) 
==83869== Address 0xffbb7520 is on thread 1's stack 

沿與其他錯誤信息噸,並最終退出Segmentation fault: 11

+0

我沒有看到Segfault的事實可能與我的程序捕捉到某些信號有關。我會調查它。 – highsciguy

+0

@highsciguy同時給我一個貼出來的代碼,以確保您在這種簡單的情況下看到seg故障。 –