Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WifiClient exception 29 #4488

Closed
s0170071 opened this issue Mar 9, 2018 · 14 comments
Closed

WifiClient exception 29 #4488

s0170071 opened this issue Mar 9, 2018 · 14 comments

Comments

@s0170071
Copy link

s0170071 commented Mar 9, 2018

Basic Infos

  • [x ] This issue complies with the issue POLICY doc.

  • [x ] I have read the documentation at readthedocs and the issue is not addressed there.

  • [x ] I have tested that the issue is present in current master branch (aka latest git).

  • [x ] I have searched the issue tracker for a similar issue.

  • [ x] If there is a stack dump, I have decoded it.

  • [x ] I have filled out all fields below.

Platform

  • Hardware: [ESP-12]
  • Core Version: latest
  • Development Env: [Arduino IDE]
  • Operating System: [Ubuntu]

Settings in IDE

  • Module: [Wemos D1 mini r2]
  • Flash Mode: [dio]
  • Flash Size: [4MB]
  • lwip Variant: [v2 Lower Memory]
  • Reset Method: [ck|nodemcu]
  • Flash Frequency: [40Mhz]
  • CPU Frequency: [80Mhz]
  • Upload Using: [SERIAL]
  • Upload Speed: [115200] (serial upload only)

Problem Description

This issue is related to #4487.
What changed is that I now have two instances of the SMA class which means I do have two instances of the WiFiClient too.

Sketch difference to #4487 is pretty much just the fact that I instantiated the class twice :


  mySMA = new SMA;
  mySMA2 = new SMA;
  dummy[1]=0;
}

void loop ( void ) {
 
  delay(100); 
  Serial.println(ESP.getFreeHeap());
  mySMA->handleTXRX();
  mySMA2->handleTXRX();
}

It does drain the memory twice as fast but instead of stalling, it is throwing an exception:

connect 192.168.1.41 OK, sending: 0 1 0 0 0 6 126 4 157 7 0 1
connect 192.168.1.41 fail.
1328
1160
reading bytes: 0 1 0 0 0 5 126 4 2 16 16 pow: -32768
1328
1328
1328
1328
1328
1328
1328
1328
1328
connect 192.168.1.41 OK, sending: 0 1 0 0 0 6 126 4 157 7 0 1


Exception (29):
epc1=0x40202e7b epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

ctx: cont 
sp: 3fff8330 end: 3fff8590 offset: 01a0

>>>stack>>>
3fff84d0:  7a797877 00000001 3ffe8b65 40202e79  
3fff84e0:  2901a8c0 00000001 3fff8521 3fff9209  
3fff84f0:  c02363d8 0000003e 3fff92d4 3ffe84dc  
3fff8500:  3fff92bc 000001f6 3fff92bc 40202a20  
3fff8510:  401070b0 2901a8c0 401070b0 2901a8c0  
3fff8520:  3ffe88a3 00000004 3fff91fc 3fff755c  
3fff8530:  3fff92bc 3fff92d4 3fff9294 402022d0  
3fff8540:  00000000 00000000 3fff749c 40203670  
3fff8550:  402033f0 00000064 00000064 3fff755c  
3fff8560:  3fffdad0 00000000 3fff7554 402024fc  
3fff8570:  3fffdad0 00000000 3fff7554 40203cec  
3fff8580:  feefeffe feefeffe 3fff7570 401006ed  
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16 
tail 8
chksum 0x2d
csum 0x2d
v3b269c4a
~ld


Exception 29: StoreProhibited: A store referenced a page mapped with an attribute that does not permit stores
Decoding 12 results
0x40202e7b: ClientContext at /home/john/ArduinoPortable/arduino-1.8.5_ESPgit/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp line 371
:  (inlined by) WiFiClient::connect(IPAddress, unsigned short) at /home/john/ArduinoPortable/arduino-1.8.5_ESPgit/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp line 137
0x40202e79: WiFiClient::connect(IPAddress, unsigned short) at /home/john/ArduinoPortable/arduino-1.8.5_ESPgit/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp line 371
0x40202a20: WiFiClient::connect(char const*, unsigned short) at /home/john/ArduinoPortable/arduino-1.8.5_ESPgit/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.cpp line 371
0x401070b0: gdb_init at ?? line ?
0x401070b0: gdb_init at ?? line ?
0x402022d0: SMA::handleTXRX() at /home/john/Arduino/scetchbooks/clientmemloss/clientmemloss.ino line 71
0x40203670: Print::println() at /home/john/ArduinoPortable/arduino-1.8.5_ESPgit/hardware/esp8266com/esp8266/cores/esp8266/Print.cpp line 99
0x402033f0: EspClass::getFreeHeap() at /home/john/ArduinoPortable/arduino-1.8.5_ESPgit/hardware/esp8266com/esp8266/cores/esp8266/Esp.cpp line 165
0x402024fc: loop at /home/john/Arduino/scetchbooks/clientmemloss/clientmemloss.ino line 183
0x40203cec: loop_wrapper at /home/john/ArduinoPortable/arduino-1.8.5_ESPgit/hardware/esp8266com/esp8266/cores/esp8266/core_esp8266_main.cpp line 58
0x401006ed: cont_wrapper at /home/john/ArduinoPortable/arduino-1.8.5_ESPgit/hardware/esp8266com/esp8266/cores/esp8266/cont.S line 81



@s0170071
Copy link
Author

s0170071 commented Mar 9, 2018

It appears that the connection is not closed after the communication is done. client.stop() closes it, however, the issue remains.

@debsahu
Copy link

debsahu commented Mar 10, 2018

I am facing similar issues. Developing a library for esp8266 to talk to Twitter https://github.com/debsahu/TwitterWebAPI . Unfortunately, library works fine on 2.4.0 but after the upgrade to 2.4.1, I also get exception 29. I use WiFiSecureClient to send GET data and close the connection after every request. @igrr recommends to have only one client open due to the memory size. The recommendation is to use client.flush() and client.stop(), which I do and still get exception 29. Please help.

@s0170071
Copy link
Author

s0170071 commented Mar 10, 2018

I got it to work on 2.3.0 when I call tcpCleanup regularly.

struct tcp_pcb;
extern struct tcp_pcb* tcp_tw_pcbs;
extern "C" void tcp_abort (struct tcp_pcb* pcb);

void tcpCleanup()
{
         while(tcp_tw_pcbs!=NULL)
    {
      tcp_abort(tcp_tw_pcbs);
    }
 }

It does however not work with the current core and LWIP 1.4 (compile from source)

@igrr
Copy link
Member

igrr commented Mar 10, 2018

@s0170071 could you please upload a reproducer sketch? Thank you.

@s0170071
Copy link
Author

@igrr: please see #4487. Its the same sketch. This issue uses two instances of the SMA class which gives a different kind of error. The underlying problem seems to be a memory leak if the connection is not closed by the peer.
Beware, for the sketch to work you would need a responding peer. If the client can't connect or doesn't receive anything nothing happens.

@igrr
Copy link
Member

igrr commented Mar 10, 2018

Well, that was my point — I am not sure how exactly to modify the sketch to reproduce this issue. I would be grateful if you give instructions to reproduce, including how to implement the peer side.

@s0170071
Copy link
Author

ok, I just used another esp to respond with 11 bytes when contacted at port 502. They talk but I cannot reproduce the issue. But I observed that the connection is closed when the communication is done.
My SMA peer leaves the connection open.
Whats needed is a way to force the connection closure an freeing the allocated memory in the process.

@s0170071
Copy link
Author

Is there a way to make the server not close the connection? That could help to reproduce.

@igrr
Copy link
Member

igrr commented Mar 10, 2018

Maybe connect to an HTTP server and send a Connect: keep-alive header?

@s0170071
Copy link
Author

There is no such thing as headers when you play with modbus. And the client class has no method for headers :-)
I found a workaround that may work for me. Since I communicate cyclically I just check if the connection is still alive before calling connect() again.
Doesn't fix the issue though.

@s0170071
Copy link
Author

Nope. No real workaround. The leak is smaller but now and then it drops a few bytes... Slowly. Tested with latest git.

@debsahu
Copy link

debsahu commented Mar 10, 2018

Try adding client.setTimeout(time_ms) before client.connect(). Seems to solve my issues with exception 29.

EDIT: nevermind. It was a bit stable for ~10min.

@s0170071
Copy link
Author

@igrr Here is a server sketch that leaves the connection open. The trick is to just not send anything ;-)
Stupid but effective. You would have to match the IP in the client sketch to that server ESP. The client connects, sends and times out.

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <WiFiServer.h>
  
 const char *ssid = "...";
const char *password = "...";
WiFiServer server(502);
  

void setup ( void ) {
  Serial.begin ( 115200 );
  WiFi.mode ( WIFI_STA );
  WiFi.begin ( ssid, password );
  Serial.println ( "" );

  // Wait for connection
  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 );
    Serial.print ( "." );
  }

  Serial.println ( "" );
  Serial.print ( "Connected to " );
  Serial.println ( ssid );
  Serial.print ( "IP address: " );
  Serial.println ( WiFi.localIP() );

  server.begin();
  
 
}

void loop ( void ) {
 char dummy[12];
  WiFiClient client = server.available();
  if (client) {
    while (client.available()) client.read();
    Serial.println("new client");
    //client.write(dummy,11); // don't write to leave the connection open.
    //client.stop();
  
  }
  delay(100); 

}

Debug output of the client is:

.....
Connected to MNET
IP address: 192.168.1.36
45976
connect 192.168.1.9 OK, sending: 0 1 0 0 0 6 126 4 157 7 0 1 
44896
connect 192.168.1.9 OK, sending: 0 1 0 0 0 6 126 4 157 7 0 1 
timeout while receiving or too many bytes. 0
timeout while receiving or too many bytes. 0
45768
connect 192.168.1.9 OK, sending: 0 1 0 0 0 6 126 4 157 7 0 1 
44736
connect 192.168.1.9 OK, sending: 0 1 0 0 0 6 126 4 157 7 0 1 
timeout while receiving or too many bytes. 0
timeout while receiving or too many bytes. 0
45656
connect 192.168.1.9 OK, sending: 0 1 0 0 0 6 126 4 157 7 0 1 
44624
connect 192.168.1.9 OK, sending: 0 1 0 0 0 6 126 4 157 7 0 1 
timeout while receiving or too many bytes. 0
timeout while receiving or too many bytes. 0
45544
connect 192.168.1.9 OK, sending: 0 1 0 0 0 6 126 4 157 7 0 1 
44512
connect 192.168.1.9 OK, sending: 0 1 0 0 0 6 126 4 157 7 0 1 
timeout while receiving or too many bytes. 0
timeout while receiving or too many bytes. 0
45432


... until it stalls.

 
connect 192.168.1.9 fail. 
2312
connect 192.168.1.9 fail. 
2288
connect 192.168.1.9 fail. 
2312
connect 192.168.1.9 fail. 
2288
connect 192.168.1.9 fail. 
2312
connect 192.168.1.9 fail. 

@debsahu I tried that and also client.disableKeepAlive() but with little success

@igrr
Copy link
Member

igrr commented Mar 14, 2018

Closing, will track in #4497. Please follow the link to that issue and click "subscribe" to receive notifications.

@igrr igrr closed this as completed Mar 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants