[wine-zh] 分享: 如何入门 WIne 的开发调试?

  • From: Qian Hong <fracting@xxxxxxxxx>
  • To: wine-zh <wine-zh@xxxxxxxxxxxxx>
  • Date: Tue, 5 Feb 2013 04:58:11 +0800

今天跟一个朋友邮件交流到Wine开发的经验, 我把对他的回复稍微修改一下发布出来, 希望对感兴趣的朋友有启发, 更希望抛砖引玉, 跟大家一起讨论学习.

Wine的开发调试比较困难, 学习曲线比较长, 我学习wine开发的过程中走了很多弯路, 希望整理下来的经验可以让别人少走弯路,
希望以后有更多中国开发者参与Wine项目,为Wine上游做贡献.

要入门WIne的开发, 我认为第一步要学会给Wine报bug,学会在Wine的bugzilla中搜索bug的workaround.
这有多方面的原因,要详细解释,需要花很长的篇幅,以后有时间再专门解释.
简单地说,从报bug做起,可以先熟悉wine的使用,有的朋友可能在使用wine的过程中有很多误区(需要一整篇文章的篇幅来介绍这些误区),如果使用的过程就陷入误区了,就更谈不上开发了.网上很多介绍wine的帖子,不少都是误导的.要纠正这些误区,一个有用的方法就是阅读wine上游的官方文档,以及通过给Wine报bug来积累经验.
另外,当一个bug有已知的workaround的时候,
定位bug的难度会降低很多,而wine的bugzilla是搜索workaround的最佳途径,没有谁比wine的上游开发者最了解如何workaround了.
最后, 报bug可以避免重复劳动, 可以知道前人的研究成果,也可以避免后人走弯路.
如果说成为一名Wine开发者需要的经验值为6的话,那么'会报bug'的时候,经验值就达到0了, 而'连报bug都不会', 经验值可能是
-2. 对wine开发感兴趣的朋友, 我建议先到软件下载站排行榜下载一批软件进行测试, 给 Wine 报 30 个 bug,
这个过程就可以了解到很多有价值的东西了. 顺便说一下, 如果有朋友给 Wine 报了bug, 欢迎抄送我. 在bugzilla上点击
'cc', 输入我的邮箱地址 (fracting AT gmail DOT com), 我就会收到这个bug的更新, 做一些力所能及的事情.

假设我们已经熟悉了如何从Wine的bugzilla中查找workaround以及如何报bug, 那么接下来,
可以采用下面的练习方法去学习wine的调试.这套方法是我经过走弯路之后摸索出来的,因此我没办法验证一个没走过和我相同弯路的朋友采用下面的方法是否有效,还希望试过的朋友分享一下心得体会,或者吐槽一下也行,告诉其他朋友我的方法根本不靠谱,千万不要被我误导.
最坏的结果是没人回应,既不说好也不说坏,这样我就不知道分享的内容到底有没有用了.

入门Wine的调试, 最重要的一关是学会阅读Wine的日志, 不是终端的普通日志, 而是打开了调试参数的详细日志. 如何读这些日志,
也是入门Wine调试的第一个门槛.
关于调试参数, 又叫 debug channel, 官方介绍见此:
http://wiki.winehq.org/DebugChannels
http://www.winehq.org/docs/winedev-guide/wine-debugger
读完上面的文档,可以看一看Wine开发者运用这些调试参数的实例:
http://wiki.winehq.org/DeveloperExamples
这些实例一开始可能很难读懂, 如果没有办法读懂这些实例,要参与Wine开发几乎是不可能的. 以下三个阶段的自我训练方法,应该有助于读懂Wine的调试日志.

第零阶段包括一些编程必备的基础知识,例如c语言基础,bash基础,操作系统基础,Windows api编程基础, linux编程基础等.
这些在网上可以搜到一些公认比较优秀的教材,我就不重复了.

第一阶段的练习, 是学习 WINEDEBUG=+relay 的日志的阅读方法.
先写一个hello world 程序, 除了 printf("helloworld\n") , 什么都不做, 用mingw交叉编译为 exe, 然后终端运行:
WINEDEBUG=+relay wine helloworld.exe &> relay.txt , 在日志中搜索 Starting
process, 找到 helloworld.exe 的相关日志, 然后根据helloworld.exe的线程号 grep 一下日志,
只保留同一个线程的日志, 然后从日志中寻找printf的helloworld, 从那句话的上下文处开始理解日志, 必要的时候结合
helloworld.exe 的反汇编代码去读日志.
这一步的要点是, 了解日志中哪些信息是价值大的,哪些信息是价值比较少可以忽略的. 做完这个helloworld实验之后,
可以写一些稍微复杂的程序进行练习, 这就是第二阶段的事情了.

第二阶段的练习-了解更多的调试参数,学会从调试日志反推闭源程序的伪代码:
过完上一关之后, 可以下载 windows 编程第五版的实例程序, 在wine下运行, 阅读 +relay 日志, 并结合wine的wiki,
了解其他debug channel, 比如 +win +msg +message 等, 再结合源代码, 搜索每个dll的源码里的
WINE_DEFAULT_DEBUG_CHANNEL , 可以知道什么dll需要用什么debug channel 观察.

这样做一些练习之后, 可以把握那种从日志反推伪代码的感觉: 一开始是对着windows 5th 的 sample code阅读wine的日志,
后来要想办法从日志反推出sample code是怎么样的.

做这些练习的时候,需要循序渐进,从最简单的开始,这也是为什么需要 windows 5th这本书的实例的,因为开头的实例比较简单.

这个阶段的练习还要注意积累有潜力作为'标记'的日志特征.
什么是'标记'呢? 比方说, 我有一个程序, 有两个图形界面控件,
那么日志中就会出现两个控件的日志,怎么从日志中知道哪个控件对应那一部分的日志呢? 我能想到的其中一个方法是, 同时打开
+win,+message 和 +relay 日志, 运行程序的时候用鼠标点击一下你想标记的控件,
这样就能从日志中根据鼠标点击的记录,判断哪部分日志对应于那个被我们点击过的控件,而哪部分日志对应于另外一个控件.
再比如, 有个程序, 运行状态会随时间改变, 那么我可以用鼠标点击这个程序两次, 阅读日志的时候, 两次点击之间的日志就对应两次点击之间的事件.



这类标记的运用需要积累和创新,在真正调试问题的时候,需要灵活运用已有的经验.欢迎大家分享更多例子.

Windows编程第5版 这本教材附带的sample程序可以从这里下载:
http://www.charlespetzold.com/pw5/
电子书也可以从网上下载得到.
这本书的几乎每一章都会同时有几个类似但又不完全相同的示例程序, 这些程序可以作为练习阅读日志的好材料:
想象自己跟自己玩猜谜游戏, 依次在Wine下运行几个同类的示例程序, 配合某些调试参数, 然后把日志保存下来进行阅读,
看看自己能不能通过日志猜出哪份日志对应哪个程序? 注意要自己防止'无意作弊',
比如日志的文件名,以及日志内出现的文件名,都有可能成为泄漏信息的来源,要自己想办法避免这些情况,否则这个'猜谜游戏'就失去练习的意义了.

第三阶段的练习-研究Wine的测试用例:
WIne自带了一套测试用例,用于确保Wine的api跟Windows的api行为相同. 这些测试在源代码目录的
dlls/XXX/tests下, 这里 XXX 替换为相应的dll名称.

找一个自己关心的dll, 运行它对应的测试用例, 比如 跑 dlls/gdi32/tests 下的测试, 只要运行 make && make
test就可以了. 运行测试的时候, 打开 +relay 和+XXX 日志, 这里的 XXX对应与你关心的dll, 比如 gdi32
可能对应与 font/dc/dib/gdi
等,然后边读日志边读tests的源代码边读gdi32本身的源代码,这个方法可以从表层开始层层深入: 一开始读的是
tests本身的源代码,然后深入一层就变成 gdi32 的源代码, 再深入一层就变成 gdi32
所依赖的底层的源代码,这时候就根据你要阅读的源码需要开启更多更底层的debug channel了.
实际上, 初入门wine开发的话,从实用的角度看,没必要了解太多底层细节.
当然有的朋友对底层兴趣很强烈,这样的话研究wine的底层也是一种乐趣,不过我目前在这方面没有什么领悟可以分享给大家就是了 :)

做完这三个阶段的练习, 重新阅读上文提到的 DeveloperExamples中的调试实例,应该就会轻松很多了. 这个时候,
就可以开始尝试修复wine的一些bug了. 一开始应该尽量从那些已知workaround的bug入手, 因为这些bug最容易定位和修复.

有一个开源项目叫做ReactOS,是一个开源版本的Windows,借用了Wine的部分代码, Wine的调试参数对ReactOS也有效,
我认为上面上个阶段的练习方法对于ReactOS的调试开发也是有价值的,不过我自己没有做过ReactOS的开发,只是猜测而已,还希望跟其他朋友一起交流经验.

上面的文章是修改自对一位对wine有了解的朋友的回复,没有时间好好整理就发出来了,主要怕Zhenbo
Li同学提的关于迅雷的问题太久没有得到回应,所以仓促发了这篇文章作为回应的第一部分. 如果有错漏或者介绍不清楚的地方还请大家帮忙指出,
我估计有些背景知识可能还需要另外花时间去整理. 由于时间仓促,也没有给上面的'三个阶段'添加具体的实例,以后希望有时间可以补充.

这篇文章以 CC-允许转载-允许修改-保留原作者-非商用 的许可发布, 欢迎大家一起来改进文章, 增添实例, 吸引更多中国的开发者参加wine项目.

洪谦
2012-02-05

--
Regards,
Qian Hong

-
Sent from Ubuntu
http://www.ubuntu.com/

Other related posts:

  • » [wine-zh] 分享: 如何入门 WIne 的开发调试? - Qian Hong