URN Logo
UNIX Resources » Linux » China Linux Forum » Linux下的GUI软件开发 » 10 » 紧急求助:GtkTreeView运行时崩溃问题!
announcement 声明: 本页内容为中国Linux论坛的内容镜像,文章的版权以及其他所有的相关权利属于中国Linux论坛和相应文章的作者,如果转载,请注明文章来源及相关版权信息。
Resources
China Linux Forum(finished)
Linux Forum(finished)
FreeBSD China(finished)
linuxforum.net
  业界新闻与评论
  自由软件杂谈
  IT 人生
  Linux软件快递
  翻译作坊
  Linux图书与评论
  GNU Emacs/XEmacs
  Linux 中文环境和中文化
  Linux桌面与办公软件
  Linux 多媒体与娱乐版
  自由之窗Mozilla
  笔记本电脑上的Linux
  Gentoo
  Debian 一族
  网络管理技术
  Linux 安装与入门
  WEB服务器和FTP服务器
  域名服务器和邮件服务器
  Linux防火墙和代理服务器应用
  文件及打印服务器
  技术培训与认证
  TI专版
  Linux内核技术
  Linux 嵌入技术
  Linux设备驱动程序
  Linux 集群技术
  LINUX平台数据库
  系统和网络安全
  CPU 与 编译器
  系统计算研究所专栏
  Linux下的GUI软件开发
  C/C++编程版
  PHP 技 术
  Java&jsp技术
  Shell编程技术
  Perl 编 程
  Python 编 程
  XML/Web Service 技术
  永远的Unix
  FreeBSD世界
   
紧急求助:GtkTreeView运行时崩溃问题!
 
 
 
 
 
 
 
 
 
 
 
Subject: 紧急求助:GtkTreeView运行时崩溃问题!
Author: gloryofxinyi    Posted: 2006-08-18 15:43    Length: 2,991 byte(s)
[Original] [Print] [Top]
大家好,有一个运行时崩溃的问题一直没有办法解决。

问题是这样的:
我创建了一个GtkTreeView,用来滚动显示网络流量数据的协议分析结果,大致代码是这样的:
GtkWidget *tree_view;
GtkTreeModel *tree_model;
GtkListStore *list_store;
...
list_store = gtk_list_store_new (...);
tree_model = GTK_TREE_MODEL (list_store);
tree_view = gtk_tree_view_new_with_model (tree_model);
gtk_widget_show (tree_view);
接下来就是给TreeView加一些Columns,并设置相关属性了。

在一个函数中,每分析一个数据包,用gtk_list_store_append ()增加一条记录,用gtk_list_store_set ()设置协议分析结果,然后显示出来。
但在运行一段时间后,程序总会崩溃,出现Segmentation fault的错误!

并且多次运行,每次提示的错误可能还不一样,有时出现下面的提示:
Gtk-CRITICAL ** : file gtktreeview.c : line 4225 (do_validate_rows) : assertion 'gtk_tree_model_iter_next (tree_view->priv->model, &iter)' failed.
There is a disparity between the internal view of the GtkTreeView, and the GtkTreeModel. This generally means that the model has changed without letting the view know. Any display from now on is likely to be incorrect.

Gtk-ERROR ** : file gtkliststore.c : line 516 (gtk_list_store_get_iter) : assertion failed : (list)
aborting...
大致意思是说TreeModel运行时发生了变化,而TreeView却未被告知,断言错误。有时直接就Segmentation fault后直接退出了,没有任何提示。

目前就这个问题,我做了以下尝试:
注:“显示日志消息函数”以下简称“日函”
  “显示协议分析结果函数”以下简称“协函”
呵呵! 

(1) 首先,我的“日函”与“协函”结构完全相同,而“日函”工作很正常,当然日志消息毕竟很少,不像“协函”要显示大量的数据。但尝试用“日函”代替“协函”时(把“协函”的代码全部注释掉,仅调用“日函”),也出现了程序崩溃的现象。
分析:这个现象让人感觉是不是数据量过大而导致崩溃,我在实验室的正常流量一般是每秒600~800个数据包(网卡混杂模式)。 为验证这一点,我在程序中加入了显示数量的限制,每秒至多显示100条记录。结果,程序运行能坚持长一点儿的时间,但最终还是崩溃。

(2) 考虑到程序中用到了多线程,我怀疑是线程并发的原因,于是我写了一个单线程的程序,只滚动显示数据,不做其它任何事情。试验结果表明:随着ListStore的不断增大,Linux交换内存不断上升,且由于刷新显示的数据较多(每秒产生1000以内的随机数),CPU占用很多。
但有一点很可喜,那就是尽管机器速度变慢,但程序并没有崩溃!!!
分析:问题似乎已经找到了,多线程并发导致的崩溃。

(3) 昨天晚上,我又满怀希望地在“协函”中加入了互斥锁,想设定一个临界区来保护增加记录的代码:
gtk_list_store_append (...);
gtk_list_store_set (...);
但最终,程序还是崩溃了。

真的不知道该怎么解决了,很郁闷!今天在看GtkList,准备不用TreeView了,但了解到GtkList已经被Deprecated了,呵呵!

感谢您能阅读到这里,谢谢!
----
把握现在 成就未来
动力无限 杭州天堂
[Original] [Print] [Top]
Subject: Re: 紧急求助:GtkTreeView运行时崩溃问题!
Author: passworld    Posted: 2006-08-18 18:58    Length: 42 byte(s)
[Original] [Print] [Top]
你只加不删,会不会把记忆占满了?
----
[Original] [Print] [Top]
Subject: Re: 紧急求助:GtkTreeView运行时崩溃问题!
Author: gloryofxinyi    Posted: 2006-08-18 20:13    Length: 164 byte(s)
[Original] [Print] [Top]
嗯,这的确是个问题,因为我观察到交换内存随着程序的运行在不断地增长。

但是,我在单线程试验的时候,也并没有删除记录啊,不断地添加,程序没有崩溃的。
----
把握现在 成就未来
动力无限 杭州天堂
[Original] [Print] [Top]
Subject: Re: 紧急求助:GtkTreeView运行时崩溃问题!
Author: gloryofxinyi    Posted: 2006-08-18 20:33    Length: 95 byte(s)
[Original] [Print] [Top]
刚刚增加了gtk_list_store_clear ()来删除记录,程序还是崩溃,而且还更快,呵呵

----
把握现在 成就未来
动力无限 杭州天堂
[Original] [Print] [Top]
Subject: Re: 紧急求助:GtkTreeView运行时崩溃问题!
Author: passworld    Posted: 2006-08-18 23:15    Length: 366 byte(s)
[Original] [Print] [Top]
看前面你问的问题,你似乎没有处理 gdk_thread 的情况就直接做多线程的 gtk 操作,那是一定会出问题的。在多线程的 gtk 操作,每次操作前都要上锁。具体用法参看 gdk 手册的 thread 部分。

最好不要在多线程里调用 gtk 函数,最好所有绘图部分用单一线程处理,其他线程排队。Windows 下多线程操作绘图是一定要出问题的。




----
[Original] [Print] [Top]
Subject: Re: 紧急求助:GtkTreeView运行时崩溃问题!
Author: gogoliu    Posted: 2006-08-19 11:55    Length: 66 byte(s)
[Original] [Print] [Top]
我以前也做过这样的软件,但那时我是用io_channel来完成数据包接收的。
----
killall 眼高手低 用心浮躁 浅尝辄止
[Original] [Print] [Top]
Subject: Re: 紧急求助:GtkTreeView运行时崩溃问题!
Author: gloryofxinyi    Posted: 2006-08-19 13:06    Length: 1,393 byte(s)
[Original] [Print] [Top]
嗯,passworld提出的“不要在多线程里调用gtk函数”倒是提醒了我,估计问题锁定在多线程并发上了。

昨晚的再次试验让我确信不是ListStore可能的溢出(反复添加记录引起的)而导致的程序崩溃。因为我创建了一个循环链表,表结点数据结构如下:
struct _ProtocolAnalysisShowingList
{
GtkTreeIter *tree_iter;
struct _ProtocolAnalysisShowingList *next;
};
typedef struct _ProtocolAnalysisShowingList PASL;
初始化一个长度为128的链(当然可以任意设定),当gtk_list_store_append ()添加一条记录时,我就把这个记录指针(GtkTreeIter * 类型)保存到循环链尾部;同时从链头部获取一个记录指针(指针可能为空),如果指针不为空的话,就调用gtk_list_store_move ()删除它。这样的话,ListStore中顶多只有128条记录。同时,我限定了每一秒钟也只显示128个协议分析结果。
然而,程序还是崩了,但是,程序运行的时间长了一点儿,似乎健壮了许多,呵呵!

passworld的提醒,让我想到:设计中,协议分析是由一个独立的线程来完成的,而的确是在这个线程中,调用了显示结果的函数,并间接调用了Gtk函数!!!

看来问题差不多找到了,今晚的试验,我准备创建一个共享的协议分析结果链,分析线程向共享链中添加数据,而显示部分与之分离,由主线程来完成。当然,对共享链要有一个写、读互斥的处理,还有就是链的防溢出(链太长时)措施了。

希望下一个贴子,就是结贴了,呵呵,感谢所有阅读与提出宝贵意见的朋友,谢谢你们!
----
把握现在 成就未来
动力无限 杭州天堂
[Original] [Print] [Top]
Subject: Re: 紧急求助:GtkTreeView运行时崩溃问题!
Author: gloryofxinyi    Posted: 2006-08-21 09:00    Length: 1,705 byte(s)
[Original] [Print] [Top]
崩溃问题已经解决,发贴庆祝一下,呵呵!

解决过程如下:
(1) Gtk绘图方法在多线程环境下发生的错误
由于在协议分析线程中加入了Gtk的图形显示,结果导致了运行时的一大堆错误,而且每次出现的错误还不一样,有各种各样的提示。解决办法是把Gtk绘图从多线程中分离出来,在主线程中调用它,定义一个共享的链,协议分析与协议显示按照“生产者-消费者”的方式互斥访问它。

解决上述问题后,满以为OK了,结果还是崩了,呵呵。但多次反复试验,发现不再提示Gtk相关的错误了,只出现Segmentation fault的错误。说明上面的解决方法是完全正确的!

(2) 多线程中某些函数调用产生的错误
这个错误的发现,真是个偶然,同实验室一同学在观看我的测试时,提出为什么显示要用不同的颜色来区分,我说这对应了不同的协议类型,为了说明这一点,我在另一台机器上ping一下,反复ping就会不断产生ICMP报文,正常情况下多数是TCP的,结果问题出现了:只要我一ping的话,程序马上就崩了,不ping的话,程序运行一段时间后,也可能就崩了,现在猜测估计是产生了ICMP了。这个明显的现象说明ICMP相关的代码有问题。这段代码中主要用到了strcmp函数,可能是在做字符串比较时出现的Segmentation fault了,呵呵,重新改写了这段代码,做了优化,程序不再崩溃了。

经过长时间的反复试验,程序没有再出现崩溃的现象!估计问题完全解决了,但仍在观察中。

总结:
(1) 避免在多线程中调用Gtk绘图函数
(2) 程序问题可能是多个bug综合产生的结果

目前程序还有一点不足,那就是协议显示时,速度会越来越慢,我通过限制每次显示的个数和采用循环链表保存ListStore的TreeIters也没有凑效。显示时CPU已经达到100%,有时界面都响应不过来了,但是,仍然没有崩溃,非常robust,呵呵!

顺便想提一个问题:除了看源代码来猜测程序中耗CPU的部分外,还有其它什么好的测试方法吗?谢谢!
----
把握现在 成就未来
动力无限 杭州天堂
[Original] [Print] [Top]
Subject: Re: 紧急求助:GtkTreeView运行时崩溃问题!
Author: passworld    Posted: 2006-08-21 09:27    Length: 184 byte(s)
[Original] [Print] [Top]
测试速度用 profile ,gprof 是传统的,oprofile,sysprof 是比较新的,valgrind 好象也有一定的功能,比如 callgrind , helgrind 可以对 race condition 进行分析。


----
[Original] [Print] [Top]
Subject: Re: 紧急求助:GtkTreeView运行时崩溃问题!
Author: passworld    Posted: 2006-08-21 09:40    Length: 123 byte(s)
[Original] [Print] [Top]
CPU 100% 的话,也可以用 strace, ltrace attach 到pid上,看看它正在什么地方拼命打转。



----
[Original] [Print] [Top]
Subject: Re: 紧急求助:GtkTreeView运行时崩溃问题!
Author: gloryofxinyi    Posted: 2006-08-21 12:42    Length: 220 byte(s)
[Original] [Print] [Top]
好的,strace是一个什么工具吗?我从未用过的,呵呵,Google一下先

我从代码的角度来猜测,昨天加了监视协议结果链的功能,但输出的值几乎总是0,说明显示部分处理的速度还是跟得上来的,就不晓得啥原因造成CPU100%了
----
把握现在 成就未来
动力无限 杭州天堂
[Original] [Print] [Top]
« Previous thread
GTK on DirectFB 怎么不行啊!
Linux下的GUI软件开发
10
Next thread »
求助:GLib中g_thread的使用
     

Copyright © 2007~2009 UNIX Resources Network, All Rights Reserved.      About URN | Privacy & Legal | Help | Contact us
webmaster: webmaster@unixresources.net
This page created on 2009-09-07 16:42:27, cost 0.0215358734131 ms.