Unverified Commit c4b567ab authored by Joseph Noir's avatar Joseph Noir Committed by GitHub

Merge pull request #879

Fix potential segfault with logging enabled
parents 2d79652b 5c8798cb
...@@ -56,15 +56,12 @@ namespace caf { ...@@ -56,15 +56,12 @@ namespace caf {
template <class T> template <class T>
struct mpi_field_access { struct mpi_field_access {
std::string operator()(const uniform_type_info_map& types) { std::string operator()(const uniform_type_info_map& types) {
auto nr = type_nr<T>::value; auto result = types.portable_name(type_nr<T>::value, &typeid(T));
if (nr != 0) if (result == types.default_type_name()) {
return *types.portable_name(nr, nullptr); result = "<invalid-type[typeid ";
auto ptr = types.portable_name(0, &typeid(T));
if (ptr != nullptr)
return *ptr;
std::string result = "<invalid-type[typeid ";
result += typeid(T).name(); result += typeid(T).name();
result += "]>"; result += "]>";
}
return result; return result;
} }
}; };
......
...@@ -75,32 +75,45 @@ public: ...@@ -75,32 +75,45 @@ public:
/// Returns the portable name for given type information or `nullptr` /// Returns the portable name for given type information or `nullptr`
/// if no mapping was found. /// if no mapping was found.
const std::string* portable_name(uint16_t nr, const std::type_info* ti) const; const std::string& portable_name(uint16_t nr, const std::type_info* ti) const;
/// Returns the portable name for given type information or `nullptr` /// Returns the portable name for given type information or `nullptr`
/// if no mapping was found. /// if no mapping was found.
inline const std::string* const std::string&
portable_name(const std::pair<uint16_t, const std::type_info*>& x) const { portable_name(const std::pair<uint16_t, const std::type_info*>& x) const {
return portable_name(x.first, x.second); return portable_name(x.first, x.second);
} }
/// Returns the enclosing actor system. /// Returns the enclosing actor system.
inline actor_system& system() const { actor_system& system() const {
return system_; return system_;
} }
/// Returns the default type name for unknown types.
const std::string& default_type_name() const {
return default_type_name_;
}
private: private:
uniform_type_info_map(actor_system& sys); uniform_type_info_map(actor_system& sys);
/// Reference to the parent system.
actor_system& system_; actor_system& system_;
// message types /// Value factories for builtin types.
std::array<value_factory_kvp, type_nrs - 1> builtin_; std::array<value_factory_kvp, type_nrs - 1> builtin_;
/// Values factories for user-defined types.
value_factories_by_name ad_hoc_; value_factories_by_name ad_hoc_;
/// Lock for accessing `ad_hoc_`.`
mutable detail::shared_spinlock ad_hoc_mtx_; mutable detail::shared_spinlock ad_hoc_mtx_;
// message type names /// Names of builtin types.
std::array<std::string, type_nrs - 1> builtin_names_; std::array<std::string, type_nrs - 1> builtin_names_;
/// Displayed name for unknown types.
std::string default_type_name_;
}; };
} // namespace caf } // namespace caf
......
...@@ -79,7 +79,7 @@ inbound_path::inbound_path(stream_manager_ptr mgr_ptr, stream_slots id, ...@@ -79,7 +79,7 @@ inbound_path::inbound_path(stream_manager_ptr mgr_ptr, stream_slots id,
mgr->register_input_path(this); mgr->register_input_path(this);
CAF_STREAM_LOG_DEBUG(mgr->self()->name() CAF_STREAM_LOG_DEBUG(mgr->self()->name()
<< "opens input stream with element type" << "opens input stream with element type"
<< *mgr->self()->system().types().portable_name(in_type) << mgr->self()->system().types().portable_name(in_type)
<< "at slot" << id.receiver << "from" << hdl); << "at slot" << id.receiver << "from" << hdl);
} }
......
...@@ -169,8 +169,8 @@ error message::save(serializer& sink, const type_erased_tuple& x) { ...@@ -169,8 +169,8 @@ error message::save(serializer& sink, const type_erased_tuple& x) {
auto n = x.size(); auto n = x.size();
for (size_t i = 0; i < n; ++i) { for (size_t i = 0; i < n; ++i) {
auto rtti = x.type(i); auto rtti = x.type(i);
auto ptr = types.portable_name(rtti); const auto& portable_name = types.portable_name(rtti);
if (ptr == nullptr) { if (portable_name == types.default_type_name()) {
std::cerr << "[ERROR]: cannot serialize message because a type was " std::cerr << "[ERROR]: cannot serialize message because a type was "
"not added to the types list, typeid name: " "not added to the types list, typeid name: "
<< (rtti.second != nullptr ? rtti.second->name() << (rtti.second != nullptr ? rtti.second->name()
...@@ -181,7 +181,7 @@ error message::save(serializer& sink, const type_erased_tuple& x) { ...@@ -181,7 +181,7 @@ error message::save(serializer& sink, const type_erased_tuple& x) {
: "-not-available-"); : "-not-available-");
} }
tname += '+'; tname += '+';
tname += *ptr; tname += portable_name;
} }
auto save_loop = [&]() -> error { auto save_loop = [&]() -> error {
for (size_t i = 0; i < n; ++i) { for (size_t i = 0; i < n; ++i) {
......
...@@ -148,21 +148,22 @@ uniform_type_info_map::make_value(const std::type_info& x) const { ...@@ -148,21 +148,22 @@ uniform_type_info_map::make_value(const std::type_info& x) const {
return nullptr; return nullptr;
} }
const std::string* const std::string&
uniform_type_info_map::portable_name(uint16_t nr, uniform_type_info_map::portable_name(uint16_t nr,
const std::type_info* ti) const { const std::type_info* ti) const {
if (nr != 0) if (nr != 0)
return &builtin_names_[nr - 1]; return builtin_names_[nr - 1];
if (ti == nullptr) if (ti == nullptr)
return nullptr; return default_type_name_;
auto& custom_names = system().config().type_names_by_rtti; auto& custom_names = system().config().type_names_by_rtti;
auto i = custom_names.find(std::type_index(*ti)); auto i = custom_names.find(std::type_index(*ti));
if (i != custom_names.end()) if (i != custom_names.end())
return &(i->second); return i->second;
return nullptr; return default_type_name_;
} }
uniform_type_info_map::uniform_type_info_map(actor_system& sys) : system_(sys) { uniform_type_info_map::uniform_type_info_map(actor_system& sys)
: system_(sys), default_type_name_("???") {
sorted_builtin_types list; sorted_builtin_types list;
fill_builtins(builtin_, list, 0); fill_builtins(builtin_, list, 0);
for (size_t i = 0; i < builtin_names_.size(); ++i) for (size_t i = 0; i < builtin_names_.size(); ++i)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment