From 0a03a2809a9ccdc30aaf731c9e066c47f5025cb6 Mon Sep 17 00:00:00 2001 From: Ethan Mahintorabi Date: Mon, 12 Dec 2022 19:03:59 +0000 Subject: [PATCH] Fixes segfault on some linux systems The static order initialization seems to be more present throughout Klayout and might cause additional issues, but this fix stopped the segfault on my machine. When compiling with asan there are a number or other issues that could be addressed, but it's not clear if they're real problems. dbLayout change occured when using the python API to read a DEF layout. When the layout is updated the code uses a const iterator which implicitly wraps the non-const iterator. In the loop the end() is implicitly wrapped, which tries to dereference a nullptr. My fix checks to ensure that the non-const iterator is not null before trying blindly dereference it. --- src/db/db/dbLayout.h | 9 +++++++-- src/tl/tl/tlClassRegistry.cc | 29 +++++++++++++++-------------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/db/db/dbLayout.h b/src/db/db/dbLayout.h index 450f8ba80..222860458 100644 --- a/src/db/db/dbLayout.h +++ b/src/db/db/dbLayout.h @@ -192,8 +192,13 @@ public: * @brief Default constructor */ cell_list_const_iterator (cell_list_iterator iter) - : mp_cell (& (*iter)) - { } + { + if (iter == cell_list_iterator()) { + mp_cell = nullptr; + } else { + mp_cell = &(*iter); + } + } /** * @brief Equality diff --git a/src/tl/tl/tlClassRegistry.cc b/src/tl/tl/tlClassRegistry.cc index b208dc5b2..a02311d5b 100644 --- a/src/tl/tl/tlClassRegistry.cc +++ b/src/tl/tl/tlClassRegistry.cc @@ -23,35 +23,36 @@ #include "tlClassRegistry.h" -#include +#include +#include +#include namespace tl { -struct ti_compare_f -{ - bool operator() (const std::type_info *a, const std::type_info *b) const - { - return a->before (*b); - } -}; +typedef std::map inst_map_type; -typedef std::map inst_map_type; -static inst_map_type s_inst_map; +// Used to fix https://en.cppreference.com/w/cpp/language/siof segfault +// on some systems. +inst_map_type& s_inst_map() { + static inst_map_type s_inst_map; + return s_inst_map; +} TL_PUBLIC void set_registrar_instance_by_type (const std::type_info &ti, RegistrarBase *rb) { if (rb) { - s_inst_map[&ti] = rb; + s_inst_map()[std::type_index(ti)] = rb; } else { - s_inst_map.erase (&ti); + s_inst_map().erase (std::type_index(ti)); } } TL_PUBLIC RegistrarBase *registrar_instance_by_type (const std::type_info &ti) { - inst_map_type::const_iterator im = s_inst_map.find (&ti); - if (im != s_inst_map.end ()) { + inst_map_type map = s_inst_map(); + inst_map_type::const_iterator im = map.find (std::type_index(ti)); + if (im != map.end ()) { return im->second; } else { return 0;