optimized pipe writing/reading and `ErrorMessage` serialization a bit (#5279)
This commit is contained in:
parent
d4d77edeae
commit
5371455606
|
@ -90,32 +90,35 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// TODO: how to log file name in error?
|
// TODO: how to log file name in error?
|
||||||
void writeToPipe(PipeSignal type, const std::string &data) const
|
void writeToPipeInternal(PipeSignal type, const void* data, std::size_t to_write) const
|
||||||
{
|
{
|
||||||
unsigned int len = static_cast<unsigned int>(data.length() + 1);
|
const ssize_t bytes_written = write(mWpipe, data, to_write);
|
||||||
char *out = new char[len + 1 + sizeof(len)];
|
|
||||||
out[0] = static_cast<char>(type);
|
|
||||||
std::memcpy(&(out[1]), &len, sizeof(len));
|
|
||||||
std::memcpy(&(out[1+sizeof(len)]), data.c_str(), len);
|
|
||||||
|
|
||||||
std::size_t bytes_to_write = len + 1 + sizeof(len);
|
|
||||||
ssize_t bytes_written = write(mWpipe, out, len + 1 + sizeof(len));
|
|
||||||
if (bytes_written <= 0) {
|
if (bytes_written <= 0) {
|
||||||
const int err = errno;
|
const int err = errno;
|
||||||
delete[] out;
|
std::cerr << "#### ThreadExecutor::writeToPipeInternal() error for type " << type << ": " << std::strerror(err) << std::endl;
|
||||||
out = nullptr;
|
|
||||||
std::cerr << "#### ThreadExecutor::writeToPipe() error for type " << type << ": " << std::strerror(err) << std::endl;
|
|
||||||
std::exit(EXIT_FAILURE);
|
std::exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
// TODO: write until everything is written
|
// TODO: write until everything is written
|
||||||
if (bytes_written != bytes_to_write) {
|
if (bytes_written != to_write) {
|
||||||
delete[] out;
|
std::cerr << "#### ThreadExecutor::writeToPipeInternal() error for type " << type << ": insufficient data written (expected: " << to_write << " / got: " << bytes_written << ")" << std::endl;
|
||||||
out = nullptr;
|
|
||||||
std::cerr << "#### ThreadExecutor::writeToPipe() error for type " << type << ": insufficient data written (expected: " << bytes_to_write << " / got: " << bytes_written << ")" << std::endl;
|
|
||||||
std::exit(EXIT_FAILURE);
|
std::exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delete[] out;
|
void writeToPipe(PipeSignal type, const std::string &data) const
|
||||||
|
{
|
||||||
|
{
|
||||||
|
const char t = static_cast<char>(type);
|
||||||
|
writeToPipeInternal(type, &t, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned int len = static_cast<unsigned int>(data.length() + 1);
|
||||||
|
{
|
||||||
|
static constexpr std::size_t l_size = sizeof(unsigned int);
|
||||||
|
writeToPipeInternal(type, &len, l_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
writeToPipeInternal(type, data.c_str(), len);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int mWpipe;
|
const int mWpipe;
|
||||||
|
@ -164,8 +167,8 @@ bool ProcessExecutor::handleRead(int rpipe, unsigned int &result, const std::str
|
||||||
|
|
||||||
// Don't rely on incoming data being null-terminated.
|
// Don't rely on incoming data being null-terminated.
|
||||||
// Allocate +1 element and null-terminate the buffer.
|
// Allocate +1 element and null-terminate the buffer.
|
||||||
char *buf = new char[len + 1];
|
std::string buf(len + 1, '\0');
|
||||||
char *data_start = buf;
|
char *data_start = &buf[0];
|
||||||
bytes_to_read = len;
|
bytes_to_read = len;
|
||||||
do {
|
do {
|
||||||
bytes_read = read(rpipe, data_start, bytes_to_read);
|
bytes_read = read(rpipe, data_start, bytes_to_read);
|
||||||
|
@ -177,13 +180,14 @@ bool ProcessExecutor::handleRead(int rpipe, unsigned int &result, const std::str
|
||||||
bytes_to_read -= bytes_read;
|
bytes_to_read -= bytes_read;
|
||||||
data_start += bytes_read;
|
data_start += bytes_read;
|
||||||
} while (bytes_to_read != 0);
|
} while (bytes_to_read != 0);
|
||||||
buf[len] = 0;
|
buf[len] = '\0';
|
||||||
|
|
||||||
bool res = true;
|
bool res = true;
|
||||||
if (type == PipeWriter::REPORT_OUT) {
|
if (type == PipeWriter::REPORT_OUT) {
|
||||||
// the first character is the color
|
// the first character is the color
|
||||||
const Color c = static_cast<Color>(buf[0]);
|
const Color c = static_cast<Color>(buf[0]);
|
||||||
mErrorLogger.reportOut(buf + 1, c);
|
// TODO: avoid string copy
|
||||||
|
mErrorLogger.reportOut(buf.substr(1), c);
|
||||||
} else if (type == PipeWriter::REPORT_ERROR) {
|
} else if (type == PipeWriter::REPORT_ERROR) {
|
||||||
ErrorMessage msg;
|
ErrorMessage msg;
|
||||||
try {
|
try {
|
||||||
|
@ -200,7 +204,6 @@ bool ProcessExecutor::handleRead(int rpipe, unsigned int &result, const std::str
|
||||||
res = false;
|
res = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] buf;
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -227,35 +227,50 @@ Suppressions::ErrorMessage ErrorMessage::toSuppressionsErrorMessage() const
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void serializeString(std::string &oss, const std::string & str)
|
||||||
|
{
|
||||||
|
oss += std::to_string(str.length());
|
||||||
|
oss += " ";
|
||||||
|
oss += str;
|
||||||
|
}
|
||||||
|
|
||||||
std::string ErrorMessage::serialize() const
|
std::string ErrorMessage::serialize() const
|
||||||
{
|
{
|
||||||
// Serialize this message into a simple string
|
// Serialize this message into a simple string
|
||||||
std::ostringstream oss;
|
std::string oss;
|
||||||
oss << id.length() << " " << id;
|
serializeString(oss, id);
|
||||||
oss << Severity::toString(severity).length() << " " << Severity::toString(severity);
|
serializeString(oss, Severity::toString(severity));
|
||||||
oss << MathLib::toString(cwe.id).length() << " " << MathLib::toString(cwe.id);
|
serializeString(oss, MathLib::toString(cwe.id));
|
||||||
oss << MathLib::toString(hash).length() << " " << MathLib::toString(hash);
|
serializeString(oss, MathLib::toString(hash));
|
||||||
oss << file0.size() << " " << file0;
|
serializeString(oss, file0);
|
||||||
if (certainty == Certainty::inconclusive) {
|
if (certainty == Certainty::inconclusive) {
|
||||||
const std::string text("inconclusive");
|
const std::string text("inconclusive");
|
||||||
oss << text.length() << " " << text;
|
serializeString(oss, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string saneShortMessage = fixInvalidChars(mShortMessage);
|
const std::string saneShortMessage = fixInvalidChars(mShortMessage);
|
||||||
const std::string saneVerboseMessage = fixInvalidChars(mVerboseMessage);
|
const std::string saneVerboseMessage = fixInvalidChars(mVerboseMessage);
|
||||||
|
|
||||||
oss << saneShortMessage.length() << " " << saneShortMessage;
|
serializeString(oss, saneShortMessage);
|
||||||
oss << saneVerboseMessage.length() << " " << saneVerboseMessage;
|
serializeString(oss, saneVerboseMessage);
|
||||||
oss << callStack.size() << " ";
|
oss += std::to_string(callStack.size());
|
||||||
|
oss += " ";
|
||||||
|
|
||||||
for (std::list<ErrorMessage::FileLocation>::const_iterator loc = callStack.cbegin(); loc != callStack.cend(); ++loc) {
|
for (std::list<ErrorMessage::FileLocation>::const_iterator loc = callStack.cbegin(); loc != callStack.cend(); ++loc) {
|
||||||
std::ostringstream smallStream;
|
std::string frame;
|
||||||
smallStream << (*loc).line << '\t' << (*loc).column << '\t' << (*loc).getfile(false) << '\t' << loc->getOrigFile(false) << '\t' << loc->getinfo();
|
frame += std::to_string((*loc).line);
|
||||||
oss << smallStream.str().length() << " " << smallStream.str();
|
frame += '\t';
|
||||||
|
frame += std::to_string((*loc).column);
|
||||||
|
frame += '\t';
|
||||||
|
frame += (*loc).getfile(false);
|
||||||
|
frame += '\t';
|
||||||
|
frame += loc->getOrigFile(false);
|
||||||
|
frame += '\t';
|
||||||
|
frame += loc->getinfo();
|
||||||
|
serializeString(oss, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
return oss.str();
|
return oss;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ErrorMessage::deserialize(const std::string &data)
|
void ErrorMessage::deserialize(const std::string &data)
|
||||||
|
|
Loading…
Reference in New Issue