基于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的代码修改,也比较详细。