首页 文章

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

提问于
浏览
1

当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 回答

  • 1

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

相关问题