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
*/
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

View File

@ -23,35 +23,36 @@
#include "tlClassRegistry.h"
#include <map>
#include <unordered_map>
#include <typeinfo>
#include <typeindex>
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<std::type_index, RegistrarBase *> inst_map_type;
typedef std::map<const std::type_info *, RegistrarBase *, ti_compare_f> 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;