[ZZ]OPNET的ODB调试

 

原文链接:http://blog.163.com/zhoumhan_0351/blog/static/399542272009826105222389/

1)基本概念

日志文件:仿真日志(DES logDiscrete Event Simulation log)和错误日志(Error log)。它的内容是在仿真过程中由进程调用OPNET 函数op_prg_log_handle_create ()op_prg_log_entry_write ()写入的。 Help 菜单下可以打开错误日志文件。错误日志文件以文本方式保存为<home>/op_admin/err_log,除了在菜单中打开也可以在OPNET 控制台(console)窗口输入op_vuerr 命令查看。 它包含了函数调用堆栈信息,我们可以从函数阶层性的调用关系中精确定位出错位置。

在编写函数时必须使用FINfunction begin)、FOUTfunction out)、FRETfunction return)等界定函数范围的标识符,而且必须使它们配对。编写程序时切记使FIN FOUT/FRET 配对。要产生ODB 调试信息,必须将仿真核心类型设定为development,优化的仿真核心optimized)为了加快仿真速度不产生ODB 调试信息。之后我们还需要在仿真属性中包含debug 环境变量。

       ODB 为控制和管理仿真行为提供一个交互式环境。ODB 支持断点(Breakpoint)定义,跟踪并显示仿真诊断信息。ODB 功能的实现有赖于进程模型中编写相应的程序支持,作为ODB 指令激活调试状态(breakpointtrace action)的依据,可以在ODB 窗口中输入help<参数:allbasicactioneventmemeorymiscobjectpacketprocessscriptingstoptrace>查看感兴趣的指令。

       ODB常用的指令分为basiceventobjectpacketstoptraceprocess几类。Basic

指令主要包含了一些基本的操作;Event类指令主要针对事件进行操作;Object类指令主要

针对各类对象(如节点,信道等)进行操作。Packet类指令处理所有与包相关的操作。

   

指令类型

指令名称

功能描述

Basic

tstop

为与特定时间最接近的事件设置断点

 

cont

继续事件运行直至下一个断点

 

next

执行下面几个事件

 

quit

退出程序

 

status

显示用户当前所设的断点,跟踪信息。

 

mstop

为特定进程模块设置断点

 

delstop

取消断点设置

 

Event

evprint

打印事件信息

 

evstop

在某个事件处设置断点

Object

attrget

获取某类的属性值

 

attrprint

打印目标的属性信息

 

attrset

设置目标的属性值

 

objassoc

打印与目标关联的信息

 

objid

获取目标的id

 

objpkmap

打印由指定目标所拥有的包的列表

 

objprint

打印目标的信息

 

objmap

打印所指定类型的目标列表

Packet

iciprint_pk

打印与包关联的ici信息

 

pkmap

打印指定的包的列表

 

pkstop

为指定的包设置断点

 

pttrace

跟踪所指定的包树

 

pktrace

跟踪所指定的包

 

protrace

为目标进程调用的核心函数设置跟踪

Trace

fulltrace

显示所有事件调用函数的情况

 

ltrace

激活对某个标签的跟踪

 

mtrace

针对某个指定模块,显示调用该模块所执行的程序

 

deltrace

取消对某个标签的跟踪

Process

promap

打印进程模块当前包含的进程信息

 

prodiag

执行隶属于某进程诊断块中的程序

 

proldiag

将诊断块中的标签激活,并执行诊断块中的程序

 

prolstop

设置标记断点

Diagnostic Blocks

proldiag

执行目标进程的诊断区程序

proldiag 带的参数有个,分别是进程ID 和标签(label)。它的效果等同于3条指令的叠加,首先ltrace 激活标签;然后prodiag 执行进程诊断块中的程序,并且打印标签被激活程序段的信息;最后,在执行完程序后deltrace 取消对标签的跟踪。

         deltrace 取消对某个标签的跟踪,与激活标签不同的是,它带的参数为trace_id而不是标签本身,但是trace_id 是系统分配的,不为我们所知,需要通过输入status 指令查看。

     2)针对结构错误(Structural Error)的ODB 调试实例

 

 [ZZ]OPNET的ODB调试_第1张图片

我们得知是第13 个事件出错

我们让仿真停止在第13 个事件执行之前,如下所示,在事件栏中我们看到当前中断类型为流中断,另外还有两个ID 号,其中execution ID 为当前事件IDschedule ID 标明当前事件处在仿真核心事件列表中的位置,这两个值可能不相同,因为随着事件的增加和消减,仿真核心列表是不断变化的。Source 指明了当前中断源,例如这里表明中断是由全球网top下的pksw1 子网下的node_0 节点下的src 进程模块在执行事件时发出来的。Data 指明了与当前中断相关的信息,这里表明封包是从号流端口接收来的,封包的ID 0Module指明当前中断的接收方top.pksw1.node_0.procprocessor)指明了物件的阶层关系和类型,OPNET 中最高层物件永远为top,代表全球网。

接着将执行第13 个事件,为了观察间中执行的代码,我们启动完全跟踪(fulltrace),之后输入status 命令就可以查看已设定的中断和跟 

踪有哪些。

[ZZ]OPNET的ODB调试_第2张图片

 

 

 

[ZZ]OPNET的ODB调试_第3张图片       

         接下来输入next 命令,让仿真执行下一个事件。从进程信息栏中我们可以看出当前进程(Invoking process)的ID 号为1,进程模型的名称为pksw_nd_proc。进程收到中断后将执行红色idle状态的窗口执行代码(exit executives),首先判断中断的类型为流中断,接着获取流中断索引号,其值为1。执行完之后满足条件SRC_ARRVL,从idle 状态再次转移到idle 状态,同时执行条件子程序xmt(),间中试图从号流索引的包流中获取封包,这时我们已经看出一些端倪,应该是从号流索引收包才对,果然指示包流中并没有数据包(strm.is empty),接着出现封包指针为空的错误提示,因此op_pk_nfd_set_int32 代码肯定不能正常运行。到这里我们找到了错误所在,只要把op_pk_get(0)改为op_pk_get(1)就行了。     

注意到最后两行的提示Press (ENTER) to continue。这是在edit->preference 中,console_exit_pause设定为TRUE 带来的结果。

2)针对逻辑错误的ODB 调试实例

例如某个端口正常情况下应该收到数据包,吞吐量却为零。

我们通过pktrace 命令启动对Packet ID 的封包的跟踪,pktrace 跟踪有关包的所有执行语句,直至包被销毁。在新版的OPNET 中支持对包设置断点,任何涉及到处理封包的事件到达时仿真都会停下来,如下图所示,要推进事件必须再次输入继续仿真的命令(cont 或者next),这样让我们清晰查看包在每个事件中的行为。

 

 

下面我们再次输入cont 命令,包被top.pksw1.node_1.src 进程模块创建,接着被

top.pksw1.node_1.proc 进程接收并将其dest_address 域设定为1,如下图方框所示,之后被传输到底层。

 

    接着我们再连续输入cont 命令,直到包被交换机节点进程(top.pksw1.hub.hub)接收,发现包的dest_address 被修改为0,如图所示。我们仔细想一下交换机应该取出包的目的地址,根据目的地址再选择正确的路由,而不是去重新设置,这时我们已经找到了这个逻辑上的错误,只要将op_pk_nfd_set_int32 改为op_pk_nfd_get_int32 问题就解决了。

 

 

3)针对进程模块的ODB 调试

由于进程是实现整个仿真的基础,因此针对进程的调试是ODB 调试的主要内容,主要包括四个部分,分别是定位进程、控制进程、跟踪进程及显示进程状态。

1定位进程

11promap <Objid>显示指定进程模块包含的所有进程的Process ID

12promap all 显示所有仿真中存在的进程Process ID,如图所示。

 

 [ZZ]OPNET的ODB调试_第4张图片

     进程标记用来更直观地区别同种类型进程(父进程产生多个进程,这些进程

是由同一个进程模型派生而来的),使用这种方法必须在进程模块中通过

op_pro_tag_set(pro_handle,tag_string)来设置进程标记。

    2控制进程

ODB 调试时输入指令prostop <proc_id>为进程调用设置断点。无论什么中断,只要调

用该进程,仿真都会暂时中断。首先在进程模型中通过op_prg_odb_bkpt(label)为指定位置设置断点,这个断点以标签(label)标识,ODB 调试过程中如果通过prolstop <proc_id> <label>激活了该断点标签,则仿真会在被设置标签的位置中断。

3跟踪进程

31protrace <proc_id>跟踪并显示调用指定进程的信息。

32ltrace <label>是最实用的调试指令,例如如果想找到程序中的逻辑错误,可以在可疑的程序段中加入这样一个语句。

if (op_prg_odb_ltrace_active("label")==OPC_TRUE){ printf(...)}

printf 打印需要观察的变量,在ODB 中激活标签就可以看到仿真中这些变化的情况。

33proltrace <proc_id> <label>显示指定进程中设置过某个标签的位置所对应的信息。

4显示进程状态

41)在进程的诊断块(Diagnostic block)中编写与调试相关的程序后,ODB 调试时

就能通过prodiag <proc_id>执行诊断块对应的程序,从而显示调试信息。

42proldiag <proc_id> <label>指令相当于prodiag <proc_id>ltrace <label>的叠加。

    ODB>objmap proc dp

查看进程对象的信息,dp 为进程的名字。

ODB> promap 2

查看进程模块当前被激活的进程信息,其中Objid

ODB> prostop 0

为进程设置断点,其中process id

ODB> protrace 0

激活进程跟踪信息显示其中process id

ODB> status

显示指令状态。

ODB> cont,继续执行事件直至仿真运行到断点位置。

ODB> next,执行下一个事件。

子进程dp_child 中的有设置进程标记的语句:sprinf(tag_string,"DynProc Child (stream %d)", op_intrpt_strm());

根据包流的输入端口索引号制定进程标记tag_string

op_pro_tag_set(op_pro_self(),tag_string);

为进程自身设置标签。

ODB> delstop all

ODB> deltrace all

ODB> status,再次显示指令状态,发现断点已经被取消

ODB> prolstop 6 "dynproc_50"

这时激活进程的断点标签,

当执行到进程中的op_prg_odb_bkpt("dynproc_50")语句时程序中止运行。

ODB> prodiag 6,运行进程诊断块的代码

 

你可能感兴趣的:(function,object,String,basic,action,scripting)