Skip to content

Instantly share code, notes, and snippets.

@flavio-fernandes
Created December 24, 2019 21:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save flavio-fernandes/666a45cab1e3b9212813e9b6539afbc7 to your computer and use it in GitHub Desktop.
Save flavio-fernandes/666a45cab1e3b9212813e9b6539afbc7 to your computer and use it in GitHub Desktop.
#include <string.h>
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
/************************* WiFi Access Point *********************************/
//#include "ssidConfig.h"
#define WLAN_SSID "wifissid" // Your WiFi AP.
#define WLAN_PASS "superSecret" // Your WiFi AP password.
#define MQTT_SERVER "192.168.1.1" // Address of MQTT server.
#define MQTT_PORT 1883 // Standard MQTT port 1883.
#define MQTT_USERNAME "" // Set to any username for the MQTT server (default none/empty).
#define MQTT_PASSWORD "" // MQTT user password (default none/empty).
/************ Global State (you don't need to change this!) ******************/
// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, MQTT_SERVER, MQTT_PORT, MQTT_USERNAME, MQTT_PASSWORD);
/****************************** Feeds ***************************************/
// Setup a feed for publishing.
Adafruit_MQTT_Publish foo_pub_topic = Adafruit_MQTT_Publish(&mqtt, "/feeds/foo");
// Setup a feed for subscribing to changes.
Adafruit_MQTT_Subscribe foo_sub_topic = Adafruit_MQTT_Subscribe(&mqtt, "/feeds/foo");
// A buffer that has more data than the send packet can handle. It will cause
// a nasty memory corruption. This space has to be big enough to hold the entire
// MQTT packet, which is definitely not going to happen in this example.
char tooMuchData[MAXBUFFERSIZE + 10];
/*************************** Sketch Code ************************************/
// Bug workaround for Arduino 1.6.6, it seems to need a function declaration
// for some reason (only affects ESP8266, likely an arduino-builder bug).
void MQTT_connect();
void setup() {
Serial.begin(115200);
delay(10);
// Fill tooMuchData with 'x'
memset(tooMuchData, 'x', sizeof(tooMuchData));
tooMuchData[sizeof(tooMuchData) - 1] = 0;
Serial.println(F("Adafruit MQTT memory corruption bug demo"));
// Connect to WiFi access point.
Serial.println(); Serial.println();
Serial.print("Connecting to ");
Serial.println(WLAN_SSID);
// Set WiFi to station mode
WiFi.mode(WIFI_STA);
WiFi.begin(WLAN_SSID, WLAN_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.println("IP address: "); Serial.println(WiFi.localIP());
// Setup MQTT subscription for sub_topic feed.
mqtt.subscribe(&foo_sub_topic);
}
void loop() {
// Ensure the connection to the MQTT server is alive (this will make the first
// connection and automatically reconnect when disconnected). See the MQTT_connect
// function definition further below.
MQTT_connect();
// Publish a buffer so big, it will corrupt the members of the mqtt
// instance. That includes the subscription member. Boom! :) :)
Serial.print(F("\nSending foo_pub_topic val "));
Serial.print("...");
if (! foo_pub_topic.publish(tooMuchData)) {
Serial.println(F("Failed"));
} else {
Serial.println(F("OK!"));
}
delay(3000);
// Now try to look at packets we subscribed to and see it
// hit a LoadProhibited exception.
Adafruit_MQTT_Subscribe *subscription;
while ((subscription = mqtt.readSubscription(5000))) {
if (subscription == &foo_sub_topic) {
Serial.print(F("Got: "));
Serial.println((char *)foo_sub_topic.lastread);
}
}
// Will likely never make it here if you have bug described in
// https://github.com/adafruit/Adafruit_MQTT_Library/issues/122
Serial.println(F("Bug must have been fixed. Nice!"));
}
// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
int8_t ret;
// Stop if already connected.
if (mqtt.connected()) {
return;
}
Serial.print("Connecting to MQTT... ");
uint8_t retries = 3;
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 5 seconds...");
mqtt.disconnect();
delay(5000); // wait 5 seconds
retries--;
if (retries == 0) {
// basically die and wait for WDT to reset me
while (1);
}
}
Serial.println("MQTT Connected!");
}
@flavio-fernandes
Copy link
Author

NOTE: See below the log for stack trace

13:49:39.367 -> .........
13:49:44.140 -> WiFi connected
13:49:44.140 -> IP address: 
13:49:44.140 -> 192.168.10.116
13:49:44.140 -> Connecting to MQTT... MQTT Connected!
13:49:44.177 -> 
13:49:44.177 -> Sending foo_pub_topic val ...OK!
13:49:47.196 -> 
13:49:47.196 -> Exception (28):
13:49:47.196 -> epc1=0x4000bf64 epc2=0x00000000 epc3=0x00000000 excvaddr=0x0028459b depc=0x00000000
13:49:47.196 -> 
13:49:47.196 -> >>>stack>>>
13:49:47.196 -> 
13:49:47.196 -> ctx: cont
13:49:47.196 -> sp: 3ffffdb0 end: 3fffffc0 offset: 01a0
13:49:47.196 -> 3fffff50:  40105065 00284598 3ffee70c 00000000  
13:49:47.196 -> 3fffff60:  00000095 00000030 00000bb8 00000000  
13:49:47.196 -> 3fffff70:  3ffee512 0028459b 00000bb8 40203a7b  
13:49:47.196 -> 3fffff80:  40204035 00000bb8 3ffee6b0 3ffee6b0  
13:49:47.196 -> 3fffff90:  3fffdad0 00000000 3ffee638 4020125f  
13:49:47.229 -> 3fffffa0:  3fffdad0 00000000 3ffee670 40203b90  
13:49:47.229 -> 3fffffb0:  feefeffe feefeffe 3ffe84e8 40100b8d  
13:49:47.229 -> <<<stack<<<
13:49:47.229 -> 
13:49:47.229 ->  ets Jan  8 2013,rst cause:2, boot mode:(3,6)
13:49:47.229 -> 
13:49:47.229 -> load 0x4010f000, len 1392, room 16 
13:49:47.266 -> tail 0
13:49:47.266 -> chksum 0xd0
13:49:47.266 -> csum 0xd0
13:49:47.266 -> v3d128e5c
13:49:47.266 -> ~ld
13:49:47.302 -> Adafruit MQTT memory corruption bug demo
13:49:47.302 -> 
13:49:47.302 -> 
13:49:47.302 -> Connecting to wifissid
13:49:47.863 -> .......

Details from ESP Exception Decoder

Exception 28: LoadProhibited: A load referenced a page mapped with an attribute that does not permit loads
PC: 0x4000bf64
EXCVADDR: 0x0028459b

Decoding stack results
0x40203a7b: __esp_yield() at /Users/flaviof/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/core_esp8266_main.cpp line 107
0x40204035: __delay(unsigned long) at /Users/flaviof/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/core_esp8266_wiring.cpp line 57
0x4020125f: loop() at /Users/flaviof/Desktop/mqtt_bug/mqtt_bug.ino line 96
0x40203b90: loop_wrapper() at /Users/flaviof/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/core_esp8266_main.cpp line 180

@flavio-fernandes
Copy link
Author

This is what you are going to see if you use the proposed fix (PR166) and compiling with:

#define MQTT_DEBUG

Output:

14:02:54.753 -> Connecting to wifissid
14:02:55.316 -> .........
14:03:00.163 -> WiFi connected
14:03:00.163 -> IP address: 
14:03:00.163 -> 192.168.10.116
14:03:00.163 -> Added sub 0
14:03:00.163 -> Connecting to MQTT... Connecting to: 192.168.10.238
14:03:00.163 -> Connect result: 1
14:03:00.163 -> SERVER GENERATING CLIENT ID
14:03:00.163 -> MQTT connect packet:
14:03:00.163 ->       [0x10],   [0x0C],   [0x00],   [0x04], M [0x4D], Q [0x51], T [0x54], T [0x54], 
14:03:00.163 ->       [0x04],   [0x02],   [0x01], , [0x2C],   [0x00],   [0x00], 
14:03:00.163 -> Client sendPacket returned: 14
14:03:00.163 -> Read data:          [0x20], 
14:03:00.163 -> Packet Type:          [0x20], 
14:03:00.163 -> Read data:          [0x02], 
14:03:00.163 -> Packet Length:    2
14:03:00.163 -> Read data:          [0x00],   [0x00], 
14:03:00.163 -> MQTT subscription packet:
14:03:00.163 ->       [0x82],   [0x0F],   [0x00],   [0x00],   [0x00],   [0x0A], / [0x2F], f [0x66], 
14:03:00.163 ->     e [0x65], e [0x65], d [0x64], s [0x73], / [0x2F], f [0x66], o [0x6F], o [0x6F], 
14:03:00.163 ->       [0x00], 
14:03:00.163 -> Client sendPacket returned: 17
14:03:00.163 -> Read data:          [0x90], 
14:03:00.163 -> Packet Type:          [0x90], 
14:03:00.163 -> Read data:          [0x03], 
14:03:00.163 -> Packet Length:    3
14:03:00.163 -> Read data:          [0x00],   [0x00],   [0x00], 
14:03:00.163 -> MQTT Connected!
14:03:00.163 -> 
14:03:00.163 -> Sending foo_pub_topic val ...MQTT publish packet (length: 150):
14:03:00.163 ->     0 [0x30],   [0x96],   [0x01],   [0x00],   [0x0A], / [0x2F], f [0x66], e [0x65], 
14:03:00.271 ->     e [0x65], d [0x64], s [0x73], / [0x2F], f [0x66], o [0x6F], o [0x6F], x [0x78], 
14:03:00.271 ->     x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], 
14:03:00.271 ->     x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], 
14:03:00.271 ->     x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], 
14:03:00.271 ->     x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], 
14:03:00.271 ->     x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], 
14:03:00.271 ->     x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], 
14:03:00.271 ->     x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], 
14:03:00.271 ->     x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], 
14:03:00.271 ->     x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], 
14:03:00.271 ->     x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], 
14:03:00.271 ->     x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], 
14:03:00.271 ->     x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], 
14:03:00.305 ->     x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], 
14:03:00.305 ->     x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], 
14:03:00.305 ->     x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], 
14:03:00.305 ->     x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], 
14:03:00.305 ->     x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], x [0x78], 
14:03:00.305 -> Client sendPacket returned: 150
14:03:00.305 -> OK!
14:03:08.410 -> Bug must have been fixed. Nice!
14:03:08.410 ->

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment