arduino / ArduinoCore-mbed

347 stars 200 forks source link

Moving one EthernetClient object to another crashes the Portenta H7 #715

Open xmkg opened 1 year ago

xmkg commented 1 year ago

As the title says. Reproducer sketch:

#include <Ethernet.h>

// --------------------------------------------------------------------------------
// remove_reference

template<typename T>
struct remove_reference {
  typedef T type;
};

template<typename T>
struct remove_reference<T &> {
  typedef T type;
};

template<typename T>
struct remove_reference<T &&> {
  typedef T type;
};

#define MOVE(...) \
  static_cast<typename remove_reference<decltype(__VA_ARGS__)>::type &&>( \
    __VA_ARGS__)

void setup() {
  EthernetClient ec = {};
  EthernetClient ec2{ MOVE(ec) };  // Crashes the board
}

void loop() {}
xmkg commented 1 year ago

It seems like it's not exclusive to moving. Copying also has the same effect:

void setup() {
  EthernetClient ec = {};
  EthernetClient ec2{ ec };  // Crashes the board
}
hwmaier commented 1 year ago

I have the same issue with verion 4.0.8.

I believe this bug makes it impossible to use the Ethernet server accepting Ethernet client connections using the standard implementation:

        client = server.available();
        if (client) {
           ...

which tries to return an EthernetClient object from the available() call which is internally created using a copy constructor.

I tracked it down to arduino::MbedClient::setSocket() trying to configure a nullptr socket with this possible fix:

void arduino::MbedClient::setSocket(Socket *_sock) {
  sock = _sock;
  if (sock != nullptr) // Configure only if not null
      configureSocket(sock);
}