Skip to content

Commit

Permalink
Make logging use a fixed-length buffer to avoid race conditions.
Browse files Browse the repository at this point in the history
Previously, race conditions occurred inside logging, that caused
segfaults because a thread was trying to use an old pointer that
was freed when the string was reallocated. Using a fixed-length buffer
avoids this, at the cost of cutting too long messages over seveal lines.
  • Loading branch information
Ekdohibs authored and paramat committed Apr 21, 2016
1 parent 5c32c5e commit c350cfb
Showing 1 changed file with 18 additions and 6 deletions.
24 changes: 18 additions & 6 deletions src/log.cpp
Expand Up @@ -34,17 +34,22 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <cerrno>
#include <cstring>

const int BUFFER_LENGTH = 256;

class StringBuffer : public std::streambuf {
public:
StringBuffer() {}
StringBuffer() {
buffer_index = 0;
}

int overflow(int c);
virtual void flush(const std::string &buf) = 0;
std::streamsize xsputn(const char *s, std::streamsize n);
void push_back(char c);

private:
std::string buffer;
char buffer[BUFFER_LENGTH];
int buffer_index;
};


Expand Down Expand Up @@ -338,11 +343,18 @@ std::streamsize StringBuffer::xsputn(const char *s, std::streamsize n)
void StringBuffer::push_back(char c)
{
if (c == '\n' || c == '\r') {
if (!buffer.empty())
flush(buffer);
buffer.clear();
if (buffer_index)
flush(std::string(buffer, buffer_index));
buffer_index = 0;
} else {
buffer.push_back(c);
int index = buffer_index;
buffer[index++] = c;
if (index >= BUFFER_LENGTH) {
flush(std::string(buffer, buffer_index));
buffer_index = 0;
} else {
buffer_index = index;
}
}
}

Expand Down

0 comments on commit c350cfb

Please sign in to comment.