当流程超出范围时,偶尔会出现SEG FAULT

时间:2012-09-14 15:33:15

标签: c++ segmentation-fault ofstream

当std :: ofstream超出范围时,我很少遇到seg错误问题。我在Logger.h中有以下结构:

        struct LogRequest
        {
            std::string line;
            std::string prefix;
        };

        struct FileInfo
        {
            std::string name;
            std::ofstream ofs;
            int lines;
            std::string ToString()
            {
                return (name + " exists");
        };

在Logger.cpp中,我有以下功能:

void Logger::Log(const std::string line, std::string prefix)
{
    pthread_mutex_lock(&mutex);
        if (file_map.find(prefix) == file_map.end())
        {
            OpenLogFile(prefix);
        }

        LogRequest* request = new LogRequest;
        request->line = line;
        request->prefix = prefix;
        message_queue.push_back(request);
    pthread_mutex_unlock(&mutex);
}

void Logger::OpenLogFile(const std::string& prefix)
{
    //get timestamp to use
    char timestamp[15];
    time_t now;
    time(&now);
    struct tm* current = localtime(&now);
    sprintf(timestamp, "%02u%02u%04u_%02u%02u%02u", (current->tm_mon+1),
        current->tm_mday,(1900 + current->tm_year), current->tm_hour,
        current->tm_min, current->tm_sec);

    FileInfo* info = new FileInfo;
    info->name = "logs/" + prefix + ".log_" + timestamp;
    info->ofs.open(info->name.c_str(), std::ios::out);
    info->lines = 0;

    file_map[prefix] = info;
}

void Logger::CloseLogFile(const std::string& prefix)
{
    delete file_map[prefix];
}

在Logger.cpp的一个帖子中,我有......

void Logger::WriteToFile()
{
    std::map<std::string, FileInfo* >::iterator it;

    while(run)
    {
        char timestamp[16];
        time_t now;
        time(&now);
        struct tm* current = localtime(&now);
        sprintf(timestamp, "%02u%02u%04u|%02u%02u%02u|", (current->tm_mon+1),
            current->tm_mday,(1900 + current->tm_year), current->tm_hour,
            current->tm_min, current->tm_sec);

        pthread_mutex_lock(&mutex);
            for(it=file_map.begin(); it != file_map.end(); ++it)
            {
                if(it->second->lines > MAX_LINES)
                {
                    CloseLogFile(it->first);
                    OpenLogFile(it->first);
                }
                else
                {
                    int written = 0;

                    while(!message_queue.empty() && written < MESSAGES_PER_WRITE)
                    {
                        LogRequest* request = message_queue.front();
                        message_queue.pop_front();

                        std::string line(timestamp, 16);
                        line.append(request->line);

                        FileInfo* info = file_map[request->prefix];
                        info->ofs << line << std::endl;
                        info->lines++;
                        written++;
                        delete request;
                    }
                }
            }
        pthread_mutex_unlock(&mutex);

        usleep(1000);
    }
}

我遇到的问题是,当我尝试CloseLogFile时,有一个seg错误会在FileInfo中的std :: ofstream ofs的析构函数中抛出。它工作很多次。甚至在SEG Fault发生之前(通过各种cout语句)我已经确认std :: ofstream是好的,没有失败,没有达到eof,并且还不错。我还确认file_map [prefix]存在,并且通过输出FileInfo的ToString()也存在。这些都是在CloseLogFile中删除之前检查的。

我的问题涉及SEG FAULT的原因。

当行在WriteToFile()中输出到ofstream时,如果删除LogRequest对象,则可以。如何,info->ofs << line << std::endl;行中究竟发生了什么?

1 个答案:

答案 0 :(得分:1)

看起来像你的sprintf(timestamp ...)调用被一个字符(null)覆盖,这将导致未定义的行为。可能是也可能不是你的主要问题,因为那是在一个线程堆栈上,你的ons在堆上......