基于MFlood的错误代码分析(作者:lzqlgq@gmail.com)

1错误代码格式及其句柄说明
    错误代码从错误发生时开始输出,然后返回上一级调用,上一级可能继续返回错误代码的相关信息,最典型的模式是
1 "eval $self create-wireless-node $args"          # 命令代码
2   (procedure "_o3" line 23)                    # 命令所在行数
3   (Simulator node line 23)                    # Simulator 实体的node函数体
4     invoked from within                        #
5 "$ns_ node"                                # 调用代码
此5行大体意思是, 1行对应的命令是从句柄为 "_o3"的Simulator实体的函数 node  "函数定义"的第23行调用的,在每一个Simulator对应的模拟中"_o*"标示唯一的一个分裂类实体,也就是说,所有的分裂类实体都有自己的唯一标识。对于MFlood中的错误代码提到的几个句柄说明如下: _o3 是一个Simulator实例句柄, _o14是一个node实例句柄,_o17是一个agent实例句柄

2 MFlood的错误提示及分析
INITIALIZE THE LIST xListHead
1      (_o17 cmd line 1)
2      invoked from within
3  "_o17 cmd port-dmux _o26"
4     invoked from within
5  "catch "$self cmd $args" ret"
//但是MFlood也没有定义次函数,所以问题在这里,没有相应的处理代码
6     invoked from within
7  "if [catch "$self cmd $args" ret] {
8  set cls [$self info class]
9  global errorInfo
10 set savedInfo $errorInfo
11 error "error when calling class $cls: $args" $..."
12     (procedure "_o17" line 2)
13     (SplitObject unknown line 2)
//但是agent 没有port-dmux函数,agent 的祖先也没有次函数,所以转到 ->  MFlood port-dmux $dmux_ 
14     invoked from within
15 "$agent port-dmux $dmux_"
16     (procedure "_o14" line 11)
17     (Node/MobileNode add-target-rtagent line 11)
//8)15-17可知调用."$agent port-dmux $dmux_"
18     invoked from within
19 "$self add-target-rtagent $agent $port"
20     (procedure "_o14" line 23)
21     (Node/MobileNode add-target line 23)
//7)19-21行可知 动态转向了Node/MobileNode  <-o14> 的add-target函数的23行
//这里的node其实是一个移动节点Node/MobileNode 类型,所以调用的是Node/MobileNode instproc add-target { agent port }函数

22     invoked from within
23  "$self add-target $agent $port"        //$self 调用类似于动态运行时
24     (procedure "_o14" line 15)
25     (Node attach line 15)  // attach 函数15行果然是"$self add-target $agent $port" ,计算行数不算注释,空格要算
//6)23-25行,提示_o14即node实体句柄发生文件在ns-2.31/tcl/lib/ns-node.tcl
//可知self add-target $agent $port 来自Node attach函数的15行

26     invoked from within
27 "$node attach $ragent [Node set rtagent_port_]"  //此时 "$ node = = _o14"
28     (procedure "_o3" line 75)
29     (Simulator create-wireless-node line 75)
//5)27-29行,指明出现_o3出现错误的调用语句,在Simulator instproc create-wireless-node args函数体的75行
//即
可知 $node attach $ragent [Node set rtagent_port_] 在该函数的75行

30     invoked from within
31 "_o3 create-wireless-node"        // _o3 是Simulaor的一个实体句柄
32     ("eval" body line 1)
//4)31-32指明了"_o3 create-wireless-node",也就是Simulator instproc create-wireless-node args函数
//在此 _o3 是Simulaor的一个实体句柄

33     invoked from within
34 "eval $self create-wireless-node $args"     #$self = = "-o3" 
35     (procedure "_o3" line 23)
36     (Simulator node line 23)
//2)34-36行,提示在ns-2.31/tcl/lib/ns-lib.tcl文件中的Simulator instproc node args的23行代码
//23   set node [eval $self create-wireless-node $args]     #$self = = "-o3"
//使用eval 是从tcl脚本调用Otcl对象及函数 就是"_o3 create-wireless-node"

37     invoked from within
38 "$ns_ node"
39     ("for" body line 2)
//3)38-39行,分析一下下句语法 & Node_(*)是干什么用的?
//    set node [eval new [Simulator set node_factory_] $args]
//    set Node_([$node id]) $node
//把节点加入到Simulator的C++空间的链表中
//    $self add-node $node [$node id]
//    $node set ns_ $self                    //指向模拟器实例

40     invoked from within
41 "for {set i 0} {$i < $val(nn) } {incr i} {
42         set node_($i) [$ns_ node]    
43         $node_($i) random-motion 0;    
44     }" 
//1)41-44给出错误从脚本附近的代码,在一个for循环中, 38行说明"$ns_ node"是来自42行
//
在tcl脚本里调用如下:

//1 set  ns_  [new Simulator]
//2 set  node_(0)  [$ns_ node]  ;#调用了Simulator instproc node 过程

45     (file "mflood-3nodes.tcl" line 61)
其实tcl中的self 相当于 C++中的this指针,了解C++的肯定知道,this指针有一个运行时的问题,"this command"可能动态调用父类< 或者子类? > 的同名command,具体的分析采用从下向上方法,如果你很熟悉ns2机制,可以越过一些。

3 错误深入分析

ns-2.27之后多了一个 $agent port-dmux $dmux
所以在执行protocol时找不到对应的code
最简单的方法就是在aodv.cc中的 AODV::command(int argc, const char*const* argv)里加一段
else if(strcmp(argv[1],"port-dmux")==0){
        return TCL_OK;
}

以后如果看到有下面的问题,可以同理使用同样的方法解决
"$self add-target $agent $port"
>    (procedure "_o14" line 15)
>    (Node attach line 15)
>    invoked from within
> "$node attach $ragent [Node set rtagent_port_]"
>    (procedure "_o3" line 71)
>    (Simulator create-wireless-node line 71)
>    invoked from within
> "_o3 create-wireless-node"
>    ("eval" body line 1)
>    invoked from within
其实从2.26到2.29有许多功能又被加入,所以make会不过是正常的。只要把相对应的功能加入就ok. 以例子来说 mac/wireless-phy.cc 这个档案在2.26和2.29就不同,需要在make的時候,得知哪些档案error,把一些东西修改增加,make应该就能成功。

http://140.116.72.80/~smallko/ns2/mflood.htm分析了MFlood的代码修改,也比较详细。

posted on 2011-09-25 20:53  心月  阅读(586)  评论(0编辑  收藏  举报