2010-11-11 39 views
5

我剛開始學習使用的valgrind和--tool = MEMCHECK如何使用Valgrind的有效

但我有實際查找問題什麼麻煩。

例如

一個這樣的問題是這樣的。

==12561== Conditional jump or move depends on uninitialised value(s) 
==12561== at 0x425779: Server::HandleReceiveFrom(boost::system::error_code const&, unsigned long) (mUUID.h:63) 
==12561== by 0x428EC4: boost::asio::detail::reactive_socket_recvfrom_op<boost::asio::mutable_buffers_1, boost::asio::ip::basic_endpoint<boost::asio::ip::udp>, boost::_bi::bind_t<void, boost::_mfi::mf2<void, Server, boost::system::error_code const&, unsigned long>, boost::_bi::list3<boost::_bi::value<Server*>, boost::arg<1> (*)(), boost::arg<2> (*)()> > >::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code, unsigned long) (mem_fn_template.hpp:280) 
==12561== by 0x42E589: boost::asio::detail::task_io_service::run(boost::system::error_code&) (task_io_service_operation.hpp:35) 
==12561== by 0x42720C: Server::Run() (io_service.ipp:57) 
==12561== by 0x42FB00: main (obbs.cpp:198) 

,另一個是這個

== Use of uninitialised value of size 8 
==12561== at 0x5E56091: _itoa_word (_itoa.c:196) 
==12561== by 0x5E573D8: vfprintf (vfprintf.c:1613) 
==12561== by 0x5F0EA6F: __vsnprintf_chk (vsnprintf_chk.c:65) 

如何最有效地追查這些類型的問題的一些提示後我。 (條件轉移和未初始化值)。

編輯

這是什麼可擔心的?似乎消失與選項--run-libc-freeres=no。 這是否意味着我有一個越野車C庫?

==14754== Invalid free()/delete/delete[] 
==14754== at 0x4C27D71: free (vg_replace_malloc.c:366) 
==14754== by 0x5F43A0A: free_mem (in /lib/libc-2.12.1.so) 
==14754== by 0x5F435A1: __libc_freeres (in /lib/libc-2.12.1.so) 
==14754== by 0x4A2366B: _vgnU_freeres (vg_preloaded.c:62) 
==14754== by 0x5E4A4A4: exit (exit.c:93) 
==14754== by 0x5E2FD94: (below main) (libc-start.c:258) 
==14754== Address 0x4046bb8 is not stack'd, malloc'd or (recently) free'd 
+0

+1一個非常重要的工具,可以使用 – 2010-11-12 08:41:42

+0

未初始化的值在Valgrind的快速入門http://valgrind.org/docs/manual /QuickStart.html(總共約12段,少於未初始化的值) – isomorphismes 2013-08-26 09:09:07

回答

15

基本上,每個Valgrind錯誤都會顯示堆棧跟蹤。堆棧跟蹤的較高部分對您來說可能不是很有用,因爲它們引用了庫代碼。但是,最終這些問題源於代碼中的問題。首先掃描堆棧跟蹤的第一部分,該部分引用應用程序中的一行代碼(與庫函數相反)。如果檢查堆棧跟蹤,則會看到obbs.cpp的第198行是您的應用程序導致您的第一個問題。再往上看,您可以看到mUUID.h的第63行最終是未初始化變量的評估位置,通過if語句或循環來進行評估。

錯誤「Conditional jump or move depends on uninitialised value(s)」表示您有一個未初始化的變量用於影響程序流。就你而言,它看起來像是將未初始化的變量傳遞給Boost庫函數,並且庫函數正在調用處理程序類,它在條件語句中計算未初始化的變量。這意味着你的程序顯示未定義的行爲。

一個簡單的例子,將導致此問題會是這樣的:

int i; // uninitialized value 
if (i == 10) { /* ... do something */ } 

開始通過檢查obbs.cpp線198,直到你意識到這個問題向上移動堆棧跟蹤。

我還會補充說,如果編譯時出現所有警告,編譯器有時會發現類似這樣的錯誤。 (例如,在GCC中,確保使用-Wall標誌進行編譯)

+1

感謝您的提示。 valgrind有時會錯誤嗎?沒有未初始化的變量,我可以看到。關於後期初始化呢? – Matt 2010-11-12 00:02:49

+3

Valgrind幾乎從不報告誤報。 – 2010-11-12 00:12:52

+0

嘗試查看堆棧跟蹤的更深層次,例如在調用回調處理程序的'mUUID.h'的第63行。您的處理程序類的所有成員變量是否已初始化? – 2010-11-12 00:28:21