星期一, 四月 30, 2007

sparse linux checker

Linus同志写的工具,还是值得一看的(尽管目前已经转给他人维护了)

主要用来检查一些Kernel 代码里的bug,Linus自己写了上下文相关的C前端(代码文件到语法),
这个叫做Sparse,是一个lib,可以供各种客户端(后端)来使用,比如检查器,编译器等。
(这个前端不是用lex.yacc.flex.bison.antlr等工具实现的)

Linus也写了一个客户端也叫Sparse,来做他想要的检查,然后写了一个perl脚本cgcc用来集成Sparse
和gcc,这样就可以在编译时刻自动检查,就这些了。

星期六, 四月 28, 2007

Dawson Engler

斯坦福大学(副)教授,主要研究软件bug的自动发现,比如静态分析等。
主页在这里: http://www.stanford.edu/~engler/
里面有很多他的文章可以下载,我心怀景仰的下载了几篇,基本看不懂。 :(

他使用自创的工具在Linux Kernel上曾经发现具多的bug,通常一个邮件丢到邮件群组,宣布发现多少多少bug,这里可以找到当时的邮件存档:  http://www.uwsg.iu.edu/hypermail/linux/kernel/0105.3/index.html
后来他和他的学生成立了一个公司Coverity推广他的工具,可惜收费。

似乎他有个学生来自清华,Junfeng Yang,也很牛,在OSDI (Operating Systems Design and Implemention)发了两篇。

星期四, 四月 26, 2007

D-BUS

星期日, 四月 22, 2007

svn感受

用svn已经有一段时间了,比较满意。
1)svn提供了相当出色的命令行工具,基于命令行的操作,感觉大多时候比gui更方便。
2)subversion book写的很好,大大缩短上手及熟练过程
3)copy-modify-merge模式有很多好处,适合于个人开发或沟通不畅的team。
4)subversion 提供了强大的离线工作能力(本地.svn目录)
5)概念得到简化,比较清晰,比如changeset, branch, tag等。

星期四, 四月 19, 2007

gtkImage与事件

gtkImage是图像控件,但有一个特性需要注意,它属于"no window"控件,所以不能接收事件。
按手册的说法,如果要它接收事件,需要将Image放到Eventbox中,然后将事件connect到Eventbox中。但在glade中,却可以为他们定义事件(glade-2和3我都试了)。

除了使用Eventbox外,在Image的容器上接收事件也可以,大部分容器控件的缺省event
mask为0,表示不接收事件,所以也需要更改才能接收事件,幸好glade里改event
mask很方便,需要注意的是鼠标移动事件和鼠标按下后移动事件有不同的mask。

星期三, 四月 11, 2007

glade与gnomeui

glade是gtk的用户界面设计工具,在安装glade之后,我们就可以使用图形化的方式编辑界面,主要是使用gtk的控件,但处了gtk控件以外,gnome也增加了很多有用的控件,这时候必须安装glade-gnome,才能看到这些gnome控件。

但从大的趋势上看,gnomeui 应该只是一个过渡,最终大部分控件会被融合到gtk中,所以从兼容性的角度来看,使用gnomeui不太好。但在没有更好的控件之前,有时使用gnomeui也是一种折衷。 

参考这里有更详细的描述: http://live.gnome.org/LibgnomeMustDie

星期一, 四月 09, 2007

pyGtk pixbuf的"内存泄露"

使用pixbuf似乎很容易造成"内存泄露",尤其是在使用pixbuf的zoom功能scale_simple时,当放大图像时,内存被快速耗尽,即使再将图像缩小回去,内存占用也不降低,似乎是"内存泄露",找到一个FAQ的解释说这和Python的内存回收机制有关。解决方法是手动调用gc.collect(),我测试了一下,确实有效,参考代码是:
pb = gtk.gdk.pixbuf_new_from_file (image_path)
pb = pb.scale_simple(thumb_width, thumb_height, gtk.gdk.INTERP_BILINEAR)
thumb_list_model.set_value(thumb_list_model.append(None), 0, pb)
del pb
gc.collect()
FAQ的链接在这里: http://www.async.com.br/faq/pygtk/index.py?req=show&file=faq08.004.htp

星期三, 四月 04, 2007

rsync

rsync是如此神奇的同步软件,它用来在不同主机间同步文件系统。它不需要历史同步信息,也不需要依赖时间戳,但它却做真正的增量拷贝,也就是说假如你的文件在主机间只有少量差异,那么rsync会只传送差异,即使是二进制文件也可以增量拷贝。因此rsync给人的感觉就是神奇且速度奇快。

隐藏在rsync背后的就是一个rsync算法,记录在rsync原作者Andrew Tridgel的1999年的博士毕业论文 Efficient
Algorithms for Sorting and Synchronization
中,这篇论文共115页,我没有精力看完它,不过关于这个算法的介绍网上比比皆是。

在看介绍之前,我自己想了一下,大概猜测是用hash之类的算法,将文件分块得到的hash传递给对端主机以作比较,然后就可以做增量拷贝,但我很快就否定自己的想法了,比如一个文件的开头被加了一个字符,那么会导致所有的hash比较都不相等,而这种修改又是非常常见的。

迫不及待的看完rsync算法介绍之后,我明白了,原来我的想法和真正的rsync算法可以说已经接近了,但也可以说有天壤之别,问题就在于如何处理我难以解决的那个问题,rsync设置了两个hash算法,一个强一个弱,强hash就是和我想象的hash一样功能(rsync用的是MD4),关键之处在于这个弱hash,它叫做rolling
hash,说的再直白一点就是类似于checksum的算法,可以在文件中以一个固定窗口来快速移动计算。这样以弱hash来做快速滑动比较,以寻找"可能"相同的块,强hash来校验之,问题解决。这样的算法可以对付几乎所有的文件类型的增量拷贝,但我想对某些特殊类型文件,比如压缩文件,可能不那么有效。

看似微不足道的设计成就了这个经典的同步软件 --- rsync.
( 微软的Server 2003中包含的分布式文件系统(DFS)中实现了一个"类似"的RDC协议。)

星期二, 四月 03, 2007

Effective SVN

Subversion中实际上没有branch的概念,它只懂得如何做copy,当我们将项目从主干branch到分支下的时候,Subversion只是做了一个浅拷贝(cheap
copies),把这个拷贝当作branch只是用户的理解。

Subversion的版本标识数是针对整个Repository的,每个文件的版本号实际上是这个文件在Repository的这个版本下的状态。

Subversion的merge其实不是真正的merge,而只是"diff-and-patch",这方面比clearcase差,因此要实现真正的merge操作,你必须牢记"diff-and-patch"原则,比如你想将branch1
merge到trunk上,需要对branch1的base和current做diff,再patch到当前trunk的working
copy。由于Subversion不会记录merge,所以只能在commit时的comment中记录,比如你可能两次merge同一个branch到主干,在第二次merge时,你只有参考第一次merge的comment才知道上次的merge是在哪个版本做的,这样可以从那个版本之后开始做,省去大量的工作。

Subversion的svn move也不是真正的rename,而是copy-and-delete,而且Subversion不会记住新文件的历史来源,这在大部分情况下不会造成问题,但在分支Merge时,某个分支上的move操作可能就会掩盖其它分支上对源文件的修改。

Subversion提供了一个有意思的feature--svn switch,可以高效的在分支间切换,它在本质上和svn
update同义,但svn update仅仅是在同一个路径的不同时间进行diff操作,但svn
switch则在不同路径(分支)的不同时间进行diff操作。由此引申了一个用法,在对主干文件修改后,你忽然意识到应该是在分支上做修改而不应该是主干,你可以使用svn
switch在commit,没有问题。

Tag和branch本质上完全相同,都是svn
copy,唯一的不同是我们"认为"不应该对tag进行commit,如果一旦用户做了commit,那么这个tag就变成了branch。

Subversion repository的备份不是直接的cp这么简单,因为简单的cp命令可能导致一个不一致的备份(假设有多人频繁commit),需要使用svnadmin
hotcopy....

星期日, 四月 01, 2007

SVN 使用小结

Subversion的使用还是很简单的,下面列出10条/组基本命令,分支属于高级功能,不在此列出。
1)安装Subversion
apt-get install subversion

2)创建Repository, create后的参数一定是一个本地的path.
svnadmin create /usr/path/repos

3)import当前目录下所有文件到Repository中, 这里的参数则是一个URL了.
svn import file:///usr/path/repos/ -m "Initial import"
svn可以支持符号连接文件(symbol link),但在windows系统下不支持.

4)checkout一个repos到工作目录
svn co file:///usr/path/repos

5)从repos更新文件
snv update
显示更新的每个文件都有一个字符描述更新类型: A-added, D-deleted, U-updated, C-conflict, G-Merged

6)更改目录结构, 这些命令通常对working copy执行,但也可以对URL执行,对working
copy执行时,生效要等到commit时,而对URL做时,直接生效。
svn add/ svn copy/ svn move/ svn mkdir

7)检查Working copy的修改情况 通常在commit/update前要做的事
svn status

8)对于冲突文件,需要手工解决(修改此文件),然后执行
svn resolved
当然如果不想要自己的修改了,可以用svn revert恢复服务器版本

9)提交修改
svn commit

10)放弃修改
svn revert