TinyOS论文01:T-Check:Bug Finding for Sensor Networks.

论文中的Bug指的是:传感网程序的bug(TinyOS源码的bug)

一、摘要

  1. T-Check工具:采用模型检测随机检测这两种方法来找出传感网状态空间中违反安全属性活性属性的bug;
  2. 所涉及到的模拟器:TOSSIM模拟器(事件驱动):对中断驱动和底层硬件交互的抽象,T-Check不能检测某些底层的Bug。
  3. 但T-Check能够检测分布式错误,例如:当一个结点失效时集合树协议(CTP)未能正确地修复传感网的状态空间这样的bug。

二、介绍

  1. T-Check的实现思想:传感网程序有些bug检测不到的一个简单原因是传感器结点的测试环境与它真实的部署环境测试环境是有所不同;因此引入了一种基于状态空间搜索的测试方法:详尽地列举出传感网所处的状态(这种方法原则上可以找出传感网程序的所有bug)
  2. T-Check工具:采用模型检测随机检测这两种方法来找出传感网状态空间中违反安全属性活性属性的bug;
    1、安全属性:
    1) 从TinyOS中继承(大部分) + 也可由开发人员指定
    2) 形式:传感网不会XXX,例如:TinyOS中数组索引为0—9
    2、活性属性:
    1) 必须由开发人员指定;
    2) 形式:传感网最终是XXX,例如:缓存最终会处于一个打开的状态(unlock);
  3. TOSSIM:
    1、基于事件驱动的传感网程序运行的模拟器;
    2、不支持并发执行
    3、TOSSIM的上述特点就表示:TOSSIM不能用于检测某些底层的传感网程序错误,例如:时钟错误 + 栈溢出+ 由中断抢占导致的竞争条件 。
    4、但是在另一方面,TOSSIM这种粗粒度、基于事件驱动的模拟器很适用于状态空间的探测;. 对中断驱动和底层硬件交互的抽象来简化程序的运行从而会减少传感网的状态空间。这里就采用了TOSSIM模拟器作为T-Check的基础
  4. 论文的研究包括要解决的问题:
    1、传感网程序执行的时候哪些安全属性或者活性属性是该被检测的?
    2、如何有效的搜索大型的状态空间?
    3、抽象底层的细节来找出高层的bug是不是一个好的方法?
    4、在传感网执行的时哪些非决定性的资源是可以被使用到状态空间的搜索?
    5、随机检测与模型检测的如何权衡?
    6、用这种方法能否有效地检测TinyOS程序的bug
  5. 总之,使用T-Check能偶找出12个TinyOS中未曾遇到过的bug,大部分已经被TinyOS开发人员修正。

二、 背景

一、TinyOS

  1. TinyOS:无线传感网操作系统 + 为低能耗、有限内存的单片机设计的
  2. TinyOS:单独的一个栈、支持中断处理器还有任务(耗时操作) + 支持并发
  3. 组件 + NesC + Interface(Command + Event) + module + configuration
  4. 事件驱动 + 任务 + 中断
  5. 分离-阶段(split - phase)用于并发

二、TOSSIM

  1. 对于T-Check而言,TOSSIM的最大好处是:TOSSIM可以自动模拟事件的执行 + 对中断驱动和底层硬件交互的抽象;这就意味着,在TOSSIM上执行的代码不会被中断抢占(非抢占执行模型),这就大大减少了T-Check要在TinyOS探索的状态空间;但是相反,某些错误也不能被T-Check所检测到,譬如:时钟错误、并发错误,底层设备驱动的bug

三、Safe TinyOS

  1. nesC不安全 + TinyOS结点缺少内存保护硬件、缺少指针和数组调试;
  2. 安全的TinyOS:使用代理编译器(支持静态和动态监测)来加强类型还有内存安全;代理编译器是基于采用了数组绑定信息的依赖类型系统,与其它内存安全版本的C不同,他没有在Harvard-架构上的内存开销(???)
  3. 对于T-Check来说,安全的TinyOS中提供了大量断言,这些断言可以作为传感网程序安全属性检测,T-Check通过这个可以检测出违反这些属性的bug

四、Model Checking

  1. 传感网程序的状态空间:将传感网结点的状态抽象成一组状态空间模型;
  2. 为结点状态的定义活性属性(一组谓词 + 公式),譬如说结点处于某个状态的时候它的缓存是处于打开状态的。
  3. 如果在规定的时间内到达给定的状态并且满足活性属性的话就表示没有违反这个结点的活性属性。
  4. 检测器:探索计算机系统的状态空间;为给定的状态定义一个谓词(一个或真或假的公式),表明为了满足某些属性,这些状态是否能成立;真实系统执行的状态空间路径成为一个Execution(执行过程)*。(可理解成通过搜索状态空间的方法检测安全属性和活性属性)
  5. 安全属性的违反(违反TinyOS内置的规定):在执行过程中如果有状态违反了安全属性,则称整个执行过程都违反了安全属性 + 活性属性的违反(未能达到终态):即在有限的时间内会到达某一个给定的状态,则成该执行过程满足活性属性;
  6. T-Check的实现思想:
    1、通过查找足够长的违反活性属性能够检测出违反活性的属性;
    2、基于以上观点,活性属性的违反可以分为两类:瞬态活性属性的违反(它最终会到达一个活性状态) + dead活性属性的违反(再怎么样都不会达到一个活性状态)
    3、关键过度点:关键过度点是最后一个从瞬态活性转换到死亡活性的最后一个状态;

T-Check

  1. T-Check是基于TOSSIM的状态空间探索工具,TOSSIM是一个编写脚本语言的模拟器,由Python语言执行的脚本模拟器,T-Check也是一个这样的脚本;
  2. T-Check支持两种操作模式:
    1、随机检测模式
    2、模型检测模式:模型检测模式中,T-Check的执行的具体阶段:
    1) 随机执行用于将传感网络通过初始阶段到达一个稳定状态;
    2) 深度有界模型检测用于详尽的探索系统状态空间到达某一深度;
    3) 通过状态空间的随机探索用于找出额外的安全违反行为和验证可能违反活性的行为;
    4) 进一步的随机探索用于找出违反活性的关键的过渡点

一、安全属性与活性属性

安全属性与活性属性示例:
这里写图片描述

二、T-Check中的随机性
(模拟全部可能发生的情况来建模传感网状态空间)
4. 为了成功找出传感网程序的状态空间,T-Check应该采用随机性条件;如果丢失一个随机性条件的话,一些bug可能会被忽略掉;但是相反,如果随机性条件被添加到原始系统中并不会出现这个条件的话,我们就会探索错误路径和报告错误(而事实中是不存在的错误)
5. T-Check的第一种随机性条件:交互随机性
例如:一个已发送的数据包的四中操作算子情况:是否发送交互或者丢弃 + 一个以接收的包是否成功接收或者有数据丢失;
6. T-Check的第二种随机性条件:”粗粒度节点层型的随机性条件“,包括结点的正常执行、死亡和重启
7. T-Check的第三种随机性条件:”事件顺序随机性“:单一节点中事件序列的顺序不能保证(任务的顺序就可以保证)。
(建模的实现:事件队列、中断队列、TOSSIM中断扩展)
8. 为了给TinyOS执行语义建模,T-Check为每一个节点都设有多个事件队列:事件在不同队列可以有不同顺序,但同一队列中的事件顺序是一定的;队列的头部事件为使能事件;
9. 为了确定合适的事件到队列的映射,这种非确定性来源主要是中断,因此,T-Check(不支持抢占中断)对每一个中断生成设备都维护有一个相应的队列;而且,中断(作为原子事件的建模)科可能会与其他任务或者事件交错执行。
10. TOSSIM只有时钟中断,T-Check在TOSSIM的基础上又扩展了ADC(模拟数字转换器)中断、UART(串口)的发送和接收、和串行外围接口;对于bug检测、这些扩展有两个好处:可以测试底层的驱动设备 + 有这些中断驱动的非确定条件执行可以被T-Check探索到。
11. T-Check并不支持中断的抢占执行, + 中断必须要具有实时性,因此不需要对处理器全局中断使能标志建模;另一方面啊,为了避免部分不可行的状态空间探索,与中断源相关的单独使能位必须建模(例如 ADC中断)。

深度有界状态模型检测

  1. T-Check是能执行代码的驱动模型检测器,T-Check使用深度优先的、深度有界的、无状态的、偏序规约的搜索方式。
  2. 无状态执行指的是:通过返回到初始或者稳定状态然后重新执行一些新的路径来实现回溯而不是保存一些检查点。(这种方式更简单和节省内存)
  3. 偏序规约(POR)是一种经常用于减少探索冗余状态的方法,T-Check即是一种静态的POR,这就需要提前知道状态转移的依赖关系。
    1、统一节点上的转换总是依赖;
    2、在不同结点上的转换的事件与发送/接收对匹配也是依赖;
  4. T-Check的目标是探索分布式系统中所有非冗余的状态(分布式的状态装换预先可以确定下来),T-Check的执行步骤为:
  5. 模型检测器首先检查是否有违反安全属性。如果是,则T-Check打印当前的错误信息然后转存到当前的转换栈,作为属性的一个反例;然后,T-Check会创建一个就绪组,与使能组和失眠组不同,就绪组为空,则系统回溯。否则,将就绪组中的元素t取出放到过渡栈,然后执行相应的代码。然后所有依赖t的事件从睡眠组中删除。最后,只要过渡栈的深度没有超过预先确定的深度界限,模型检测的代码就会一直递归调用。
  6. 回溯(到达深度界限或者就绪组为空),将过渡栈中的最后一个元素添加到睡眠组,并且恢复到系统保存的状态(初始或者稳定状态,),接着,由转换栈中的内容来决定状态的转换,状态转换一旦完成,模型检测就会被调用。
  7. 恢复保存传感网程序状态。

四、随机探索状态空间

  1. 模型检测技术能够保证有界深度范围能的bug,但是不适用于指数型的状态空间,这里就引入了随机执行的方法来探索状态空间:当执行到指定深度时,采用随机探索的方法检测出更多的错误和识别可能违反活性的属性
  2. 实现步骤:
    1、检测是否违反了安全属性;
    2、如果是,终止当前事件的执行;否则,对于每一个活性属性和每一个节点,清除满足属性的违反数量和减少违反属性的违反数量,如果违反活性属性的计数吃超过了一定的阈值,就标记为活性违反;最后选择一个使能节点的随机事件来执行;
  3. 随机检测的一个难点是选择不同事件执行的概率问题。T-Check采用的方式是对所有使能的事件都分配的是同意的执行概率(并且用户可以自己制定概率)。
  4. T-Check实现的转换算法:二叉树搜索 ,转换结点作为随机检测的起始点 + 重要的转换发生在从一个活性的状态到最后一个状态 + 一旦一个执行序列是违反活性的,T-Check就会将初始的转换结点切换到重要转换结点。

五、找出短错误路径

  1. 模型检测发现的错误路径一般来说是很短的,很容易找出错误;而随机检测发现的错误路径一般来说很长。
  2. T-Check使用了一种算法来缩短随机检测的错误检测长度。已知的最短错误长度会被保存,步骤为:
    1、首先,错误路径的状态转换结点作为一个改变结点;在改变结点之前的转换都来自保存了的错误路径,而之后的转换时随机的。
    2、变换结点的选择是启发式的:指数型搜索 + 随机搜索(纯粹的)
    3、如果新的搜索路径在给定的长度内没有找到错误,则忽略背刺搜索并结束迭代 + 如果找到了(更短的),则它成为最短的错误路径
    4、另一个启发式改变结点的选择是:对于可能违反属性的结点事件增加它执行的概率。

四、T-Check的使用

这里写图片描述

  1. 如图为T-Check的工具链使用如下:
    1、开发人员想要提供高级的属性(由模拟器属性接口提供、NesC组件的形式),有两种命令:安全属性检测 + 活性属性检测。T-Check提供了自动连接属性组件的脚本。初始属性在Table1中列举,这些属性需要串行栈打开他们的缓存实现如下:
    1)第三个属性列表检测的代码实现如下:
command bool SimProperty.livenessPropertyCheck() {
int tmpMote = sim_node(), mote;
for (mote = 0; mote < sim_simulated_mote_num(); mote++) {
sim_set_node (mote);
if (sim_mote_forms_loop (mote)) {
sim_set_node (tmpMote);
return FALSE;
}
}
sim_set_node (tmpMote);
return TRUE;
}

2、通过Python脚本配置T-Check(扩展了TOSSIM的功能)的相关配置信息,要配置的信息包括:随即执行的概率 + 模型检测的深度 + 是否使用偏序规约。
3、最后,如果T-Check在执行过程中遇到了违反安全的属性,它会将执行序列转存到违反序列中;如果检测到了违反的活性属性,会将关键的转换和执行序列转存到转换序列中。

五、Result

一、Bug检测
结果:找出了12个之前没有发现的bug
这里写图片描述

  1. 串行栈bug
    1、串行栈:传感网为了实现有一个基站结点于与PC通信,TinyOS中提供了一个串行栈,SerialDispatcherP 组件手机传入的字节数据然后发送到合适的高层组件 + 使用的是双缓存机制,其数据结构如下:
    这里写图片描述
    isCurrentBufferLocked函数用于检测当前缓存是否被上锁(被应用程序使用或者串行栈使用的时候会上锁,闲置的时候会打开)
    2、使用T-Check测试以下的安全属性:数据报到达且缓存打开,则能成功收到数据且将数据发送给应用程序层。T-Check能检测出这样一种违反的安全属性:缓存0是当前正在使用的缓存,且正在接收PC发送过来的串行数据报,当数据报接收结束时,当前使用的缓存变为缓存1,而且串行栈通知应用程序缓存0可供使用。锁住了缓存不能接收新的数据违反了安全属性。
    3、改进:使用if else 分支判断。
  2. 串行栈Bug
    1、最后一个字节的数据报被接收时可能会出发这个错误,代码执行逻辑为:最后一个字节的数据报接收成功 + 当前的串口栈并没有等待应用程序执行其它,执行交换缓存 + 提交任务(向应用程序层发送数据报成功接收的信号)
    2、串口栈的一个高级活性属性是:buffer0和buffer1打开。串口栈包含的一个bug是运行缓存死锁,违反了活性属性。Bug的触发条件为接收了无效的数据报。解决bug的方式:在接收错误数据包时释放对当前缓存的锁。
  3. DIP Bug
    1、DIP是一个数据挖掘和传播协议,Figure6代码:发送DipSummary消息(该消息用于总结和散列数据项的版本信息);如getPayloadPtr命令返回Null,将会导致解引用空指针。
    2、改进方法:getPayloadPtr返回空时做一个判断
  4. 更多的DIP Bug
    1、Figure7代码计算数组的左右参数,该程序包含越界数组访问你的两个bug
    2、解决这个bug的三个步骤:
    1) 2) 3)
  5. A Link Estimator Bug
    1、集合树协议(CTP)计算单一或者少数接收点的路由
    Figure8:
    2、首先为CTP设置的活性属性是:最终,所有所有结点从集合树中删除、无违反的属性
    3、第二个检测的属性是连接到连接点的任何结点都最终会成为集合树的一部分
    4、重新连接网络会导致数据报的丢失 + 有损害的网络。
  6. 数据越界Bug
    1、Figure10的应用程序功能:依赖于事件竞争重置数组索引。
    2、 假设下一个readDone事件会在下一个时钟达到之前发生是timer.fired事件初始化结点读取信息
    3、如果计时器的时间到了,当数组索引大于NREADINGS-1的时候,变量reading会作为数组索引;
    4、如果Read接口直接绑定一个传感器的时候不会有bug
    5、另一方面、如果Read绑定到一个资源的资源的
    二、偏虚规约的有效性
    三、TOSSIM、随机探索和模型检测的对比
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值