Linux下的代码淬火技术
2008-03-08 12:52:59 来源:WEB开发网 銆�

核心提示: 我们知道,铁匠经常把金属工件加热到一定温度,然后忽然浸在水或油中使其冷却,从而有效增加其硬度,Linux下的代码淬火技术,类似的,软件开发人员也可以采取某种手段, 三、 小结 本文具体介绍了代码淬火技术的概念以及Linux下常用的几种代码淬火方法,在下一篇文章中,从而显著提高软件的可靠性和质量,我们形象地称之为
我们知道,铁匠经常把金属工件加热到一定温度,然后忽然浸在水或油中使其冷却,从而有效增加其硬度。类似的,软件开发人员也可以采取某种手段,从而显著提高软件的可靠性和质量,我们形象地称之为代码淬火技术。
一、代码淬火的好处
理想中,软件淬火技术首先能够预见代码中的哪些地方可能出错,然后,要么带给我们一种能够完全避免错误的方式编写代码,要么能及时识别出错误,从而更轻松地跟踪源代码。尤其是对于C语言,因为它不是一种安全语言,所以更需要软件淬火技术来提高软件的可靠性。本文将具体介绍linux下常用的代码淬火方法。
二、常见的码淬火技术
代码淬火技术的形式各种各样,我们这里要讲的是帮助我们构建更加强健的代码的各种技术。
1 .缓冲区溢出问题
缓冲区是一个非常严重的安全问题,最好的情况下可能导致软件的行为错乱;严重时将会导致被缓冲区利用程序所控制而执行任何攻击者所想要执行的代码。请看下面的示例代码:
...
int i;
for ( i = 0 ; i < 100 ; i++ ) {
ourArray[i] = (char)(0x30+i);
}
ourArray[i] = 0; // 越界,危险!
static char ourArray[ARRAY_SIZE+1];
...
int i;
for (i = 0 ; i < ARRAY_SIZE ; i++ ) {
ourArray[i] = (char)(0x30+i);
}
ourArray[ARRAY_SIZE] = 0; //为数组的最后一个元素赋值
if ( ret < 0 ) {
ret = printf( "An error occured emitting value.\n" );
}
case OperaTIONAL_MODE:
/* 切换到运行模式进行处理 */
break;
case BUILT_IN_TEST_MODE:
/* 切换到测试模式进行处理*/
break;
}
假设现在我们又添加了一种模式,但是上面的代码段没有及时得到更新,这时假如执行了这段代码,执行结果将无法预料。假如包括default部分,至少也能利用该部分在出现问题时通知调用者,即使在此放一个assert,也能在调试时捕捉当时的状况。如下例所示:
case OPERATIONAL_MODE:
/*切换到运行模式进行处理 */
break;
case BUILT_IN_TEST_MODE:
/* 切换到测试模式进行处理 */
break;
default:
assert(0);
break;
}
if (state == FIRST_STAGE) coefficient = 0.75;
else if (state == SECOND_STAGE) coefficient = 1.25;
if (state == FIRST_STAGE) coefficient = 0.75;
else if (state == SECOND_STAGE) coefficient = 1.25;
else coefficient = SAFE_ COEFFICIENT;
#include <stdlib.h>
#include <assert.h>
#define TARGET_MARKER_SIG 0xFAF32000
typedef strUCt {
unsigned int signature;
unsigned int targetType;
double x, y, z;
} targetMarker_t;
#define INIT_TARGET_MARKER(ptr) \
((( targetMarker_t *)ptr)->signature = TARGET_MARKER_SIG)
#define CHECK_TARGET_MARKER(ptr) \
assert(((targetMarker_t *)ptr)->signature == \
TARGET_MARKER_SIG)
void displayTarget( targetMarker_t *target )
{
/* 预先检查 target结构体 */
CHECK_TARGET_MARKER(target);
printf( "Target type is %d\n", target->targetType );
return;
}
int main()
{
void *object1, *object2;
/* 新建两个对象 */
object1 = (void *)malloc( sizeof(targetMarker_t) );
assert(object1);
object2 = (void *)malloc( sizeof(targetMarker_t) );
assert(object2);
/*按照target marker结构体初始化object1 */
INIT_TARGET_MARKER(object1);
/* 尝试显示object1 */
displayTarget( (targetMarker_t *)object1 );
/* 尝试显示object2 */
displayTarget( (targetMarker_t *)object2 );
return 0;
}
在代码的第6-12行,定义了我们的目标结构体,其中有一个专门的头部,名为signature(识别标志),即该结构类型的运行时类型标识符。并且在第4行为该类型定义了一个识别标志,作为该结构类型的唯一描述符号。此外,代码中还提供了两个宏INIT_TARGET_MARKER和CHECK_TARGET_MARKER,分别用来初始化和检验该结构体中的识别标志。 继续往后看,请注重代码的34-54行,其中分配了两个等同长度(targetMarker_t)的内存空间来供两个对象使用,然后利用宏INIT_TARGET_MARKER将其中一个初始化,最后,分别利用displayTarget函数显示。 对于第22-31行的displayTarget函数,首先调用CHECK_TARGET_MARKER来检验收到的对象的识别标志,假如该标志非法,assert就会发挥作用。当然,这里只是一个概念性的演示。 5.错误报告 对于错误报告而言,根据开发的应用类型的不同,需要采取不同的处理方法。例如,假如开发的是命令行工具的话,常用的方法是通过把错误消息递给stderr来告知用用户出错情况。假如开发的是诸如嵌入式Linux应用之类的具有I/O能力的应用程序的话,错误报告的形式就多了,比如专门的日志或标准系统日志(syslog)。其中,syslog函数的原型如下所示:
void syslog( int priority, char *format, ... );
int main()
{
syslog( LOG_ERR, "Unable to load configuration!" );
return 0;
}
{
REGISTER_STS_T retStatus;
/* 验证输入 */
assert( validRegister( register ) );
assert( validMode( mode ) );
/*--------------------*/
/*这里省略checkRegisterStatus 的内部处理部分 */
/*--------------------*/
/* 可能改变了模式,检验之 */
assert( validMode( mode ) );
return retStatus;
}
注重,假如表达是结果为非(即0),assert函数就会停止应用,并在标准输出设备上生成一个错误消息。可以通过定义符号NDEBUG的方法来停用assert。 从上例中我们看到,函数首先通过验证输入来确保得到的数据是正确的,然后通过验证输出来保证它给出的数据也是正确的。根据具体情况,我们可能收到错误消息,即使这样我们也能轻而易举地发现错误之所在。另外,assert的作用不仅限于确保函数的输入输出的正确性,还能用来确保内部的一致性。所有应该在调试期间发现的严重错误,都可以利用assert来轻松处理。 8.优化调试输出 太多的输出能够掩盖错误,但输出过少也会漏掉错误,因此我们需要寻找一个平衡点,使得提供的调试输出和错误消息够用,但又不会过量,这需要在实践中具体把握。 9.内存调试技术 在Linux中,有许多程序库都可以用来调试动态内存治理。最常见的 Electric Fence是一个功能强大并且能及时发现内存错误的库,它不仅可以利用低层处理器的内存治理单元MMU的段故障来捕捉内存错误,而且还能侦察数组越界问题。 10.编译器的支持 实际上,编译器本身就是一个识别代码问题的无价之宝,当构建程序时,一定要使用-Wall项来启用报警功能。 此外,还可以利用-Werror把警告作为错误对待,从而停止对源文件进行进一步的编译,这选项对于大型应用程序格外有用。当我们构建有多个源文件组成的应用程序时,我们可以将两个选项组合使用。如下例所示:
- ››linux下两台服务器文件实时同步方案设计和实现
- ››Linux文件描述符中的close on exec标志位
- ››Linux下管道使用的一些限制
- ››Linux 误删/usr/bin 解决方法
- ››linux 添加新用户并赋予sudo执行权限
- ››linux常用软件安装方法
- ››Linux的分区已经被你从Windows中删除,系统启动后...
- ››linux enable命令大全
- ››Linux实现基于Loopback的NVI(NAT Virtual Interfa...
- ››Linux远程访问windows时,出现"连接被对端重...
- ››linux中使用head命令和tail命令查看文件中的指定行...
- ››linux swap 分区调控(swap分区 lvm管理)
更多精彩
赞助商链接