打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
How to read the error message in NS

When using NS, we usually meet some hurdles, luckily the error message can help us to find where the mistake is.

错误代码从错误发生时开始输出,然后返回上一级调用,上一级可能继续返回错误代码的相关信息,最典型的模式是

1 "eval $self create-wireless-node $args"          # 命令代码
  (procedure "_o3" line 23)                    # 命令所在行数
  (Simulator node line 23)                    # Simulator 实体的node函数体
    invoked from within                        #
5 "$ns_ node"                                # 调用代码

此5行大体意思是, 1行对应的命令是从句柄为 "_o3"的Simulator实体的函数 node  "函数定义"的第23行调用的

句柄说明
在每一个Simulator对应的模拟中"_o*"标示唯一的一个分裂类实体,也就是说,所有的分裂类实体都有自己的唯一标识详见《tclcl-1.19/tcl-object.tcl 代码分析 》

    对于下面错误代码中提到的几个句柄说明如下:
     _o3 是一个Simulator实例句柄, _o14是一个node实例句柄,_o17是一个agent实例句柄

错误例子:
INITIALIZE THE LIST xListHead

     (_o17 cmd line 1)
     invoked from within
"_o17 cmd port-dmux _o26"
    invoked from within
"catch "$self cmd $args" ret"
    invoked from within
"if [catch "$self cmd $args" ret] {
set cls [$self info class]
global errorInfo
10 set savedInfo $errorInfo
11 error "error when calling class $cls: $args" $..."
12     (procedure "_o17" line 2)
13     (SplitObject unknown line 2)
14     invoked from within
15 "$agent port-dmux $dmux_"
16     (procedure "_o14" line 11)
17     (Node/MobileNode add-target-rtagent line 11)
18     invoked from within
19 "$self add-target-rtagent $agent $port"
20     (procedure "_o14" line 23)
21     (Node/MobileNode add-target line 23)
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" ,计算行数不算注释,空格要算》
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)
30     invoked from within
31 "_o3 create-wireless-node"        // _o3 是Simulaor的一个实体句柄
32     ("eval" body line 1)
33     invoked from within
34 "eval $self create-wireless-node $args"     #$self = = "-o3"
35     (procedure "_o3" line 23)
36     (Simulator node line 23)
37     invoked from within
38 "$ns_ node"
39     ("for" body line 2)
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     }"
45     (file "mflood-3nodes.tcl" line 61)

错误分析过程(自底向上)
    其实tcl中的self 相当于 C++中的this指针,了解C++的肯定知道,this指针有一个运行时的问题,"this command"可能动态调用父类< 或者子类? > 的同名command,具体的分析采用从下向上方法,如果你很熟悉ns2机制,可以越过一些,具体的分析如下:
1.  41-44给出错误从脚本附近的代码,在一个for循环中, 38行说明"$ns_ node"是来自42行
当在tcl脚本里调用如下:
1 set  ns_  [new Simulator]
2 set  node_(0)  [$ns_ node]  ;#调用了Simulator instproc node 过程

//ns-2.31/tcl/lib/ns-lib.tcl 

Simulator instproc node args {            // args 为域参数
    $self instvar Node_ routingAgent_ wiredRouting_ satNodeType_
        if { [Simulator info vars EnableMcast_] != "" } {
                warn "Flag variable Simulator::EnableMcast_ discontinued.\n\t\
                      Use multicast methods as:\n\t\t\
                        % set ns \[new Simulator -multicast on]\n\t\t\
                        % \$ns multicast"
                $self multicast            #$self = = "-o3"
                Simulator unset EnableMcast_
        }
... ... ... ... ... ... ... ... ... ... ...
    if { [info exists routingAgent_] && ($routingAgent_ != "") } {
23        set node [eval $self create-wireless-node $args]     #$self = = "-o3"
    #使用eval 是从tcl脚本调用Otcl对象及函数 就是"_o3 create-wireless-node"
    ... ... ... ... ... ... ... ... ... ... ...
        }
        return $node            //出口之一
    }

    #分析一下下句语法 & Node_(*)是干什么用的?
    set node [eval new [Simulator set node_factory_] $args]
    set Node_([$node id]) $node
   
    #把节点加入到Simulator的C++空间的链表中
    $self add-node $node [$node id]

    #set the nodeid in c++ Node - ratul
    $node nodeid [$node id]       
    $node set ns_ $self                    //指向模拟器实例
    $self check-node-num
    return $node
}
34-37行可知,调用进入函数 $self create-wireless-node ,31-33指明了"_o3 create-wireless-node"     也就是下面函数,在此 _o3 是Simulaor的一个实体句柄
//ns-2.31/tcl/lib/ns-lib.tcl
Simulator instproc create-wireless-node args {
        //omit some code here... ... ... ... ... .. .... ... ... ... ... ... ... ... ...
        Simulator set IMEPFlag_ OFF

        # create node instance
        set node [eval $self create-node-instance $args]
       
        ... ... ... ... ... .. .... ... ... ... ... ... ... ... ...        //omit some code here

    # Attach agent
    if {$routingAgent_ != "DSR"} {
        $node attach $ragent [Node set rtagent_port_]
    }
    ... ... ... ... ... .. .... ... ... ... ... ... ... ... ...
   
    return $node
}
27 "$node attach $ragent [Node set rtagent_port_]"  此时 "$ node = = _o14"
28     (procedure "_o3" line 75)
29     (Simulator create-wireless-node line 75)
30     invoked from within
31 "_o3 create-wireless-node"   
3.  27-30 可知 $node attach $ragent [Node set rtagent_port_] 在上面函数的75行
//ns-2.31/tcl/lib/ns-node.tcl
Node instproc attach { agent { port "" } } {
    .......................................................
    $agent set agent_port_ $port
15    $self  add-target $agent  $port
}



23  "$self add-target $agent $port"   
24     (procedure "_o14" line 15)
25     (Node attach line 15)
26     invoked from within
27 "$node attach $ragent [Node set rtagent_port_]"
4.  23-25行 可知self add-target $agent $port 来自Node attach函数的15行

19-23行可知 动态转向了Node/MobileNode  <-o14> 的add-target,函数的23行,这里的node其实是一个移动节点Node/MobileNode 类型的,所以调用的是下面的函数
Node/MobileNode instproc add-target { agent port } {
    $self instvar dmux_ imep_ toraDebug_
    set ns [Simulator instance]
    set newapi [$ns imep-support]
    $agent set sport_ $port
    ... ... ... ... ...
    if { $port == [Node set rtagent_port_] } {           
        # Ad hoc routing agent setup needs special handling
23        $self add-target-rtagent $agent $port
        return
    }
    ... ... ... ... ...
    }

19 "$self add-target-rtagent $agent $port"
20     (procedure "_o14" line 23)
21     (Node/MobileNode add-target line 23)
22     invoked from within
23  "$self add-target $agent $port"
5. $self add-target-rtagent $agent $port
Node/MobileNode instproc add-target-rtagent { agent port } {
    $self instvar imep_ toraDebug_

    set ns [Simulator instance]
    set newapi [$ns imep-support]
    set namfp [$ns get-nam-traceall]

    set dmux_ [$self demux]
    set classifier_ [$self entry]

    # let the routing agent know about the port dmux
    $agent port-dmux $dmux_   
     ... ... ...省略一些代码 ... ... ...
}

15 "$agent port-dmux $dmux_"
16     (procedure "_o14" line 11)
17     (Node/MobileNode add-target-rtagent line 11)
18     invoked from within
19 "$self add-target-rtagent $agent $port"

       15-19可以知调用."$agent port-dmux $dmux_" 但是agent 没有函数port-dmux ,agent 的祖先也没有次函数,所以转到 ->  MFlood port-dmux $dmux_ 
但是MFlood也没有定义次函数,所以问题在这里,没有相应的处理代码,这里最主要的是要学会看代码。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
NS节点
科学网-段克松的博客-网络仿真利器NS-2无师自通七天速成系列Ⅳ:NS-2网络控件及其使用...
在NS2中添加路由协议2(整理版)
mysql mmm实现HA
NS2中仿真分析基于CSMA/CA的WLAN的捕获效应
凱旋,自信心。英文?
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服