2010-5-26
今天中午平台停止了。停在了hotfox输出日志的地方。当时的调用栈为:
MSVCRTD! 1020b1f3()
MSVCRTD! 1021170a()
ACED! 00548f29()
ACED! 005273b2()
ACED! 005255c0()
HTX_Native_Logger::handle_message_block(ACE_Message_Block * 0x1bd1f160) line 325 + 51 bytes
HTX_Task_Base::svc() line 103 + 17 bytes
ACED! 00585301()
ACED! 00585ab7()
ACED! 005859e4()
ACED! 004fa836()
MSVCRTD! 1020c323()
KERNEL32! 7c824829()
handle_message_block是调用了ace的log函数。代码如下:
log_.log_->log(MsgTypeMap[sev-1].priority_,item->msg.c_str());
log函数是个变参函数。item->msg的字符串值如下:
+ item->msg {0x1bd1fbb1 "[2010-05-26 11:23:12:859](线程7268)|sk |47?赋iY绉%afJ韑呦??o殚? |"}
这个自符串里面有一个特殊的子串"%a".
ACE对%a的解释是:Abort System。最终会调用ACE_OS::abort();退出系统,造成系统崩溃。
标准c库的printf对%a的输出是a。
还有很多类似的特殊字串,如"%r",这样的字串传入到ACE的log函数,则都会引起程序崩溃。在测试环境下很容易验证这点。
这个字符串的产生是由于501(本地服务器上线)的应答包中的sk(会话密钥)造成的。sk的生成规则是从以下字符中随机挑选。
"0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIGKLMNOPQRSTUVWXYZ~`!@#$%^&*()_+-=.,;'"
很有可能挑选出%a或者其他的串出来。
另外,挑选出来的字符串,通过本地服务器的公钥加密,加密后的内容也有可能造成出现%a或者其他可能影响日志输出的串。
hotfox的一个配置项<debug>true/false</debug>控制umx包是否打印。而2.5平台恰好又配置了输出,所以就造成了崩溃。
该代码在2.4就已经存在了。为什么2.4没有出现这个问题?远控2.4平台,发现hotfox的配置文件里面的配置项
<debug>false</debug>是关的。所以2.4的平台不会因此造成崩溃。
中午,临时将hotfox的output代码注释(应该是修改hotfox的配置即可的)。于12:10分重起平台。
后来,发现还有一处没有改,所以,索性把hotfox的配置修改,
另外,由于debug选项控制了消息处理的耗时日志。所以,把消息耗时的日志输出的开关去掉了(便于追查501超时问题)。
19:00重启平台。