Swift: add trace logging of all trap emission

This commit is contained in:
Paolo Tranquilli
2023-04-03 11:43:05 +02:00
parent a386c58371
commit abc0c7cf24
7 changed files with 71 additions and 0 deletions

View File

@@ -5,6 +5,8 @@
#include <iostream>
#include <optional>
#include <vector>
#include <binlog/binlog.hpp>
#include <binlog/adapt_stdoptional.hpp>
#include "{{trap_library}}/TrapLabel.h"
#include "{{trap_library}}/TrapTagTraits.h"
@@ -80,3 +82,9 @@ struct detail::ToTrapClassFunctor<{{name}}Tag> {
};
{{/classes}}
}
{{#classes}}
{{#final}}
BINLOG_ADAPT_STRUCT(codeql::{{name}}, id{{> cpp_list_fields}});
{{/final}}
{{/classes}}

View File

@@ -0,0 +1 @@
{{#bases}}{{#ref}}{{> cpp_list_fields}}{{/ref}}{{/bases}}{{#fields}}, {{field_name}}{{/fields}}

View File

@@ -4,6 +4,7 @@
#include <iostream>
#include <string>
#include <binlog/binlog.hpp>
#include "{{trap_library_dir}}/TrapLabel.h"
#include "{{trap_library_dir}}/TrapTagTraits.h"
@@ -43,3 +44,7 @@ struct ToBindingTrapFunctor<{{type}}> {
{{/id}}
{{/traps}}
}
{{#traps}}
BINLOG_ADAPT_STRUCT(codeql::{{name}}Trap{{#fields}}, {{field_name}}{{/fields}});
{{/traps}}

View File

@@ -36,6 +36,8 @@ class TargetFile {
return *this;
}
const std::filesystem::path& target() const { return targetPath; }
private:
TargetFile(const std::filesystem::path& target,
const std::filesystem::path& targetDir,

View File

@@ -49,5 +49,6 @@ swift_cc_library(
visibility = ["//visibility:public"],
deps = [
"//swift/extractor/infra/file",
"//swift/extractor/infra/log",
],
)

View File

@@ -5,18 +5,21 @@
#include "swift/extractor/trap/TrapLabel.h"
#include "swift/extractor/infra/file/TargetFile.h"
#include "swift/extractor/infra/log/SwiftLogging.h"
namespace codeql {
// Abstracts a given trap output file, with its own universe of trap labels
class TrapDomain {
TargetFile out;
Logger logger{out.target().filename()};
public:
explicit TrapDomain(TargetFile&& out) : out{std::move(out)} {}
template <typename Entry>
void emit(const Entry& e) {
LOG_TRACE("{}", e);
out << e << '\n';
}
@@ -48,6 +51,7 @@ class TrapDomain {
Args&&... args) {
auto ret = allocateLabel<Tag>();
assignKey(ret, std::forward<Args>(args)...);
LOG_TRACE("^^^ .implementation {}", implementationId);
out << " .implementation " << trapQuoted(implementationId) << '\n';
return ret;
}
@@ -62,6 +66,7 @@ class TrapDomain {
template <typename Tag>
void assignStar(TrapLabel<Tag> label) {
LOG_TRACE("{}=*", label);
out << label << "=*";
}
@@ -69,6 +74,7 @@ class TrapDomain {
void assignKey(TrapLabel<Tag> label, const std::string& key) {
// prefix the key with the id to guarantee the same key is not used wrongly with different tags
auto prefixed = std::string(Tag::prefix) + '_' + key;
LOG_TRACE("{}=@{}", label, prefixed);
out << label << "=@" << trapQuoted(prefixed);
}

View File

@@ -5,6 +5,9 @@
#include <iostream>
#include <string>
#include <vector>
#include <binlog/binlog.hpp>
#include <cmath>
#include <charconv>
namespace codeql {
@@ -18,6 +21,7 @@ class UntypedTrapLabel {
friend class std::hash<UntypedTrapLabel>;
template <typename Tag>
friend class TrapLabel;
BINLOG_ADAPT_STRUCT_FRIEND;
static constexpr uint64_t undefined = 0xffffffffffffffff;
@@ -38,7 +42,21 @@ class UntypedTrapLabel {
return out;
}
std::string str() const {
std::string ret(strSize(), '\0');
ret[0] = '#';
std::to_chars(ret.data() + 1, ret.data() + ret.size(), id_, 16);
return ret;
}
friend bool operator==(UntypedTrapLabel lhs, UntypedTrapLabel rhs) { return lhs.id_ == rhs.id_; }
private:
size_t strSize() const {
if (id_ == undefined) return 17; // #ffffffffffffffff
if (id_ == 0) return 2; // #0
return /* # */ 1 + /* hex digits */ static_cast<size_t>(ceil(log2(id_ + 1) / 4));
}
};
template <typename TagParam>
@@ -100,3 +118,33 @@ struct hash<codeql::UntypedTrapLabel> {
}
};
} // namespace std
namespace mserialize {
// log labels using their string representation, using binlog/mserialize internal plumbing
template <>
struct CustomTag<codeql::UntypedTrapLabel, void> : detail::BuiltinTag<std::string> {
using T = codeql::UntypedTrapLabel;
};
template <typename Tag>
struct CustomTag<codeql::TrapLabel<Tag>, void> : detail::BuiltinTag<std::string> {
using T = codeql::TrapLabel<Tag>;
};
template <>
struct CustomSerializer<codeql::UntypedTrapLabel, void> {
template <typename OutputStream>
static void serialize(codeql::UntypedTrapLabel label, OutputStream& out) {
mserialize::serialize(label.str(), out);
}
static size_t serialized_size(codeql::UntypedTrapLabel label) {
return sizeof(std::uint32_t) + label.strSize();
}
};
template <typename Tag>
struct CustomSerializer<codeql::TrapLabel<Tag>, void> : CustomSerializer<codeql::UntypedTrapLabel> {
};
} // namespace mserialize