使用ApDiag工具进行WinCC脚本诊断

n
1使用apdiag工具进行wincc脚本诊断概述
wincc 的c脚本功能非常强大,可以提供较高的自由度。 但是,不恰当地组态和使用脚本功能会显著降低系统性能,也可能导致系统崩溃。本文所讨论的脚本问题主要为c脚本的阻塞和挂起问题,即如果在过小的周期内正在运行的动作太多或者动作的执行时间过长(要处理的动作将越聚越多),或者动作已被挂起(休眠、循环、输出对话框、等待另一个应用程序的响应…),则等待队列可能会溢出。所有其它动作均将积聚在等待队列中,不能及时进行处理。
针对以上问题,可以使用 apdiag 诊断工具进行分析和诊断,apdiag 工具主要可以提供以下功能:n
1. 监控当前请求队列中待处理的动作数。
2. 判断脚本是否发生阻塞。
3. 帮助定位发生阻塞的动作。
4. 定位导致脚本阻塞的函数。
5. 启动将重要脚本诊断值保存在变量中的功能。
6. 设置诊断信息输出到窗口、文件或被删除。
……
诊断工具apdiag.exe 位于安装目录的“…siemenswinccutools”文件夹中,双击即可启动该应用程序。关于 apdiag 的详细使用方法,请参见帮助文档目录中的“wincc 诊断”一章。
另外,关于wincc脚本的基本诊断方法,包括“gsc诊断窗口”和“gsc运行系统窗口”(在对象选项板中,选择“智能对象应用程序窗口”,在“窗口内容”对话框中选择“全局脚本”,在“模板”对话框中,选择“gsc 诊断”或“gsc 运行系统”即可)的使用,请参见视频“v0742 wincc跟我做:wincc 脚本调试与诊断方法”,链接如下:
http://www.ad.siemens.com.cn/service/elearning/cn/course.aspx?courseid=859
2 apdiag 诊断工具提供的主要功能和使用方法介绍
以下介绍了6个主要的功能和相应的使用方法。注意,要及时关闭不用的诊断功能,以避免在运行系统运行期间降低系统性能。n
2.1监控当前请求队列中待处理的动作数
功能描述:根据当前请求队列中待处理动作数的变化趋势,判断脚本是否发生阻塞。
使用方法:
首先,在画面上放置“gsc 诊断窗口”,运行wincc时,打开apdiag 工具,选择“info”菜单下的“count of actions in requestqueue”菜单项,将输出当前请求队列中待处理的动作数,其中包括来自全局脚本的作业、来自画面的周期性作业以及来自画面的事件控制性作业。例如,在“gsc 诊断窗口”中输出如下图1所示的内容,红色框中的内容代表来自全局脚本作业的当前请求队列中待处理的动作数为8个。n
图 1 使用“count of actions in requestqueue”的诊断输出n
运行一段时间后,再次点击“count of actions in requestqueue”菜单项,红色框所示的待处理的动作数变为59个,如图2所示。多次操作后,如果待处理的动作数有不断上涨的趋势,则说明全局脚本发生了阻塞。n
图 2再次使用“count of actions in requestqueue”的诊断输出n
此外,在“info”菜单中,还提供了与系统有关的其它诊断信息,如图3所示。在选择相应菜单项后,均将输出诊断信息到“gsc 诊断窗口”,详细内容请参见帮助文档。n
图 3 “info”菜单中菜单项n
2.2判断脚本是否发生阻塞
功能描述:设置“扫描速率”和“梯度”,可以监视请求队列的增长。
使用方法:
打开“diagnostics”菜单下的“概要文件”(profile) 菜单项。组态“check the request/actionqueues”,可对缓慢增加的等待队列进行检测。“扫描速率” (scanrate) 值可用于定义应在增加了多少个新作业后检查队列的长度。 如果队列的增长超出在“梯度”(gradient) 中所定义的值,则将以 “printf ”的形式输出警告。n
图 4 “扫描速率”和“梯度” 的组态n
如上图4所示,如果输入“扫描速率”(scanrate) 为“100”且“梯度”(gradient) 为“30”,则每放置 100 个新条目(动作)到队列中,即会检查队列的增长是否超过 30 个条目(100 个新作业中得到处理的少于 70 个)。 如果情况如此,则以 “printf() ”的形式输出以下诊断信息,如图5所示。n
图 5 组态“扫描速率”和“梯度”输出的诊断信息n
需要注意的是,除了全局动作之外,画面中周期执行的脚本也在检查的范围内。n
2.3帮助定位发生阻塞的动作
功能描述:设置动作运行时间的限值,可测量运行时间过长的动作的实际运行时间,帮助定位发生阻塞的动作。
使用方法:
打开“diagnostics”菜单下的“概要文件”(profile) 菜单项。激活“检查运行需要超过 xx 毫秒的动作”(check which action need more than xx msec) 复选框,则将输出运行时间大于规定时间的所有动作的实际运行时间。n
图 6 组态“check which action need more than xx msec”n
如上图6所示,将xx毫秒设置成2000毫秒,如果有动作执行超出2000毫秒,可以在图7的“gsc诊断窗口”中找到如下的输出:n
图 7 组态“检查运行需要超过 xx 毫秒的动作”的输出诊断信息n
从上图中红色线标注的信息可以看出,有动作执行超出设定的毫秒数。由“szfunctionname:@c”,在“gsc 运行系统窗口”可以查到“@c” 所对应的动作名称。假设该动作设置的触发周期为2秒钟,但是由上图实际执行时间为4999.6毫秒,则有可能由于该动作执行时间过长,导致整个脚本队列的堵塞,需要检查该动作的代码。注意,如果该动作发生挂起(停在某代码处,无法继续执行),则无法计算该动作执行的时间,此时没有以上的输出。n
2.4定位导致脚本阻塞的函数
功能描述:使用正在运行动作的“调用堆栈”信息,定位导致脚本阻塞的函数。
使用方法:
使用“info”菜单下的菜单命令“第一个动作”(firstaction) ,可以得到正在运行的动作的相关信息。该命令可以将当前正在运行的动作(如果脚本发生阻塞时,很有可能为正在发生阻塞的动作,该动作阻塞了其它需要处理的动作),以及动作的调用堆栈信息输出到文本文件中。如果正在执行的动作很多,这将有助于快速定位到发生阻塞的动作,并从“调用堆栈”信息中查出该动作中究竟是哪个函数发生了阻塞或挂起。n
图 8使用“firstaction”输出的正在运行动作的信息n
上图8是使用“firstaction”输出的正在运行动作的信息和调用堆栈信息的示例。首先介绍一下什么叫调用堆栈:假设有几个函数,分别是function1、function2和function3,且function1调用function2,function2调用function3。在function3运行过程中,可以从线程当前堆栈中了解到调用它的那几个函数的名称。从函数的调用顺序关系看,function3、function2、function1呈现出一种“堆栈”的特征,最后被调用的函数出现在最上方,因此称呼这种关系为调用堆栈(call stack)。
由上图所示的“szapplicationname:gsc_rt”判断输出的是某一全局动作的信息;由“szfunctionname:@1d5”,在“gsc 运行系统窗口”中可以查到“@1d5” 所对应的全局动作的名称;再仔细核对该全局动作的代码,从上述调用堆栈函数列表中就可以查找到该全局动作代码中使用的函数msrtgetmsgquit(这是一个odk函数),可能由于该函数执行所需的时间较长,或者发生了阻塞或挂起,因此使用“firstaction”功能时,打印到该函数调用堆栈信息的概率就比较大。n
2.5启动将重要脚本诊断值保存在变量中的功能
功能描述:可以启动将重要脚本诊断值保存在变量中的功能。
使用方法:
在 wincc 项目的创建期间会生成与脚本相关的诊断变量,如下表1所示。这些诊断变量默认情况下不保存诊断值。n
@script_count_tags此变量包含当前通过脚本请求的变量数。@script_count_request_in_queues此变量包含当前的作业数。@script_count_actions_in_queues此变量包含当前待处理的动作数。表 1 wincc脚本诊断变量列表n
使用菜单“诊断”(diagnostics) 中的“填充变量”(filltags) 可打开或关闭将重要脚本诊断值保存在上述变量中的功能,默认情况为关闭。n
图 9 “填充变量”对话框n
请注意,写入诊断值会产生额外的基本负载,因此该功能只应短时启动。n
2.6设置诊断信息输出到窗口、文件或被删除
功能描述:设置诊断信息输出到窗口、文件或被删除。
使用方法:
在“output”菜单中,使用菜单命令“输出到画面”(output on screen) 将打开一个诊断窗口,迄今所收集的跟踪条目将输出到如图10所示的窗口中。n
图 10 “诊断窗口”对话框n
菜单命令“输出到文件”(output to file) 可用于将迄今所收集的跟踪条目一次性存储到文本文件中。
使用菜单命令“复位缓冲区”(reset buffer) 将删除迄今所收集的跟踪条目。n
3使用apdiag诊断工具帮助快速定位阻塞脚本的实例
下面以一个简单的测试项目为例,介绍如何使用上述方法进行脚本的诊断,并快速定位到发生阻塞的脚本的函数名称。
首先创建一个测试项目(以wincc v7.0 sp2为例),在wincc的全局脚本中,创建一个c动作,设置该动作的触发周期为2秒钟,在该动作中加入sleep函数(延时5秒钟),模拟c脚本的阻塞现象,如下图11所示。
图 11 阻塞脚本代码示例
由于该脚本设定触发周期为2秒钟,即每隔2秒钟会将请求加入队列,但是实际执行脚本需要花费5秒钟的时间,因此脚本实际触发的周期为5秒钟左右执行一次,给用户的感觉是脚本执行变慢。随着时间的推移,就会导致请求队列中的动作数不断增多,将导致在几小时或几天之后出现出错消息“more than 10000 actions in work”。
如果客户在项目运行过程中,发现类似上述脚本阻塞的现象,可以使用apdiag工具,分步诊断上述问题,从而快速定位到阻塞脚本的函数名称。
步骤1:使用上述“功能1”介绍的“count of actions in requestqueue ”方法输出当前请求队列中待处理的动作数,先后使用两次,显示结果分别如“图 1”和“图 2”所示;或者使用“功能2”介绍的设置“扫描速率”和“梯度”方法监视请求队列的增长,输出结果如“图5”所示。上述两种方法均可以诊断出当前请求队列正在快速增长,说明脚本发生了阻塞。
步骤2:使用“功能3” 测量运行时间过长的动作的实际运行时间,从 “gsc 诊断窗口”中输出的信息(如“图7”所示)表明,某一 id (@c)的动作执行时间超出在 apdiag 工具中所组态的数值(2000毫秒),在“gsc运行系统窗口”中查询该 id 对应的全局动作名称为“trigger_sleep.pas”。由于该动作的设定触发周期为 2 秒,但是实际运行花费5秒左右,说明该脚本动作可能发生阻塞,影响了其它全局动作的执行。
步骤3:使用 “功能4” 定位导致脚本阻塞的函数,执行几次后,发现输出的调用堆栈诊断文件中均有近似如下的内容:
此外,也可以通过函数“messagebox(null,”world”,”hello”,mb_ok); ”模拟“挂起”动作(调用消息框的动作将不会继续执行,直到该消息框被关闭)。此时使用“firstaction”方法,同样可以找到导致挂起的脚本函数“messagebox”。
可见,综合利用 apdiag 的以上方法,对快速诊断脚本的阻塞或挂起问题很有帮助。关于 apdiag 工具的使用,需要在实际的复杂项目中多多实践、灵活应用。
关键词
wincc、c脚本、阻塞、挂起、apdiag、诊断