Почему SEGFAULT возникает при вызове функции класса шаблона? - PullRequest
0 голосов
/ 17 октября 2019

ПРИМЕЧАНИЕ: его проблема связана с проблемой Gazebo, касающейся разрушения объекта GpuLaserPlugin - для оригинальной проблемы см. здесь , где также есть инструкции по воспроизведению проблемы)

У меня возникла проблема с ошибкой при попытке уничтожить объект Connection:

class GZ_COMMON_VISIBLE Connection
{
  public: Connection(Event *_e, const int _i);
  public: ~Connection();
  // Get the id of this connection.
  // The id of this connection.
  public: int Id() const;
  // The event for this connection
  private: Event *event = nullptr;
  private: int id = -1;
  private: common::Time creationTime;
  public: template<typename T> friend class EventT;
};

Деструктор вызывает Disconnect() из шаблона класса EventT, потомкаEvent класс:

class GZ_COMMON_VISIBLE Event
{
  public: Event();
  public: virtual ~Event();
  public: virtual void Disconnect(int _id) = 0;
  public: bool Signaled() const;
  public: void SetSignaled(const bool _sig);
  private: bool signaled;
};

...

template<typename T>
class EventT : public Event
{
  public: EventT();
  public: virtual ~EventT();
  public: ConnectionPtr Connect(const std::function<T> &_subscriber);
  public: virtual void Disconnect(int _id);

...

}

...

void EventT<T>::Disconnect(int _id)
{
  printf("Start disconnect \n");                                //for debug

  // Find the connection
  auto const &it = this->connections.find(_id);

  if (it != this->connections.end())
  {
    it->second->on = false;
    this->connectionsToRemove.push_back(it);
  }
  printf("End disconnect \n");                                  //for debug
}

Деструктор Connection:

Connection::~Connection()
{
  gzwarn << "Start destructor \n";                                  //for debug

  if (this->event && this->id >= 0)
  {
    this->event->SetSignaled(true);
    bool eventBool = this->event->Signaled();                       //for debug
    std::cout << "ID value is " << this->id << std::endl;           //for debug
    std::cout << "Event bool value is " << eventBool << std::endl;  //for debug
    std::cout << typeid(this->event).name() << std::endl;           //for debug
    this->event->Disconnect(this->id);
    this->id = -1;
    this->event = nullptr;
  }
  gzwarn << "End destructor \n";                                    //for debug
}

К сожалению, когда вызывается Disconnect(), возникает ошибка (возможна полная обратная трассировка здесь )

Я проверил, что id и event переменные-члены все еще существуют, печатая их значения и тип события перед вызовом функции:

[Wrn] [Event.cc:60] Start destructor 
ID value is 0
Event bool value is 1
PN6gazebo5event5EventE

Thread 1 "gzserver" received signal SIGSEGV, Segmentation fault.
0x000055555719fd20 in ?? ()

Что кажется страннымдля меня это то, что SEGFAULT происходит где-то после вызова функции Disconnect() , но перед тем, как фактически войти в него (потому что оператор отладки Start disconnect никогда не печатается), что указывает на то, что проблема заключается в id или event, хотя согласно выводу они должны существовать.

Может ли кто-нибудь пролить свет на то, почему вызов этой функции вызывает SEGFAULT?

...