64位开发中去除64位平台的内存错误
发布时间:2006-02-16 10:42:01 来源:天极开发 网友评论 0 条 对新平台上应用程序的开发者来说,64位平台的稳定和可靠,是吸引他们的关键;而任何内存错误问题都会导致开发工作的失败,内存错误最棘手之处在于它是难以捉摸的,找出它们非常困难且要花费大量时间。内存错误不会在通常意义上的测试中暴露出来,正是因为它们潜在的有害性,所以在程序定型之前,去除所有的内存问题就显得非常必要了。
目前有一些强大的内存错误检测工具,它们可以在运行于双核心处理器的应用程序中,找出导致线程内存错误的原因;它可在传统测试技术找不出问题的地方,找出并修正那些难以捉摸、导致程序崩溃的"元凶"。错误检测工具可帮助你在发布程序之前,找出并修正那些C/C++内存错误,而在移植程序之前修正这些问题,可提高在新平台新架构上的程序质量,使移植过程更加流水线化,并且使老程序更加健壮可靠。
为何移植如此之难?
在向64位处理器或新硬件移植代码时产生的问题当中,大多数开发者是负有主要责任的。就此来说,代码在移植到新平台或新架构之上时,内存问题似乎也成倍增长了。
在过渡到64位架构时最基本的问题,就是对各种不同的int和指针在比特位长度上假定。在从long转换到int时,不管是赋值还是显式转换,都存在着一定的隐含限制。前者可能产生一个编译器警告,而后者可能被无声地接受,就此导致了运行时的各种错误。另一个问题就是int常量并不总是与int同样大小,这是混淆有符号和无符号常量的问题,同时,适当地使用有关的后缀可以减少此类问题的发生。
另一些问题的主要原因是各种指针类型的不匹配。举例来说,在多数64位架构上,指针类型不能再放入一个int中,而那些把指针值储存在int变量中的代码,此时当然就会出错了。
这些问题通常会在移植过程中暴露出来,因为移植从本质上来说是一种变体测试。当你在移植代码时,实际上是在创建一种"同等变体"(对原始代码的小幅改动,不会影响到测试的结果),而通过这些"同等变体",可找出许多不常见的错误。在C/C++中,创建和运行"同等变体",可揭示出以下问题:
1、缺少拷贝构造函数或错误的拷贝构造函数
2、缺少或不正确的构造函数
3、初始化代码的错误顺序
4、指针操作的问题
5、依赖未定义的行为,如求值的顺序
在准备移植应用程序时,有以下几个相关步骤
第1步、在移植之前,要保证原始代码中没有诸如内存崩溃、内存泄露等问题,找出指针类型和int错误的最有效的一个方法是,采用平衡变体测试,来达到运行时错误检测的目的。
变体测试最先是为解决无法计量测试的准确性问题而产生的,大致如下:假定已有了一个完美的测试方案,它已经覆盖了所有的可能性,再假定已有一个完美的程序通过了这个测试,接下来修改代码(称之为变异),在测试方案中运行这个"变异"后的程序(称之为变体),将会有两个可能的情况:
一是程序会受代码改变的影响,并且测试方案检测到了,在此假定测试方案是完美的,这意味着它可以检测一切改变。此时变体被称作"已死的变体"。
二是程序没受改变的影响,而测试方案也没有检测到这个变体。此时变体称作"同等变体"。
如果拿"已死变体"和已生成的变体作对比,就会发现这个比率要小于1,这个数字表示程序对代码改变有多敏感。事实上,完美的测试方案和完美的程序都不存在,这就说上面的两种情况可能会有一个发生。
程序受影响的结果因个体而异,如果测试方案不适当,将无法检测到。"已经变体"和"生成变体"的比率小于1同时也揭示了测试方案有多精确。
在实践中,往往无法区分测试方案不精确与同等变体之间的关系。由于缺乏其他的可能性,在此我们只好把"已死变体"对所有变体的比率,看成是测试方案的精确程度。
例1(test1.c)证实了以上的说法(此处所有的代码均在Linux下编译),test1.c用以下命令编译:
例1:程序test1.c
这个简单的程序读取输入的参数,并打印出相关的信息。现在假定用一个测试方案来测试此程序:
这个测试方案在业界是有一定代表性的,它进行正则测试,表示它将测试对所有正确的输入,程序是否有正确的输出,而忽视非法的输入。程序test1完全通过测试,但它也许隐藏着严重的错误。
现在,对程序进行"变体",用以下简单的改变:
如果在测试方案中运行此修改后的程序,Mutants 1和3完全通过测试,而Mutant 2则无法通过。
目前有一些强大的内存错误检测工具,它们可以在运行于双核心处理器的应用程序中,找出导致线程内存错误的原因;它可在传统测试技术找不出问题的地方,找出并修正那些难以捉摸、导致程序崩溃的"元凶"。错误检测工具可帮助你在发布程序之前,找出并修正那些C/C++内存错误,而在移植程序之前修正这些问题,可提高在新平台新架构上的程序质量,使移植过程更加流水线化,并且使老程序更加健壮可靠。
为何移植如此之难?
在向64位处理器或新硬件移植代码时产生的问题当中,大多数开发者是负有主要责任的。就此来说,代码在移植到新平台或新架构之上时,内存问题似乎也成倍增长了。
在过渡到64位架构时最基本的问题,就是对各种不同的int和指针在比特位长度上假定。在从long转换到int时,不管是赋值还是显式转换,都存在着一定的隐含限制。前者可能产生一个编译器警告,而后者可能被无声地接受,就此导致了运行时的各种错误。另一个问题就是int常量并不总是与int同样大小,这是混淆有符号和无符号常量的问题,同时,适当地使用有关的后缀可以减少此类问题的发生。
另一些问题的主要原因是各种指针类型的不匹配。举例来说,在多数64位架构上,指针类型不能再放入一个int中,而那些把指针值储存在int变量中的代码,此时当然就会出错了。
这些问题通常会在移植过程中暴露出来,因为移植从本质上来说是一种变体测试。当你在移植代码时,实际上是在创建一种"同等变体"(对原始代码的小幅改动,不会影响到测试的结果),而通过这些"同等变体",可找出许多不常见的错误。在C/C++中,创建和运行"同等变体",可揭示出以下问题:
1、缺少拷贝构造函数或错误的拷贝构造函数
2、缺少或不正确的构造函数
3、初始化代码的错误顺序
4、指针操作的问题
5、依赖未定义的行为,如求值的顺序
在准备移植应用程序时,有以下几个相关步骤
第1步、在移植之前,要保证原始代码中没有诸如内存崩溃、内存泄露等问题,找出指针类型和int错误的最有效的一个方法是,采用平衡变体测试,来达到运行时错误检测的目的。
变体测试最先是为解决无法计量测试的准确性问题而产生的,大致如下:假定已有了一个完美的测试方案,它已经覆盖了所有的可能性,再假定已有一个完美的程序通过了这个测试,接下来修改代码(称之为变异),在测试方案中运行这个"变异"后的程序(称之为变体),将会有两个可能的情况:
一是程序会受代码改变的影响,并且测试方案检测到了,在此假定测试方案是完美的,这意味着它可以检测一切改变。此时变体被称作"已死的变体"。
二是程序没受改变的影响,而测试方案也没有检测到这个变体。此时变体称作"同等变体"。
如果拿"已死变体"和已生成的变体作对比,就会发现这个比率要小于1,这个数字表示程序对代码改变有多敏感。事实上,完美的测试方案和完美的程序都不存在,这就说上面的两种情况可能会有一个发生。
程序受影响的结果因个体而异,如果测试方案不适当,将无法检测到。"已经变体"和"生成变体"的比率小于1同时也揭示了测试方案有多精确。
在实践中,往往无法区分测试方案不精确与同等变体之间的关系。由于缺乏其他的可能性,在此我们只好把"已死变体"对所有变体的比率,看成是测试方案的精确程度。
例1(test1.c)证实了以上的说法(此处所有的代码均在Linux下编译),test1.c用以下命令编译:
| cc -o test1 test1.c. main(argc, argv) /* line 1 */ int argc; /* line 2 */ char *argv[]; /* line 3 */ { /* line 4 */ int c=0; /* line 5 */ /* line 6 */ if(atoi(argv[1]) < 3){ /* line 7 */ printf("Got less than 3/n"); /* line 8 */ if(atoi(argv[2]) > 5) /* line 9 */ c = 2; /* line 10 */ } /* line 11 */ else /* line 12 */ printf("Got more than 3/n"); /* line 13 */ exit(0); /* line 14 */ } /* line 15 */ |
例1:程序test1.c
这个简单的程序读取输入的参数,并打印出相关的信息。现在假定用一个测试方案来测试此程序:
| Test Case 1: input 2 4 output Got less than 3 Test Case 2: input 4 4 output Got more than 3 Test Case 3: input 4 6 output Got more than 3 Test Case 4: input 2 6 output Got less than 3 Test Case 5: input 4 output Got more than 3 |
这个测试方案在业界是有一定代表性的,它进行正则测试,表示它将测试对所有正确的输入,程序是否有正确的输出,而忽视非法的输入。程序test1完全通过测试,但它也许隐藏着严重的错误。
现在,对程序进行"变体",用以下简单的改变:
| Mutant 1: change line 9 to the form if(atoi(argv[2]) <= 5) Mutant 2: change line 7 to the form if(atoi(argv[1]) >= 3) Mutant 3: change line 5 to the form int c=3; |
如果在测试方案中运行此修改后的程序,Mutants 1和3完全通过测试,而Mutant 2则无法通过。
相关文章
上一篇文章:JFC/Swing活学活用之JLabel文字魔法
下一篇文章:利用AJAX+J2EE开发组织机构管理系统
- 推荐阅讯
- 根据MIDlet套件自动生成jad文件
- 为什么要用UML建模之建模原理
- 深入浅出组件编程之固有属性和事件属性
- 微软暂停图形软件Expression开发工作
- 玩玩Spring之Rod Johnson与轮子理论
- Eclipse下实现软件项目的源码管理
- 精华:AJAX开发简略(第一部分)
- Eclipse插件的外挂安装方法
- 基于MVC模式的Struts框架研究与应用
- Oracle9i中监视索引的使用
- 阅读排行
- 1..net页面间的参数传递简单实例
- 2.VC++与Matlab混合编程之引擎操作详解
- 3.Oracle数据库数据对象分析
- 4.Eclipse3.2+Tomcat5.5.17+Oracle9配置
- 5.Oracle数据库中索引的维护
- 6.在Oracle的网络结构中解决连接问题
- 7.Oracle数据安全面面观
- 8.Oracle数据库的ORA-00257故障解决过程
- 9.Oracle数据库备份与恢复的三种方法
- 10.Oracle与SQL Server在企业应用中的比较
- 专题教程
- Windows Server-Windows Server文档-Windows Server新闻-Windows Ser PostgreSQL-PostgreSQL文档-PostgreSQL新闻-PostgreSQL专家
- WebLogic-WebLogic文档-WebLogic新闻-WebLogic专家 FreeBSD-FreeBSD文档-FreeBSD新闻-FreeBSD专家
- Linux-内核 GUI KDE Gnome DNS FTP 安全 安装-Linux专区 Windows-AD IIS ServerCore 虚拟化 安全 HPC-Windows专区
- 大话G游 专题:手机病毒揭密
- ARP攻击防范与解决方案 路由故障处理手册
|
