一个fread失败时处理不当引发的crash
2013-04-03 16:42
1266 查看
最近发现一次web机上的agent程序crash了,通过对日志分析,发现是代码中对fread使用理解有误导致。 agent程序的作用是实时收集web机上的某消息文件,然后转发到消息服务器上。在web请求中业务如果需要发送消息,则会将消息写入消息文件中,消息文件的格式为msg1_len:msg1_data:msg2_len:msg2_data... //该函数每次从文件中取一条消息 #define MESSAGE_SIZE_LEN 4 bool get_one_msg(FILE *fp, char **msg_buf, uint32_t *msg_buf_len) { uint32_t msg_len; if (1 != fread(&msg_len, sizeof(msg_len), 1, fp)) { return false; } msg_len = ntohl(msg_len); //msg_len in network byte order char *msg_buf = (char *)malloc(msg_len + MESSAGE_SIZE_LEN); if (p == NULL) { return false; } memcpy(*msg_buf, &net_msg_len, MESSAGESET_SIZE_LEN); if (1 != fread(*msg_buf + MESSAGE_SIZE_LEN, msg_len, 1, fp)) { free(*msg_buf); *msg_buf = NULL; return false; } *msg_buf_len = msg_len + MESSAGE_SIZE_LEN; return true; } 在上面的代码中,如果另外一个进程正在写消息文件,但只写了消息长度(假定消息为200字节),消息内容还未写完,那么此时调用get_one_msg函数时,会从文件中读取了该消息的长度200字节。接着在执行第二个fread读内容时读取失败,fread返回为0(也许读了20字节就到了文件结尾),但当前文件的偏移量已向前移动。 当下次调用该函数获取消息时,文件偏移量已不在正确的消息边界上了,此时读出的msg_len为4294967295。 由于没有msg_len进行判断,在malloc时,msg_len + 4,实际结果为3。则在memcpy或者每二个fread时就出现了crash 在这优代码中至少有两个地方处理不当: 1 fread失败后,要么把文件offset向前移到之前正确的位置,或者将当前的已读的buffer保存,下次再接着去读余下的。 2 未对msg_len进行检测
相关文章推荐
- VS在连接期间的一个错误的处理:转换到 COFF 期间失败: 文件无效或损坏
- LINUX驱动注册过程失败处理不当引起的恶果
- 一个crash引发对版本管理备注重要性的思考
- [负载均衡案例分享系列] 一个由负载均衡使用模式导致间断访问失败问题的处理
- win10系统 L2TP连接尝试失败:ERROR因为安全层在初始化与远程计算机的协商时遇到了一个处理错误
- 一个组件注册失败引发的惨案
- LINUX驱动注册过程失败处理不当引起的恶果
- 多个进程同时等待网络的连接事件,当这个事件发生时,这些进程被同时唤醒,我们知道进程被唤醒,需要进行内核重新调度,这样每个进程同时去响应这一个事件,而最终只有一个进程能处理事件成功,其他的进程在处理该事件失败后重新休眠或其他。
- LINUX驱动注册过程失败处理不当引起的恶果
- L2TP连接尝试失败,因为安全层在初始化与远程计算机的协商时遇到了一个处理错误
- break使用不当引发的一个“血案”
- 学习 MacCMS 6.x referer处理不当引发注射
- 控件system.windows.forms.Label在设计器中引发了一个未经处理的异常,已被禁用
- 一些Windows API导致的Crash以及使用问题总结(API的AV失败,可以用try catch捕捉后处理)
- 静态智能指针变量调用DLL引发的一个CRASH给的启示
- 一个长事务引起的血案——Informix 长事务回滚失败引起的阻塞故障处理
- win10系统 L2TP连接尝试失败:ERROR因为安全层在初始化与远程计算机的协商时遇到了一个处理错误
- 处理一个傻子引发得问题