最近Linux下我的DB server遇到一诡异问题。日志文件中毫无来由多了N多query string的内容,经查看似乎每条查询都被记录到了日志中,压力测试下几分钟就能生成N个G的内容。搜索了无数遍代码,确认没有写过这部分日志。Windows版本下却没有发现这个问题。
bp fwrite,无果;bp write,无果……仔细查看代码,往文件中写入完整查询语句的地方只可能有一处。字符串处理的时候为了计算sprintf需要的缓冲区长度,在MString类中本来想通过fopen打开/dev/null文件,并调用vfprintf来计算了格式化输出的长度,但是手贱写成了vprintf,结果本不应被保存下来的中间数据被写到stdout。而Windows下面由于CRT直接提供了_vscprintf函数,没有自己做处理,所以没有发现问题。
改掉守护进程的初始化代码,照抄了UNIX环境高级编程中的那部分处理代码,关闭当前所有FD,并open /dev/null再dup两次占掉0,1,2三个fd,将标准输入输入重定向过去。问题解决。
之前的daemon代码抄袭了某垃圾代码,close掉了三个标准fd,造成后面我自己打开日志文件fd被分配到1。而vfprintf输出到stdout,结果本来应该输出到/dev/null中的内容被输出到这个日志文件中。
这个问题有点巧合,我自己的BUG加上UNIX环境下的一些遗留的东西造成了诡异问题。稍微记录一下,写daemon的时候一定要记得处理三个标准fd,顺便吐槽一下UNIX的这些古董设计……