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.
This commit is contained in:
Ethan Mahintorabi 2022-12-12 19:03:59 +00:00
parent 92d0174711
commit 0a03a2809a
No known key found for this signature in database
GPG Key ID: 824E41B920BEA252
2 changed files with 22 additions and 16 deletions

View File

@ -192,8 +192,13 @@ public:
* @brief Default constructor * @brief Default constructor
*/ */
cell_list_const_iterator (cell_list_iterator<cell_type> iter) cell_list_const_iterator (cell_list_iterator<cell_type> iter)
: mp_cell (& (*iter)) {
{ } if (iter == cell_list_iterator<cell_type>()) {
mp_cell = nullptr;
} else {
mp_cell = &(*iter);
}
}
/** /**
* @brief Equality * @brief Equality

View File

@ -23,35 +23,36 @@
#include "tlClassRegistry.h" #include "tlClassRegistry.h"
#include <map> #include <unordered_map>
#include <typeinfo>
#include <typeindex>
namespace tl namespace tl
{ {
struct ti_compare_f typedef std::map<std::type_index, RegistrarBase *> inst_map_type;
{
bool operator() (const std::type_info *a, const std::type_info *b) const
{
return a->before (*b);
}
};
typedef std::map<const std::type_info *, RegistrarBase *, ti_compare_f> inst_map_type; // Used to fix https://en.cppreference.com/w/cpp/language/siof segfault
static inst_map_type s_inst_map; // 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) TL_PUBLIC void set_registrar_instance_by_type (const std::type_info &ti, RegistrarBase *rb)
{ {
if (rb) { if (rb) {
s_inst_map[&ti] = rb; s_inst_map()[std::type_index(ti)] = rb;
} else { } 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) TL_PUBLIC RegistrarBase *registrar_instance_by_type (const std::type_info &ti)
{ {
inst_map_type::const_iterator im = s_inst_map.find (&ti); inst_map_type map = s_inst_map();
if (im != s_inst_map.end ()) { inst_map_type::const_iterator im = map.find (std::type_index(ti));
if (im != map.end ()) {
return im->second; return im->second;
} else { } else {
return 0; return 0;