[英]Suppressing GTK errors in Valgrind
我正在尝试编写一个 GTK 应用程序并想用 valgrind 测试它的有效性。
这是我要测试的示例程序:
#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>
int
main (int argc, char *argv[])
{
GtkWidget *win;
GtkWidget *btn;
gtk_init (&argc, &argv);
win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
btn = gtk_button_new_with_label ("Hello");
gtk_container_add (GTK_CONTAINER (win), btn);
gtk_widget_show_all (win);
gtk_main();
}
GNOME 基金会写了一篇关于使用 valgrind 测试应用程序的文章,但即使我使用所有这些标志启动 valgrind
valgrind --tool=memcheck --leak-check=full --num-callers=15 --log-file=vgdump ./diashow
甚至使用该 valgrind-page 上提到的gtk.suppression 文件
valgrind --tool=memcheck --leak-check=full --num-callers=15 --suppressions=gtk.suppression --log-file=vgdump ./diasho
valgrind 转储文件(pastebin) vgdump
非常不可读。 2285行!
对我来说最奇怪的部分是我的 vgdump 文件以Invalid write of size 4
开始,然后Invalid read of size 4
。 有人可以向我解释一下吗?
根据我的经验,使用 valgrind 时的一个好规则是在开始时检查一些错误,尝试修复这些错误,然后再次在 valgrind 下重新启动应用程序。 原因是:假设您在分配数组的函数中出错,并使用数组和数组的大小+1 (即实际大小的一个元素的大小)调用另一个函数。 然后当下一个函数尝试访问那个过多的元素时,valgrind 可能会注意到它并触发警告。 但是该函数可能会调用另一个函数,该函数也可能尝试访问该元素,这也会导致警告,依此类推。
所以你最终会得到一堆导致一个错误的消息。 即使有关于另一个错误的消息,发现这些消息通常会很困难,因此更容易修复第一个错误,然后再次重新启动应用程序和 valgrind。
您还需要对 valgrind 错误持怀疑态度。 例如,我记得它曾经向我报告过一个函数 main 中的一个未初始化的变量——出于某种原因,valgrind 无法看到它实际上是。 它导致了一条关于在 main 调用的每个函数中使用未初始化变量的消息——即我程序中的每个函数。 但我应该提一下,那是很久以前——三年前——我可以假设 valgrind 甚至在那时也不是最新版本,因为 Ubuntu 存储库往往没有许多应用程序的最新版本。
Invalid read of size 4
的Invalid read of size 4
意味着某处缓冲区溢出。 第一个此类错误的堆栈跟踪应指向您可以找到问题的位置。 很难说更多,因为您没有显示堆栈跟踪,但是您必须知道出现错误的函数可能是上面错误数组的受害者。
顺便说一句,我建议您使用 AddressSanitizer调试这种错误,默认情况下它可用于 GCC 和 Clang (并且它们具有相同的选项来启用它) 。 它往往给详细的输出更加了解错误(耶,它甚至丰富多彩!ε:),并默认关闭应用程序的任何类型的内存不足的错误时有发生。 更重要的是,当 AddressSanitizer 没有时,valgrind 会错过大部分内存错误 - 例如堆栈溢出等。是的,有时(如您的情况)它有效,但根据我的经验,这种情况并不常见。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.