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:
// 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);
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));
const ssize_t bytes_written = write(mWpipe, data, to_write);
if (bytes_written <= 0) {
const int err = errno;
delete[] out;
out = nullptr;
std::cerr << "#### ThreadExecutor::writeToPipe() error for type " << type << ": " << std::strerror(err) << std::endl;
std::cerr << "#### ThreadExecutor::writeToPipeInternal() error for type " << type << ": " << std::strerror(err) << std::endl;
std::exit(EXIT_FAILURE);
}
// TODO: write until everything is written
if (bytes_written != bytes_to_write) {
delete[] out;
out = nullptr;
std::cerr << "#### ThreadExecutor::writeToPipe() error for type " << type << ": insufficient data written (expected: " << bytes_to_write << " / got: " << bytes_written << ")" << std::endl;
if (bytes_written != to_write) {
std::cerr << "#### ThreadExecutor::writeToPipeInternal() error for type " << type << ": insufficient data written (expected: " << to_write << " / got: " << bytes_written << ")" << std::endl;
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;
@ -164,8 +167,8 @@ bool ProcessExecutor::handleRead(int rpipe, unsigned int &result, const std::str
// Don't rely on incoming data being null-terminated.
// Allocate +1 element and null-terminate the buffer.
char *buf = new char[len + 1];
char *data_start = buf;
std::string buf(len + 1, '\0');
char *data_start = &buf[0];
bytes_to_read = len;
do {
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;
data_start += bytes_read;
} while (bytes_to_read != 0);
buf[len] = 0;
buf[len] = '\0';
bool res = true;
if (type == PipeWriter::REPORT_OUT) {
// the first character is the color
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) {
ErrorMessage msg;
try {
@ -200,7 +204,6 @@ bool ProcessExecutor::handleRead(int rpipe, unsigned int &result, const std::str
res = false;
}
delete[] buf;
return res;
}

View File

@ -227,35 +227,50 @@ Suppressions::ErrorMessage ErrorMessage::toSuppressionsErrorMessage() const
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
{
// Serialize this message into a simple string
std::ostringstream oss;
oss << id.length() << " " << id;
oss << Severity::toString(severity).length() << " " << Severity::toString(severity);
oss << MathLib::toString(cwe.id).length() << " " << MathLib::toString(cwe.id);
oss << MathLib::toString(hash).length() << " " << MathLib::toString(hash);
oss << file0.size() << " " << file0;
std::string oss;
serializeString(oss, id);
serializeString(oss, Severity::toString(severity));
serializeString(oss, MathLib::toString(cwe.id));
serializeString(oss, MathLib::toString(hash));
serializeString(oss, file0);
if (certainty == Certainty::inconclusive) {
const std::string text("inconclusive");
oss << text.length() << " " << text;
serializeString(oss, text);
}
const std::string saneShortMessage = fixInvalidChars(mShortMessage);
const std::string saneVerboseMessage = fixInvalidChars(mVerboseMessage);
oss << saneShortMessage.length() << " " << saneShortMessage;
oss << saneVerboseMessage.length() << " " << saneVerboseMessage;
oss << callStack.size() << " ";
serializeString(oss, saneShortMessage);
serializeString(oss, saneVerboseMessage);
oss += std::to_string(callStack.size());
oss += " ";
for (std::list<ErrorMessage::FileLocation>::const_iterator loc = callStack.cbegin(); loc != callStack.cend(); ++loc) {
std::ostringstream smallStream;
smallStream << (*loc).line << '\t' << (*loc).column << '\t' << (*loc).getfile(false) << '\t' << loc->getOrigFile(false) << '\t' << loc->getinfo();
oss << smallStream.str().length() << " " << smallStream.str();
std::string frame;
frame += std::to_string((*loc).line);
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)