文章来自:[FGL] FGLSQLDEBUG與FGLGUIDEBUG,除錯的好幫手 – iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天 (ithome.com.tw)
[day29] FGLSQLDEBUG与FGLGUIDEBUG,除错的好帮手
再厉害的高手也是要靠着不断琢磨自己的 code 才能减少错误的发生。错误不只是低级错误,更多的是思虑上差异造成操作时的认知不同。
Genero 的 DEBUG除错工具位于 GeneroStudio 套件内。但本章节谈论一下不使用除错器怎么判断大概错误的地方。
Genero编译后形成 p-code,必须透过DVM-fglrun 来执行。因此可以透过外界的干预,例如调整『环境变量』来达到窥探程序执行过程的需求。
fglrun执行的过程中可透过许多环境变量来进行操作干预。例如 FGLGUI(设定客户端样态)、FGLSERVER(设定客户IP)…等,可以查阅 https://4js.com/online_documentation/fjs-fgl-manual-html/#fgl-topics/c_fgl_EnvVariables_fgl.html
以下先讨论对于除错相关的 FGLSQLDEBUG 与 FGLGUIDEBUG
FGLSQLDEBUG
默认值 0 可异动范围
- Genero2.50以前: 3 (显示严重错误讯息) 6 (显示重要讯息) 9 (显示细节讯息)
- Genero3.00以后: 1 (显示严重错误讯息) 2 (显示重要讯息) 3 (显示细节讯息) 3以上都一样
也就是说,我们可以透过调整FGLSQLDEBUG的设定,在程序执行过程中查看讯息
export FGLSQLDEBUG=3
以 Genero 3.20来说,设定后再操作程序,就可以看到『**DVM-fglrun 与 ODI 及数据库讯息交换的过程 **』,包含 4GL内组装的指令样式、经过 ODI 转换后的样式 (因为程序必须以 INFORMIX兼容语法来写,所以ODI会有一层转换) ,ODI送到数据库端最后的样式,以及数据库执行结果和回填数据。
例如:
SQL: CONNECT TO "ds+driver='dbmoraB2x',source='t30dev'" AS "ds" USER "***" USING "***"
| 4gl source : lib_cl_db.4gl line=594 #程序出现的位置
| loading driver : [/u1/gst/3.20.09/fgl32013/dbdrivers/dbmora_11] #ODI
| db driver type : ora
| ora.c:00859(3) : Connection parameters for 'ds':
| ora.c:00860(3) : Oracle server = 't30dev' #ORACLE或其他数据库联机讯息
| ora.c:00861(3) : Schema = ''
| ora.c:00862(3) : User name = '*'
| ora.c:00863(3) : Password = '*'
SQL: SELECT userenv('SESSIONID') FROM dual #SQL语句
| 4gl source : lib_cl_db.4gl line=796 #code出处
| ../ODI_common.h:00795(3) : adaptStatement: stmt type = 1 #ODI转换
| ../ODI_common.h:00800(3) : adaptStatement: ifxemul = 1
| ora.c:01734(3) : Nat stmt1 = select userenv('SESSIONID') from dual #转换成果
| ora.c:01755(3) : Preparing SQL (0x278e540): [select userenv('SESSIONID') from dual]
| ora.c:01686(3) : Prefetch rows = 1
| ora.c:01693(3) : Prefetch memory = 0
| ora.c:03227(3) : Executing SQL (0x278e540)
| sqlcode : 0 #执行状态
| curr driver : ident='dbmora_11'
| curr connection : ident='ds' (dbspec=[ds+driver='dbmoraB2x',source='t30dev'])
| into: 1
| t: DECIMAL(20,0) f:04 v:"35192778" #执行结果
| Execution time : 0 00:00:00.00173 #花费时间
从上面范例可以清楚理解,透过 FGLSQLDEBUG 能够探知所有的 SQL指令现在运行状态。很有可能实际出错的时候,发生的成因其实是前一个,或前方很远的段落就已经发生选择错误:若用 DEBUG 查询问题时不会很容易抓出实际状况,因此透过 FGLSQLDEBUG 的输出查询会必较容易理解成因。
由于 FGLSQLDEBUG 的讯息量多,因此通常以倒出为档案的方式进行查看,例如透过重导指令:
export FGLSQLDEBUG=3; $FGLRUN test-app > $TEMPDIR/debug.log 2>&1
将讯息存放到 debug.log 再慢慢查阅即可。
r.h/FGLSQLDEBUG log viewer
程序若能正常运行出结果,接下来需要考虑的就会是执行效能。应该从上面的范例,可以看出FGLSQLDEBUG=3 的时候有包含『SQL运行时间』。因此,不管是 FourJs 或以 FGL 为底层工具开发出的平台,自然都想利用这个数值来对效能旁敲侧击。因此有不同对应的工具,可进行操作
在T100的环境中,可使用 r.h 来执行作业。执行出的 FGLSQLDEBUG log 资料会被收集、统计。将一致的数值收集起来进行平均,就可以取出** 『总执行次数、平均运行时间』 ** 两个指针,接下来评估数值是否合理,要不要透过调整进行优化 (如适当的增加 index 或变换低成本(lower cost)的语法) 就会有比较清晰的答案。
在 FourJs 也在 github 中提供类似工具
FGLSQLDEBUG在处理上更为细致 (因为是FourJS自己的),能够结合 FGLSOURCEPATH(原始码所在路径) 搭配分析,因此还可以依照 42m module 来进行比序与问题确认。
不管透过 r.h 或 FGLSQLDEBUG log viewer ,都能对开发人理解:程序被操作时的效能,有更清楚的感知。
FGLGUIDEBUG
上方的 FGLSQLDEBUG 在探索 DVM与数据库的关系。而操作的时候,DVM对上客户端软件 (如GDC/GBC/GMA…) 会出问题的,大抵就在网络上了。『封包是否正常的、循序的派送,两端是否保持着联机,License的状况是否支持继续执行,』
这些,在前面的篇章中,曾经提到,都是靠着 AUI TREE变动的讯息封包传递而得来。那么要除错,就是要观测 DVM是否正确送出封包、客户端是否正确得到封包。
在 [GDC] 基本的概念与操作中能理解到从 Monitor中查看的方法。下面范例看一下 DVM-fglrun 看的方法:
默认值 0 可异动范围 1 (显示传送内容)
export FGLGUIDEBUG=1
基本上,下列的封包讯息并不容易阅读,但是可以拿来查关键词
*** uic_FT_ackFileTransfer.972: id=-1 localName=!!__cached__!!
*** uic_read.578: returns:0
*** uic_read.568: …
*** uic_readMessage.417: …
*** uic_readMessage.439: length=138 comp_length=138
*** uic_processMessage.458: FILE_TRANSFER
*** uic_FT_processMessage.1209: id=-2 mtype=GET_REQ
*** uic_FT_processGet.1161: requestedName=16/worksheethidden.png realName=/u1/t30dev/res/img/ui/16/worksheethidden.png
例如可以探察到资源到底是否送出对的,也可以和 GDC 做比对,以厘清是否在封包的传递上出问题。
善用上述两个变量,可以不用每次都 step by step的操作除错器,对于整体环境的掌控能力会较好,可以多加习练。