ESP32: address to line number conversion

My sketch is crashing and producing a core dump on the monitor which is mostly gibberish to me. Is there any way to convert some of it to a line number in my Arduino sketch to better zero in on what's causing the problem? Thanks for any tips. Here's the dump in case it helps (the problem seems to be related to "dhcps: send_offerudp_sendto result 0"):

 Rebooting...
 ets Jun  8 2016 00:22:57
 
 rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
 configsip: 0, SPIWP:0xee
 clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
 mode:DIO, clock div:1
 load:0x3fff0018,len:4
 load:0x3fff001c,len:1216
 ho 0 tail 12 room 4
 load:0x40078000,len:9720
 ho 0 tail 12 room 4
 load:0x40080400,len:6352
 entry 0x400806b8
 dhcps: send_offerudp_sendto result 0
 Guru Meditation Error: Core  0 panic'ed (InstrFetchProhibited).
 Exception was unhandled.
 Core 0 register dump:
 PC      : 0x00000000  PS      : 0x00060e30  A0      : 0x8010fe9d  A1
    : 0x3ffb3b40
 A2      : 0x3ffcd270  A3      : 0x3ffcd4a4  A4      : 0x3ffcb51c  A5
    : 0x3ffcbe28
 A6      : 0x0201a8c0  A7      : 0x0c01a8c0  A8      : 0x8010fd40  A9
    : 0x3ffb3b00
 A10     : 0x3ffcd280  A11     : 0x3ffcd4a4  A12     : 0x3ffb3b4c  A13
    : 0x00000044
 A14     : 0x00000001  A15     : 0x00000006  SAR     : 0x00000010
 EXCCAUSE: 0x00000014
 EXCVADDR: 0x00000000  LBEG    : 0x4000c349  LEND    : 0x4000c36b  LCOUNT
    : 0x00000000
 
 Backtrace: 0x00000000:0x3ffb3b40 0x4010fe9a:0x3ffb3b80
 0x4011cd21:0x3ffb3ba0 0x40121d29:0x3ffb3be0 0x40126fc6:0x3ffb3c00
 0x401108a3:0x3ffb3c20 0x400886e1:0x3ffb3c50

No. Not without some really expensive in-circuit debuggers.

Post your sketch (code), schematic in CAD or a picture of a hand drawn circuit in jpg or png- (not a pretty Fritzing drawings)

Did it work before you made changes?
Does it compile without errors?
does it run for a while then crash?
Can you make it crash, for example when you press a button?

Thanks for offering to peruse my code. I pretty much cut-and-pasted it from a blog post on creating an ESP32 access point, but it only works sporadically. There’s not much to it, but it’s my first WiFi app so I’m still at the crawling stage.

It works most reliably when my board is running off USB power, but doesn’t work at all when running off an external power supply (5V). This seems to implicate the board, but the board vendor claims it crashes in both modes for him (I sent him the code and he ran it on some of his boards). So, it’s possibly a h/w problem, though I can run non-WiFi sketches on the same board without any problems.

// We run the ESP32 in soft access point mode, as a captive portal.  This means the ESP32
// will broadcast its own WIFi network to which the user must connect.  As soon as they
// select it from among the available networks shown on their access device (phone, PC, 
// tablet, etc.), their browser will load the web page contained in responseHTML.  No password
// or login required (though the page in their browser will be labelled "Log In"; don't
// know how to change that).  On this page they enter the configuration they want for Prime
// Time.  On hitting "Submit," their entries will be sent to the ESP32 and assigned to
// program variables.

const byte DNS_PORT = 53;
IPAddress apIP(192, 168, 1, 1);
DNSServer dnsServer;
WiFiServer server(80);

String responseHTML = ""
  "<!DOCTYPE html><html><head><title>Prime Time</title></head><body>"
  "<h1>Prime Time Configuration Page</h1>"
  "<p>This is a captive portal example. All requests will be redirected here.</p>"
  "</body></html>";

void setup() {
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  WiFi.softAP("Prime Time");

  // if DNSServer is started with "*" for domain name, it will reply with
  // provided IP to all DNS request
  dnsServer.start(DNS_PORT, "*", apIP);

  server.begin();
}

void loop() {
  dnsServer.processNextRequest();
  WiFiClient client = server.available();   // listen for incoming clients

  if (client) {
    String currentLine = "";
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (c == '\n') {
          if (currentLine.length() == 0) {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();
            client.print(responseHTML);
            break;
          } else {
            currentLine = "";
          }
        } else if (c != '\r') {
          currentLine += c;
        }
      }
    }
    client.stop();
  }
}

You don’t say how much data you are reading into currentLine, but I suspect that your problem is that you are using the evil String class.

The String class uses dynamic memory, and creates “holes” in the available RAM hat you can’t easily get back. In your loop, every time that currentLine is larger than previous uses, a new String object is created in an entirely different area of RAM.

The ESP32 has 512kB of RAM (unless you are using an ESP32 board with external RAM).

The best way is to use C strings, AKA, char arrays. there are ways to dynamically allocate and release the RAM used by C strings (malloc), but that’s above my pay grade.

If you know how large that currentLine can get, and if it’s below your available RAM, then you can do something like char currentLine[100]; to define currentLine to hold up to 100 characters. Since it’s an array, you just address each array element in sequence.

I can’t guarantee this will work because I am just coming off the String class habit myself. I do notice that you aren’t using currentLine anywhere.

// We run the ESP32 in soft access point mode, as a captive portal.  This means the ESP32
// will broadcast its own WIFi network to which the user must connect.  As soon as they
// select it from among the available networks shown on their access device (phone, PC,
// tablet, etc.), their browser will load the web page contained in responseHTML.  No password
// or login required (though the page in their browser will be labelled "Log In"; don't
// know how to change that).  On this page they enter the configuration they want for Prime
// Time.  On hitting "Submit," their entries will be sent to the ESP32 and assigned to
// program variables.

const byte DNS_PORT = 53;
IPAddress apIP(192, 168, 1, 1);
DNSServer dnsServer;
WiFiServer server(80);

String responseHTML = ""
  "<!DOCTYPE html><html><head><title>Prime Time</title></head><body>"
  "<h1>Prime Time Configuration Page</h1>"
  "<p>This is a captive portal example. All requests will be redirected here.</p>"
  "</body></html>";

char currentLine[100];   //Make room for 100 characters, 101 would likely crash the program.
int ptr=0;                     //This will point to the data in the char array: currentLine

void setup() {
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  WiFi.softAP("Prime Time");

  // if DNSServer is started with "*" for domain name, it will reply with
  // provided IP to all DNS request
  dnsServer.start(DNS_PORT, "*", apIP);

  server.begin();
}

void loop() {

  

  dnsServer.processNextRequest();
  WiFiClient client = server.available();   // listen for incoming clients

  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (c == '\n') {
          if (strlen(currentLine) == 0) {          //Is there any data in currentLine?
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();
            client.print(responseHTML);
            break;
          } else {
            ptr = 0;
            currentLine[ptr] = "\0";     //A zero at position 0 is the same as erasing the array.
          }
        } else if (c != '\r') {
          currentLine[ptr++]  c;      // Add the character to the array.
        }
      }
    }
    client.stop();
  }
}

(OK, Delta_g, what do I have wrong?)

Thanks, Steve. Not at my computer at the moment, but I’ll give it a shot tomorrow.