我正在尝试编写一个GTK应用程序,并想用valgrind测试它的有效性。
这是我要测试的示例程序:
valgrind --tool=memcheck --leak-check=full --num-callers=15 --log-file=vgdump ./diashow
GNOME基金会用valgrind编写了一个关于测试应用程序的an article,但即使我用所有这些标志启动valgrind
valgrind --tool=memcheck --leak-check=full --num-callers=15 --suppressions=gtk.suppression --log-file=vgdump ./diasho
或甚至使用valgrind-page
中提到的gtk.suppression filevgdump
valgrind dumpfile (pastebin) Invalid write of size 4
非常难以辨认。 2285行!
对我来说,最奇怪的部分是我的vgdump文件以Invalid read of size 4
开头,然后是$password = "tere";
$cryptPassword = password_hash($password, PASSWORD_DEFAULT);
$verify = password_verify($password, $cryptPassword);
var_dump($verify); // Returns bool(true)
。有人可以向我解释一下吗?
答案 0 :(得分:1)
根据我的经验,使用valgrind时的一个好规则是在开始时检查一些错误,尝试修复这些错误,然后再次在valgrind下重启应用程序。原因是:假设您在分配数组的函数中有错误,并使用数组调用另一个函数并且数组的大小为+ 1 (即大小超过实际大小的元素)。然后,当下一个函数尝试访问那个过多的元素时,valgrind可能会注意到它并触发警告。但是该函数可能会调用另一个函数,该函数也可能尝试访问该元素,这也会导致警告,等等。
因此,您最终得到一堆导致单个错误的消息。即使有关于另一个错误的消息,找到这些通常会很难,更容易修复第一个错误,并重新启动app和valgrind。
另外,你需要对valgrind错误提出一些怀疑。例如。我记得曾经向我报告过函数main中一个未初始化的变量 - 由于某些原因,valgrind实际上看不到它。它导致了一个消息,关于主要调用的每个函数中的未初始化变量用法 - 即我程序中的每个函数。但是我应该提到它很久以前 - 三年前 - 我可以假设valgrind不是最近的版本,因为Ubuntu存储库往往没有最新版本的许多应用程序。
Invalid read of size 4
表示缓冲区溢出。第一个这样的错误的堆栈跟踪应指向您可以找到问题的位置。很难说更多,因为你没有显示堆栈跟踪,但你必须知道带错误的函数可能是上面错误数组的受害者。
另外,我建议你调试那种错误with AddressSanitizer,默认情况下可用于GCC和Clang (并且它们具有相同的选项来启用它)。它倾向于给出一个关于错误的更多更详细的输出(yay,它甚至是多彩的!ε:),并且默认情况下在任何类型的内存错误时关闭应用程序发生了。更重要的是,当AddressSanitizer没有时,valgrind错过了大部分内存错误 - 例如堆栈溢出等等。是的,有时(如你的情况)它的工作原理,但从我的经验来看并不是很好常。