免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2435 | 回复: 3
打印 上一主题 下一主题

[C] [zt]关于glibc memory corruption [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-09-22 16:55 |只看该作者 |倒序浏览
最近写的一个程序自从添加了以文件大小来自动生成新的日志文件大小就问题频发;
程序主要设计是这样的:
将接收到的请求消息,与要发送的回复消息通通COPY一份push到日志队列,然后再由日志线程进行全部信息的日志输出;

后来添加了以文件大小来自动生成新的日志文件后(红色部分)在高负荷运作测试下就出现如下问题:
1.不定时的内存错误;(这个让人头疼,服务程序直接挂掉)(有时候处理几万条消息,都没问题,有时候处理几百条就出错);
2.日志信息有丢失现象,就是两个相邻生成的日志文件存在丢失日志信息的现象,一丢就丢几百条;
3.生成的日志文件中存在大小为0的文件;

注:在未添加这个红色代码时,一切正常;


//从日志队列中取值,并输出日志
void LogEventsFunc( FILE *stream)
{

MGCMessageHead *LogEventsBuffer;
LogEventsBuffer=LogQueueCache.front();

int msgCount=0;
OTSGETAVAIBLEMONEYREQ MoneyReq;
OTSGETAVAIBLEMONEYRSP MoneyRsp;
OTSSENDCDRREQ CdrReq;
OTSSENDCDRRSP CdrRsp;

time_t rawtime;
struct tm*timeinfo;
rawtime=time(NULL);
timeinfo=localtime(&rawtime);
long long size;
size=ftell(stream);
if(size>DEFAULT_MAX_LOG_SIZE)
{
sprintf(log_file_name,"packet_log%d%d%d%d%d%d",timeinfo->tm_year+1900,timeinfo->tm_mon+1,timeinfo->tm_mday,timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec);
fflush(stream);
fclose(stream);
stream=NULL;
stream=fopen(log_file_name,"a+");

}
if(!stream) return;

//根据新的消息类型进行错误定义与判断
int Type=LogEventsBuffer->get_bodyid();


#if 1
switch(Type)
{

//日志处理主要使用fprintf()

case 22:
                  .......
default:
fprintf(stream,"%s\n\t  ERRORMESSAGE:未识别的错误信息!\n",asctime(timeinfo));
break;

}
#endif


delete LogEventsBuffer;
LogEventsBuffer=NULL;
LogQueueCache.pop();

}


//日志记录线程主函数
void *LogEventsThreadFunc(void *)
{
printf("LogEventsThreadFunc\n");

time_t rawtime;
struct tm*timeinfo;
rawtime=time(NULL);
timeinfo=localtime(&rawtime);

FILE *stream;
stream = fopen( log_file_name, "w" );

bool LogIsEmpty;
//处理日志记录过程
while(1)
{
        pthread_mutex_lock(&log_mut);
LogIsEmpty=LogQueueCache.empty();
              if (LogIsEmpty)
                  {    while(1)
                        {
                          pthread_cond_wait(&log_cond, &log_mut);
                          if(LogIsEmpty) break;
                        }
}
         
              LogEventsFunc(stream);

              pthread_mutex_unlock(&log_mut);

}

fclose(stream);
char *EXIT="LogEventsThread Exit!";
pthread_exit(EXIT);
}

论坛徽章:
4
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:56:11IT运维版块每日发帖之星
日期:2016-08-11 06:20:00IT运维版块每日发帖之星
日期:2016-08-15 06:20:00
2 [报告]
发表于 2009-09-22 22:05 |只看该作者

回复 #1 marco_hxj 的帖子

文件句柄引起的问题。在日志文件轮转时,LogEventsFunc中重新打开了文件,但调用方并没有感应到。
即:日志文件轮转后,LogEventsFunc中的stream变量值发生了变化,但线程中用的还是以前的文件句柄,导致下次操作的steam无效!

论坛徽章:
0
3 [报告]
发表于 2009-09-23 09:14 |只看该作者

回复 #2 happy_fish100 的帖子

看来他的问题是这个stream没传递过去,
我的错误现象和他一样,也是memory courrupiton,但是我的stream是个全局变量,一个线程往里写,另外一个线程判断时间是否到,如果时间到,关闭前一个stream,再打开另外一个stream,
以前这个stream没加锁,现在加锁试试看

[ 本帖最后由 marco_hxj 于 2009-9-23 10:06 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2009-09-23 09:54 |只看该作者
参数问题。

void LogEventsFunc( FILE ** ppStream)
{

        MGCMessageHead *LogEventsBuffer;
        LogEventsBuffer=LogQueueCache.front();

        int msgCount=0;
        OTSGETAVAIBLEMONEYREQ MoneyReq;
        OTSGETAVAIBLEMONEYRSP MoneyRsp;
        OTSSENDCDRREQ CdrReq;
        OTSSENDCDRRSP CdrRsp;

        time_t rawtime;
        struct tm*timeinfo;
        rawtime=time(NULL);
        timeinfo=localtime(&rawtime);
        long long size;
       
        size=ftell(*ppStream);
        if(size>DEFAULT_MAX_LOG_SIZE)
        {
                sprintf(log_file_name,"packet_log%d%d%d%d%d%d",timeinfo->tm_year+1900,timeinfo->tm_mon+1,timeinfo->tm_mday,timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec);
                fflush(*ppStream);
                fclose(*ppStream);
                *ppStream=NULL;
                *ppStream=fopen(log_file_name,"a+");
        }
       
        if(!*ppStream) return;
       
        //根据新的消息类型进行错误定义与判断
        int Type=LogEventsBuffer->get_bodyid();

        #if 1
        switch(Type)
        {
                //日志处理主要使用fprintf()

                case 22:
                                                  .......
                default:
                fprintf(*ppStream,"%s\n\t  ERRORMESSAGE:未识别的错误信息!\n",asctime(timeinfo));
                break;
        }
        #endif


        delete LogEventsBuffer;
        LogEventsBuffer=NULL;
        LogQueueCache.pop();
}

void LogEventsFunc( FILE ** ppStream)
{

        MGCMessageHead *LogEventsBuffer;
        LogEventsBuffer=LogQueueCache.front();

        int msgCount=0;
        OTSGETAVAIBLEMONEYREQ MoneyReq;
        OTSGETAVAIBLEMONEYRSP MoneyRsp;
        OTSSENDCDRREQ CdrReq;
        OTSSENDCDRRSP CdrRsp;

        time_t rawtime;
        struct tm*timeinfo;
        rawtime=time(NULL);
        timeinfo=localtime(&rawtime);
        long long size;
       
        size=ftell(*ppStream);
        if(size>DEFAULT_MAX_LOG_SIZE)
        {
                sprintf(log_file_name,"packet_log%d%d%d%d%d%d",timeinfo->tm_year+1900,timeinfo->tm_mon+1,timeinfo->tm_mday,timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec);
                fflush(*ppStream);
                fclose(*ppStream);
                *ppStream=NULL;
                *ppStream=fopen(log_file_name,"a+");
        }
       
        if(!*ppStream) return;
       
        //根据新的消息类型进行错误定义与判断
        int Type=LogEventsBuffer->get_bodyid();

        #if 1
        switch(Type)
        {
                //日志处理主要使用fprintf()

                case 22:
                                                  .......
                default:
                fprintf(*ppStream,"%s\n\t  ERRORMESSAGE:未识别的错误信息!\n",asctime(timeinfo));
                break;
        }
        #endif


        delete LogEventsBuffer;
        LogEventsBuffer=NULL;
        LogQueueCache.pop();
}

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP