I am trying to create a http endpoint that writes the provided user data to the http connection.
See the following example:
static void httpHandler(struct mg_connection *c, int ev, void *p, void *user_data) {
mg_send_response_line(c, 200,"Content-Type: text/plain; charset=utf-8\r\n");
mg_printf(c, "%s", (char*)user_data);
c->flags |= (MG_F_SEND_AND_CLOSE);
}
void registerHttpEndpoint() {
char* data = (char*)malloc(6);
sprintf(data, "hello");
mgos_register_http_endpoint("/test", httpHandler, data);
}
When I send a GET request to the endpoint, I see hello
in the browser and everything works as expected except the firmware crashes.
This is what I see in the log:
[May 19 10:58:35.871] mgos_http_server.c:180 0x3ffd196c HTTP connection from 192.168.128.30:45410
[May 19 10:58:35.880] Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
[May 19 10:58:35.885]
[May 19 10:58:35.885] Core 1 register dump:
[May 19 10:58:35.888] PC : 0x400014fd PS : 0x00060030 A0 : 0x8010fff0 A1 : 0x3ffb9410
[May 19 10:58:35.896] A2 : 0x00000000 A3 : 0xfffffffc A4 : 0x000000ff A5 : 0x0000ff00
[May 19 10:58:35.905] A6 : 0x00ff0000 A7 : 0xff000000 A8 : 0x00000000 A9 : 0x3ffb93e0
[May 19 10:58:35.910] A10 : 0x3ffb7ca4 A11 : 0x00000005 A12 : 0x00000000 A13 : 0x00000000
[May 19 10:58:35.918] A14 : 0x00000000 A15 : 0x3ffd0f88 SAR : 0x00000001 EXCCAUSE: 0x0000001c
[May 19 10:58:35.927] EXCVADDR: 0x00000000 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xffffffff
[May 19 10:58:35.935]
[May 19 10:58:35.935] Backtrace:0x400014fa 0x4010ffed 0x4011979a 0x401197d6 0x4017189b 0x4017239d 0x401723e1 0x400d8be1 0x401748c5 0x40175296 0x401748c5 0x40175cca 0x40175daa 0x40179085 0x40185b09 0x401705e5 0x40082999 0x400828a3
[May 19 10:58:35.952]
[May 19 10:58:35.952]
[May 19 10:58:35.954] ELF file SHA256: 538e70cc2bc815ef
[May 19 10:58:35.957]
[May 19 10:58:35.957]
[May 19 10:58:35.957] --- BEGIN CORE DUMP ---
[May 19 10:58:35.960] mos: catching core dump
[May 19 10:58:38.797] ...
This happens if I try to access the user_data
pointer in any way. It doesn’t matter if it is printing in the log or calling strlen((char*)user_data)
or whatever. If I try to access the pointer, the firmware crashes after the method returns. The backtrace points to the line where the pointer was referenced even though the entire method will run before the crash. The pointer is never freed so the string should be allocated on the stack.
I don’t understand this behavior at all and I’m hoping someone can point me in the right direction. Surely this should work. There would be no point in having a user_data
parameter if it cannot be used!