怎样调试C语言的TSR程序?
TSR(terminate and stay resident)程序是一种执行完毕后仍然驻留在计算机内存中并继续完成某些任务的程序,这一点是通过使操作系统的某些部分定期调用由TSR程序驻留在计算机内存中的代码来实现的。
TSR程序的工作方式使TSR程序调试起来非常困难!因为对调试者来说,TSR程序真正的执行时间非常短,调试者根本无法知道TSR程序正在做什么,也无法知道TSR程序是否结束了或仍在运行。正是这种“不可见性”使得TSR程序作用非凡,然而它带来了很多问题。
此外,TSR程序是通过改变向量地址,改变可用内存的大小以及其它方法使自身驻留到内存中的,这一过程会与调试工具的执行发生灾难性的冲突,而调试程序也可能会破坏TSR所作的这些改变。
无论如何,用调试程序调试TSR程序几乎是不可能的,除非有了专门为TSR程序设计的调试程序。然而,你可以用其它方法调试TSR程序。
首先,你可以再次使用前文中提到过的一种方法,即利用print语句监视程序的运行情况。这里要对这种方法稍加改动:每当TSR程序被系统调用时,无论系统采用什么方式(击键,时钟中断,等等),你都可以用append模式打开一个记录文件,并将能告知程序员程序运行情况的有关信息打印到这个文件中。这些信息可以包括执行过程中遇到的函数,变量的值以及其它信息。在TSR程序执行完毕(或崩溃)后,你可以分析这个记录文件,并从中获得一些有价值的信息。
另一种方法是创建一个"假的"TSR程序。换句话说,创建一个与TSR程序功能相似的程序,但并不是一个真正的TSR程序!相反,还要使这个程序成为一个测试程序的子程序。你可以很容易地把原来接受系统中断的功能改为从主程序中接受函数调用。你可以把输送给TSR程序的输入信息“封装”在主程序中,也可以让主程序动态地从程序员那里接受这些输入信息。
这个功能和TSR程序相似的程序永远不会把自身装到计算机内存中,也不会改变操作系统的向量地址。
第二种方法有几点明显的好处:它使程序员能够使用自己惯用的调试技术,调试方法和调试程序,它也为程序员提供了一种更好的观察程序内部操作的方法。此外,真正的TSR程序会驻留在内存中,如果不将它们移去,它们会一直占用一部分计算机内存。如果你的程序还未经调试,那么它完全有可能不能正确地把自身从计算机内存中移去,而这很可能会导致耗尽计算机的内存(这一点很象内存漏洞)。
TSR程序的工作方式使TSR程序调试起来非常困难!因为对调试者来说,TSR程序真正的执行时间非常短,调试者根本无法知道TSR程序正在做什么,也无法知道TSR程序是否结束了或仍在运行。正是这种“不可见性”使得TSR程序作用非凡,然而它带来了很多问题。
此外,TSR程序是通过改变向量地址,改变可用内存的大小以及其它方法使自身驻留到内存中的,这一过程会与调试工具的执行发生灾难性的冲突,而调试程序也可能会破坏TSR所作的这些改变。
无论如何,用调试程序调试TSR程序几乎是不可能的,除非有了专门为TSR程序设计的调试程序。然而,你可以用其它方法调试TSR程序。
首先,你可以再次使用前文中提到过的一种方法,即利用print语句监视程序的运行情况。这里要对这种方法稍加改动:每当TSR程序被系统调用时,无论系统采用什么方式(击键,时钟中断,等等),你都可以用append模式打开一个记录文件,并将能告知程序员程序运行情况的有关信息打印到这个文件中。这些信息可以包括执行过程中遇到的函数,变量的值以及其它信息。在TSR程序执行完毕(或崩溃)后,你可以分析这个记录文件,并从中获得一些有价值的信息。
另一种方法是创建一个"假的"TSR程序。换句话说,创建一个与TSR程序功能相似的程序,但并不是一个真正的TSR程序!相反,还要使这个程序成为一个测试程序的子程序。你可以很容易地把原来接受系统中断的功能改为从主程序中接受函数调用。你可以把输送给TSR程序的输入信息“封装”在主程序中,也可以让主程序动态地从程序员那里接受这些输入信息。
这个功能和TSR程序相似的程序永远不会把自身装到计算机内存中,也不会改变操作系统的向量地址。
第二种方法有几点明显的好处:它使程序员能够使用自己惯用的调试技术,调试方法和调试程序,它也为程序员提供了一种更好的观察程序内部操作的方法。此外,真正的TSR程序会驻留在内存中,如果不将它们移去,它们会一直占用一部分计算机内存。如果你的程序还未经调试,那么它完全有可能不能正确地把自身从计算机内存中移去,而这很可能会导致耗尽计算机的内存(这一点很象内存漏洞)。