Skip to content

Commit c350cfb

Browse files
Ekdohibsparamat
authored andcommittedApr 21, 2016
Make logging use a fixed-length buffer to avoid race conditions.
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.
1 parent 5c32c5e commit c350cfb

File tree

1 file changed

+18
-6
lines changed

1 file changed

+18
-6
lines changed
 

‎src/log.cpp

+18-6
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,22 @@ with this program; if not, write to the Free Software Foundation, Inc.,
3434
#include <cerrno>
3535
#include <cstring>
3636

37+
const int BUFFER_LENGTH = 256;
38+
3739
class StringBuffer : public std::streambuf {
3840
public:
39-
StringBuffer() {}
41+
StringBuffer() {
42+
buffer_index = 0;
43+
}
4044

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

4650
private:
47-
std::string buffer;
51+
char buffer[BUFFER_LENGTH];
52+
int buffer_index;
4853
};
4954

5055

@@ -338,11 +343,18 @@ std::streamsize StringBuffer::xsputn(const char *s, std::streamsize n)
338343
void StringBuffer::push_back(char c)
339344
{
340345
if (c == '\n' || c == '\r') {
341-
if (!buffer.empty())
342-
flush(buffer);
343-
buffer.clear();
346+
if (buffer_index)
347+
flush(std::string(buffer, buffer_index));
348+
buffer_index = 0;
344349
} else {
345-
buffer.push_back(c);
350+
int index = buffer_index;
351+
buffer[index++] = c;
352+
if (index >= BUFFER_LENGTH) {
353+
flush(std::string(buffer, buffer_index));
354+
buffer_index = 0;
355+
} else {
356+
buffer_index = index;
357+
}
346358
}
347359
}
348360

0 commit comments

Comments
 (0)
Please sign in to comment.