1

I seldom have a seg fault issue when the std::ofstream is going out of scope. I have the following structs in my 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");
        };

And in Logger.cpp, I have following functions:

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];
}

And in a thread in Logger.cpp, I have...

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);
    }
}

The problem I am having is that SOMETIMES there is a seg fault that gets thrown in the destructor of std::ofstream ofs in FileInfo when I try to CloseLogFile. It works many times. And even before the SEG Fault occurs (through various cout statements) I have confirmed that the std::ofstream is good, has not failed, not reached eof, and is not bad. I have also confirmed that file_map[prefix] exists, and is present by outputting FileInfo's ToString() as well. These are all checked right before deletion in CloseLogFile.

My question concerns the reason for the SEG FAULT.

Also when the line gets outputted to the ofstream in WriteToFile(), is it fine if I delete the LogRequest object. As in, what exactly is happening in the info->ofs << line << std::endl; line?

4

1 回答 1

1

looks like your sprintf(timestamp...) call overwrites by one character (the null) which will cause undefined behavior. may or may not be your primary issue though since that's on a thread stack and your ofs is on the heap...

于 2012-09-14T16:16:13.900 回答