与熊力先生谈调试

感谢博主的好文章 http://book.51cto.com/art/200711/59610.htm

 

《Windows用户态程序高效排错》一书介绍Windows系统上的用户态程序排错方法和技巧。本文是与熊力先生谈调试的记录。 。

AD: 2013大数据全球技术峰会低价抢票中


    博文专访——与作者面对面

    与熊力先生谈调试

    针对熊力先生的新书《Windows用户态程序高效排错》的出版,博文视点对熊力先生进行了专访,现将熊力先生的谈话整理成文,以飨读者。
    采 访 人:博文视点特约策划编辑刘铁锋(Tiefeng)
    受 访 人:熊力
    采访方式:电子邮件

    作者成长的经历和书籍创作的本身相关问题

    Tiefeng:
    在第一次读完书稿的时候,我非常兴奋。脑海里立马回想起那些挑灯奋战,抽丝剥茧的日子。尤其让我佩服的是,在有源代码的情况下通过调试来解决问题都相当困难。您当年是怎么接触和掌握到这些仅靠symbol 和windbg 来解决问题的技术呢?

    熊力:
    通过调试器来完成一些比较困难的任务,比如在没有源代码的情况下找到问题的根源,通过巧妙的windbg命令来改变系统API的行为等,的确是一项让人觉得技术高超的趣事。其实你所指的这些调试技巧,跟hack和crack其实大同小异。Hacker和Cracker也都是在信息极少的情况下找到一个程序的关键,从技术上讲,都是一样的。区别在于我所从事的工作是通过这些技术帮助客户解决切身的问题,提高产品的质量。跟Hacker和Cracker喜欢挑战一样,我个人也喜欢调试一些复杂奇怪的难题。这种从蛛丝马迹中寻找线索,通过精心设计的调试手段寻求问题根源,最后找出问题所在的过程和成就感都是很让人满足的。之所以接触这项技术是因为我的工作,而深入掌握这项技术,很大程度则是因为我对技术的热情和兴趣。

    不过你所提到的“技术”,只是调试的一小部分。就像这本书第1章所强调的,解决问题主要靠思考,调试器只是一种手段。

    Tiefeng:
    现在windbg 或者windows API 似乎已经被众多的开发者所遗忘,各式各样高级语言似乎更加受到开发者的青睐。您觉得这本书对于这种类型的读者有怎样的帮助呢?

    熊力:
    如果你留意我的blog,会看到我最近提到的一个话题就是C#的struct实例,究竟是在stack上的还是heap上。
    http://eparg.spaces.live.com/blog/cns!59BFC22C0E7E1A76!2603.entry
    如果开发人员对windbg和Win32比较熟悉,只需要在windbg中使用!address命令就可以知道问题的答案。

    另外,你如果仔细统计我书中的真实案例,会发现里面一半以上的案例都是.NET Framework上的问题。比如ASP.NET的性能调优、C# 程序的死锁、内存泄露,等等,如果开发人员对Win32不熟悉,不通过调试器,是不可能找到问题根源的。书中关于Win32的介绍都是一些核心的话题,比如异常分发和内存管理,目的就是给读者背景知识,以便能更深入地理解.NET Framework上的排错。本书所讨论的所有话题都是以最近两年来我处理的真实案例为基础的,目的就是让这本书具有很强的实践性,避免脱离实际。

    同时这是一本关于如何排错的书,而不是介绍某种技术的书。无论开发工具多么高级和智能,软件产品的问题都是无法避免的。遇上问题后如何思考,如何着手,这才是我最想跟大家分享的。而windbg上几个命令的使用,根本不是解决问题的关键。

    对于书籍的阅读以及和读者的要求

    Tiefeng:
    在您调试和解决问题的时候,您觉得最重要的是什么(方法、思路还是经验)?
    【可以列举书中的例子进行说明,比如调一个API 出现两个文件的例子】

    熊力:
    最重要的是思路。

    我在书中提到了,我见过的最牛的debug是Redmond Chen提到的一个问题。
    http://blogs.msdn.com/oldnewthing/archive/2005/03/21/399688.aspx
    有人发现在四个CPU的机器上,总是只有一个CPU工作,另外三个都闲置。Redmond Chen没有使用任何工具,没有抓取任何信息,单凭细致的思考和推断就得出问题在于explorer设定了process affinity。由于这个属性会自动传播给子进程,而绝大多数用户的进程都是由explorer启动的,所以问题就发生了。

    在这个案例中,涉及了对process affinity属性、进程启动顺序等Win32知识。但是让问题暴露出来的关键,还是在于创造性的分析。

    本书中也提到了调一个API同时打开两个文件的奇怪问题。当时经验反而误导了排错的进行。最后还是通过仔细的推敲才解决了问题。

    Tiefeng:
    在您遇到过这些问题之后,您觉得程序员在编写代码的时候,最应该注意些什么呢?

    熊力:
    我自己并没有太多写代码的经验,无法回答这个问题。凭感觉说,每个程序员都是有独立性格的个体,所以每人应该“最”注意的方面,应该是因人而异的吧。

    后期的计划
    Tiefeng:
    您在书中提及,要重现(repro )一个bug 往往需要很多的环境准备。您是否设想过,未来会有怎样的debugger 能够帮忙更好地解决这些问题呢?
    【可以以设想的形式提及微软研究院的项目】

    熊力:
    现在微软最新的调试技术叫做Time Travel Debugging。代号叫iDNA。论文的下载地址在:
    instruction_level_tracing_VEE06.pdf
    http://blogs.msdn.com/cse/attachment/1077668.ashx
    这个技术可以像放视频一样,通过拖拽,观察一个程序的执行过程。当程序启动后,代码都应该是顺序执行的。只有发生异常或者中断的时候,代码执行顺序才会改变。所以记录下程序启动后所有的系统事件,从理论上讲,可以在程序退出后,完整重现程序前一次执行的所有细节。可以像放电影一样,快进到程序退出前的某一个异常观察程序的状态,然后又快退到程序启动的时候观察程序的初始化过程。有了这个技术,一旦问题重现过一次,就可以反复播放观察,这对调试难以重现的问题有很大帮助。当然除了调试以外,这项技术对于程序的破解、数据加密等都有深远的影响。如果快的话,跟该技术相关的最新调试工具会在新版的Visual Studio中面世。

    Tiefeng:
    使用高级语言(如C# )或者脚本语言(Perl、 Python、Ruby )等等进行开发,似乎已经成为了现在开发的主流,相对来说调试似乎也简单了许多。您对调试这类程序有什么看法吗?
    熊力:
    我非常喜欢C#。我老婆在淘宝开店所用到的一切工具软件,都是我用C#完成的。这套工具可以自动化淘宝的页面进行发货、评价、记账、库存管理、客户资料查询,甚至还能进行智能市场分析,还能操作我的西门子手机给客户发短消息。开发这些套工具软件的时候,我在VS2005中用F5和F9就完成了所有的调试,非常方便。
    但是,智能方便的调试工具,并不意味着调试也变得简单。俗话说:道高一尺,魔高一丈。先进智能的调试工具和古怪复杂的问题都是共生的。当开发工具变得简单,开发成本降低的时候,更庞大、更复杂的程序就会诞生,自然更麻烦的问题就会出现。一个简单的例子就是,.NET Framework带来了高效的开发, 同时也带来了COM和.NET Framework发生冲突的问题。所以,如果说调试就是设设断点,看看变量的值,那的确高级语言的调试非常简单。但如果说解决实际问题,这就不是开发工具能够帮忙的地方了。我一直在强调,排错不是操作调试工具,排错是解决现实的问题。永远都会有更新、更麻烦的问题等待解决。而解决问题的唯一武器,就是思考。调试工具不过是表面的把戏而已。

     

    • 0
      点赞
    • 0
      收藏
      觉得还不错? 一键收藏
    • 0
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值