martin-ger / MQTT_VPN

IP over MQTT for ESP controllers and Linux
135 stars 28 forks source link

pbuf_free exception after a few MQTT request/response #12

Open garudaonekh opened 2 years ago

garudaonekh commented 2 years ago

This error happen after a few MQTT request/response. However, if I remove MQTT the code program work fine.

"ERROR Message" assertion "pbuf_free: p->ref > 0" failed: file "/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/lwip/lwip/src/core/pbuf.c", line 766, function: pbuf_free abort() was called at PC 0x4010df83 on core 0

The error decoder point it to: 0x400da8e1: packet_receive_handler at /Users/***/-Firmware-master/mqttif.c:350

After several days failure to find out the real issue, it look like the problem is here

static void packet_receive_handler(void* handler_args, esp_event_base_t base, int32_t id, void* event_data)
{ ...
if (mqtt_if->netif.input(pb, &mqtt_if->netif) != ERR_OK)
...

The hard part for me is that it happen randomly after several MQTT message received.

garudaonekh commented 2 years ago

Sometimes, I got this exception. Thus, I am not sure if they are the same problem as I don't understand this C much.

0x40152b91: tcp_output at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/lwip/lwip/src/core/tcp_out.c:1153
0x400014fd: ?? ??:0
0x4000150d: ?? ??:0
0x40152b91: tcp_output at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/lwip/lwip/src/core/tcp_out.c:1153
0x4014965d: tcp_slowtmr at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/lwip/lwip/src/core/tcp.c:1765
0x4014b97a: tcp_tmr at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/lwip/lwip/src/core/tcp.c:1765
0x4014c437: tcpip_tcp_timer at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/lwip/lwip/src/core/timeouts.c:381
0x4014c325: sys_check_timeouts at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/lwip/lwip/src/core/timeouts.c:381
0x4014c52c: sys_timeouts_mbox_fetch at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/lwip/lwip/src/core/timeouts.c:433
0x40144dc8: tcpip_thread at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/lwip/lwip/src/api/tcpip.c:483
0x4008a56a: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c:355 (discriminator 1)
0
garudaonekh commented 2 years ago

After several days of failure to figure out the problem, I go back to a simple example to isolate the issue, anyhow, it also crashed if I make rapid call.

I think it's due to if (mqtt_if->netif.input(pb, &mqtt_if->netif) != ERR_OK)

Maybe need to make put some delay or something....

Here's my code: `#include

include

include

include

include "mqttif.h"

ifndef STASSID

define STASSID "XXXisal"

define STAPSK "xxxx"

endif

// VPN settings char broker = "mqtt://mybroker:1883"; char mqtt_user = ""; char mqtt_password = ""; char vpn_password = "secret";

ip4_addr_t ipaddr; ip4_addr_t netmask; ip4_addr_t gw;

const char ssid = STASSID; const char password = STAPSK;

WebServer server(80);

const int led = 2; int k=0; void handleRoot() { digitalWrite(led, 1); Serial.print(".|."); //delay(10); String ss="lkaskl dsjklasd sfjk safsfja jsfk klfsajkjfskf ljskjlsa kjfs saj sakjfs lkaskl dsjklasd sfjk safsfja jsfk klfsajkjfskf ljskjlsa kjfs saj sakjfs lkaskl dsjklasd sfjk safsfja jsfk klfsajkjfskf ljskjlsa kjfs ";

int x=k%8+2; k++; for(int i=0;i<x;i++) ss+=ss;

server.send(200, "text/plain", "hello from esp8266!"+ss); digitalWrite(led, 0); }

void setup(void) { IP4_ADDR(&ipaddr, 10,0,1,2); IP4_ADDR(&netmask, 255,255,255,255); IP4_ADDR(&gw, 0,0,0,0);

pinMode(led, OUTPUT); digitalWrite(led, 0); 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());

mqtt_vpn_if_init(broker, mqtt_user, mqtt_password, "mqttip", vpn_password, ipaddr, netmask, gw);

if (MDNS.begin("esp32")) { Serial.println("MDNS responder started"); }

server.on("/", handleRoot);

server.on("/inline", []() { server.send(200, "text/plain", "this works as well"); });

server.begin(); Serial.println("HTTP server started"); }

void loop(void) { server.handleClient(); }`

The decoded stack trace

`
Decoding stack results
0x400880c4: invoke_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 156
0x40088341: abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/panic.c line 171
0x40131813: __assert_func at ../../../.././newlib/libc/stdlib/assert.c line 63
0x4011ab12: lwip_netconn_do_writemore at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/lwip/lwip/src/api/api_msg.c line 1673
0x4011b02f: sent_tcp at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/lwip/lwip/src/api/api_msg.c line 403
0x4012fff1: tcp_input at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/lwip/lwip/src/core/tcp_in.c line 402
0x40128b83: ip4_input at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/lwip/lwip/src/core/ipv4/ip4.c line 750
0x401209c8: ip_input at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/lwip/lwip/src/core/ip.c line 117
0x400d1350: packet_receive_handler at /Users/MQTT_VPN_ESP32-main/mqtt_vpn_webserver/mqtt_vpn_webserver_gui/mqttif.c line 135
0x4017072d: handler_execute at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_event/esp_event.c line 132
0x400f9cfe: esp_event_loop_run at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_event/esp_event.c line 553
0x400f9dad: esp_event_loop_run_task at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_event/esp_event.c line 113
0x40089342: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143`
chou-o-ning commented 4 months ago

I face the same issue and fix it in the description below:

mqtt_vpn_esp32/main/mqttif.c

struct mqtt_if_data mqtt_if_add(esp_mqtt_client_handle_t cl, char topic_prefix) { .... .... netif_add(&data->netif, NULL, NULL, NULL, data, mqtt_if_init, ip_input); --> netif_add(&data->netif, NULL, NULL, NULL, data, mqtt_if_init, tcpip_input); .... }

tcpip_input() throw packets to lwip tcp/ip thread by xQueueSend(), so it's safe in ESP32 freertos envirement.