1 现象:问题描述
启动agtman后,执行setagt v无法显示VPN业务的vpnagent子进程的版本号,只能显示agtman进程的版本号,如下:
/home/hyvpn>setagt v
=============== Version Information ===============
agtman : WINV200R003 V3.2D902
vpnagent :
===================================================
但是,使用setagt对vpnagent进程设置调试日志标记,又都能得到响应。
2 关键过程:根本原因分析
用ipcs -b查看系统共享内存并显示其大小,发现拉起vpnagent(VPN业务代理进程)之后,共享内存大小为6668字节。但同样的agtman版本,在拉起iuseragt(预付费IUSER业务代理进程)时,共享内存大小为6628字节;
再尝试配置agtman不拉起vpnagent,只运行agtman,共享内存大小也为6628。初步分析,应当是vpnagent在创建共享内存时指定的共享内存size错误。
共享内存上是一个数据结构,如下:
// share memory mapped structed
struct structOfDebug
{
char m_bDebugFlags[MaxSerNum][MaxAPNum];
char m_bAgtmanDebugFlag;
…
int m_bTraceMsisdn;
char m_szTraceMsisdn[MAX_TRACE_MSISDN][MAX_LEN_MSISDN];
debugSession m_debugSession; //调试会话
//agtman版本号
char m_szAgtmanVersion[VersionLength+1];
//子进程版本号
char m_szAgentVersion[MaxSerNum][VersionLength+1];
};
共享内存大小定义为:
#define DEBUG_SHMSIZE (sizeof(structOfDebug))
将vpnagent代码与iuseragt/agtman代码逐一对比,两者结构定义完全一致;比较宏定义后,发现两者的MAX_LEN_MSISDN宏定义不一致,iuseragt/agtman中都定义为16,但vpnagent中定义为20。这就是共享内存大小不一致的根本原因。由于两者在MAX_LEN_MSISDN上定义不同,导致m_szTraceMsisdn之后定义的数据成员位置不一致,vpnagent虽然向共享内存中写入了版本号,但却无法被setagt正确访问到
3 结论:解决方案及效果
将vpnagent中的MAX_LEN_MSISDN也定义为16,即解决问题。
4 经验总结:预防措施和规范建议
多个进程共享的数据需要保证数据定义的一致性。对于同一个项目的多个进程,由于使用同一个共享内存结构定义文件,一般不会出现此问题。当多个项目开发的程序需要使用共享内存交互时,由于代码各自维护,共享内存结构的定义需要谨慎。即使是拷贝的共享内存结构定义,也要注意定义结构使用到的宏定义是否一致。通过共享内存通信是进程间通信的一种方式,进程间通信时都需要保证通信双方消息定义的一致性。
5 备注
6 考核点
不同进程之间使用的共享内存结构定义需要一致。
7 试题
1、 关于进程之间使用的共享内存数据结构定义说法正确的是:A、B
(A) 不同进程之间使用的共享内存数据结构,其定义最好使用同一个头文件,结构定义中用到的宏也在此文件中定义。
(B) 多个项目维护的进程需要使用共享内存定义,如果不能引用同一个结构定义文件。需要保证结构定义的一致性,且数据结构使用的宏定义也要一致。
(C) 多个进程间使用共享内存通信时,只要将其他进程定义的共享内存结构直接拷贝过来就可以了,这样就可以保证结构定义一致了。
(D) 以上说法都正确
阅读(570) | 评论(0) | 转发(0) |