From 69e04d2c5d48ec3583eb901cbd8df42e9d49893e Mon Sep 17 00:00:00 2001 From: Jonathan Lifflander Date: Mon, 7 Dec 2020 17:52:13 -0800 Subject: [PATCH] #98: sanitization: fix some bugs, make rt/enabled plugable --- src/checkpoint/dispatch/dispatch.impl.h | 2 ++ src/checkpoint/serializers/sanitizer.cc | 14 ++++++++- src/checkpoint/serializers/sanitizer.h | 34 +++++++++++++-------- src/checkpoint/serializers/sanitizer.impl.h | 34 ++++++++++++++------- 4 files changed, 60 insertions(+), 24 deletions(-) diff --git a/src/checkpoint/dispatch/dispatch.impl.h b/src/checkpoint/dispatch/dispatch.impl.h index c4595189..420c7ecf 100644 --- a/src/checkpoint/dispatch/dispatch.impl.h +++ b/src/checkpoint/dispatch/dispatch.impl.h @@ -88,6 +88,8 @@ T* Traverse::reconstruct(SerialByteType* mem) { template SerialSizeType Standard::size(T& target, Args&&... args) { + Traverse::with(target); + auto sizer = Traverse::with(target, std::forward(args)...); return sizer.getSize(); } diff --git a/src/checkpoint/serializers/sanitizer.cc b/src/checkpoint/serializers/sanitizer.cc index 09c16cdc..956c8cb4 100644 --- a/src/checkpoint/serializers/sanitizer.cc +++ b/src/checkpoint/serializers/sanitizer.cc @@ -47,9 +47,21 @@ #include "checkpoint/serializers/sanitizer.h" +#include + namespace checkpoint { namespace sanitizer { -std::unique_ptr rt_ = nullptr; +Runtime* rt() { + static std::unique_ptr base_rt; + if (base_rt == nullptr) { + base_rt = std::make_unique(); + } + return base_rt.get(); +} + +bool enabled() { + return false; +} }} /* end namespace checkpoint::sanitizer */ diff --git a/src/checkpoint/serializers/sanitizer.h b/src/checkpoint/serializers/sanitizer.h index d97985b8..d46c826d 100644 --- a/src/checkpoint/serializers/sanitizer.h +++ b/src/checkpoint/serializers/sanitizer.h @@ -60,6 +60,8 @@ namespace checkpoint { namespace sanitizer { */ struct Runtime { + virtual ~Runtime() = default; + /** * \brief Check that a member is serialized * @@ -104,7 +106,10 @@ struct Runtime { }; /// pimpl to runtime that contains runtime sanitizer logic -extern std::unique_ptr rt_; +extern Runtime* rt(); + +/// function that informs sanitizer if its enabled +extern bool enabled(); }} /* end namespace checkpoint::sanitizer*/ @@ -172,6 +177,14 @@ struct BaseSanitizer : checkpoint::Serializer { : checkpoint::Serializer(in_mode) { } + /** + * \internal \brief Construct from other sanitizer-like class + */ + template + explicit BaseSanitizer(U& cl) + : checkpoint::Serializer(cl.getMode()) + { } + /** * \brief Check that member is actually serialized * @@ -206,16 +219,6 @@ struct BaseSanitizer : checkpoint::Serializer { * \brief Do nothing on contiguous bytes */ void contiguousBytes(void*, std::size_t, std::size_t) { } - - /** - * \internal \brief Clean \c t and cast to \c void* - * - * \param[in] t the element - * - * \return untyped pointer to the element - */ - template - static void* cleanTypeToVoid(T&& t); }; /** @@ -234,7 +237,14 @@ struct Sanitizer : BaseSanitizer { }; * specialization to purposely invoke the regular serialization method on a * class. */ -struct NonSanitizingSanitizer : BaseSanitizer { }; +struct NonSanitizingSanitizer : BaseSanitizer { + /** + * \internal \brief Construct from normal sanitizer + */ + explicit NonSanitizingSanitizer(Sanitizer& s) + : BaseSanitizer(s) + { } +}; }} /* end namespace checkpoint::serializers */ diff --git a/src/checkpoint/serializers/sanitizer.impl.h b/src/checkpoint/serializers/sanitizer.impl.h index 33b06ede..b3caa0b8 100644 --- a/src/checkpoint/serializers/sanitizer.impl.h +++ b/src/checkpoint/serializers/sanitizer.impl.h @@ -53,17 +53,21 @@ namespace checkpoint { namespace serializers { template -/*static*/ void* BaseSanitizer::cleanTypeToVoid(T&& t) { +void* cleanTypeToVoid(T&& t) { return reinterpret_cast(dispatch::cleanType(&t)); } template void SanitizerDispatch::serializeIntrusive(SerT& s, T& t) { + if (not sanitizer::enabled()) { + return; + } + // Declare this member as serialized - sanitizer::rt_->isSerialized(cleanTypeToVoid(t), 1, typeid(T).name()); + sanitizer::rt()->isSerialized(cleanTypeToVoid(t), 1, typeid(T).name()); // Push this type on the stack since we are about to traverse it - sanitizer::rt_->push(typeid(T).name()); + sanitizer::rt()->push(typeid(T).name()); // Recurse with the current serializer (a sanitizing pass) t.serialize(s); @@ -75,22 +79,30 @@ void SanitizerDispatch::serializeIntrusive(SerT& s, T& t) { t.serialize(nss); // Pop off of stack - sanitizer::rt_->pop(typeid(T).name()); + sanitizer::rt()->pop(typeid(T).name()); } template void SanitizerDispatch::serializeNonIntrusiveEnum(SerT& s, T& t) { + if (not sanitizer::enabled()) { + return; + } + // Declare this enum as serialized - sanitizer::rt_->isSerialized(cleanTypeToVoid(t), 1, typeid(T).name()); + sanitizer::rt()->isSerialized(cleanTypeToVoid(t), 1, typeid(T).name()); } template void SanitizerDispatch::serializeNonIntrusive(SerT& s, T& t) { + if (not sanitizer::enabled()) { + return; + } + // Declare this enum as serialized - sanitizer::rt_->isSerialized(cleanTypeToVoid(t), 1, typeid(T).name()); + sanitizer::rt()->isSerialized(cleanTypeToVoid(t), 1, typeid(T).name()); // Push this type on the stack since we are about to traverse it - sanitizer::rt_->push(typeid(T).name()); + sanitizer::rt()->push(typeid(T).name()); // Recurse with the current serializer (a sanitizing pass) serialize(s, t); @@ -102,22 +114,22 @@ void SanitizerDispatch::serializeNonIntrusive(SerT& s, T& t) { serialize(nss, t); // Pop off of stack - sanitizer::rt_->pop(typeid(T).name()); + sanitizer::rt()->pop(typeid(T).name()); } template void BaseSanitizer::check(T& t, std::string t_name) { - sanitizer::rt_->checkMember(cleanTypeToVoid(t), t_name, typeid(T).name()); + sanitizer::rt()->checkMember(cleanTypeToVoid(t), t_name, typeid(T).name()); } template void BaseSanitizer::skip(T& t, std::string t_name) { - sanitizer::rt_->skipMember(cleanTypeToVoid(t), t_name, typeid(T).name()); + sanitizer::rt()->skipMember(cleanTypeToVoid(t), t_name, typeid(T).name()); } template void BaseSanitizer::contiguousTyped(SerializerT&, T* t, std::size_t num_elms) { - sanitizer::rt_->isSerialized( + sanitizer::rt()->isSerialized( reinterpret_cast(t), num_elms, typeid(t).name() ); }