繁体   English   中英

抑制 Valgrind 中的 GTK 错误

[英]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 4Invalid read of size 4意味着某处缓冲区溢出。 第一个此类错误的堆栈跟踪应指向您可以找到问题的位置。 很难说更多,因为您没有显示堆栈跟踪,但是您必须知道出现错误的函数可能是上面错误数组的受害者。

顺便说一句,我建议您使用 AddressSanitizer调试这种错误默认情况下它可用于 GCC 和 Clang (并且它们具有相同的选项来启用它) 它往往给详细的输出更加了解错误(耶,它甚至丰富多彩!ε:),并默认关闭应用程序的任何类型的内存不足的错误时有发生。 更重要的是,当 AddressSanitizer 没有时,valgrind 会错过大部分内存错误 - 例如堆栈溢出等。是的,有时(如您的情况)它有效,但根据我的经验,这种情况并不常见。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM