optimized pipe writing/reading and `ErrorMessage` serialization a bit (#5279)

This commit is contained in:
Oliver Stöneberg 2023-08-13 11:52:02 +02:00 committed by GitHub
parent d4d77edeae
commit 5371455606
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 36 deletions

View File

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

View File

@ -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)