cJSON std::string heap corruption crash

rwel59
Posts: 97
Joined: Thu Oct 12, 2017 3:32 pm

cJSON std::string heap corruption crash

Postby rwel59 » Thu Mar 29, 2018 3:09 am

I just updated to latest version espidf + toolchain and am now crashing with what seems like the same or related error. The first log message prints the expected json object data. The next 2 log messages print fine. I crash every time before getting to last log message. config::network.hubIP is a std::string.

ESP_LOGI(TAG, "transformJSON SET_NETWORK 1: %s", obj.getString("hubIP").c_str());
std::string str = obj.getString("hubIP");
ESP_LOGI(TAG, "transformJSON SET_NETWORK 1a");
config::network.hubIP = "xx.xx.xx.x";
ESP_LOGI(TAG, "transformJSON SET_NETWORK 1b");
config::network.hubIP = obj.getString("hubIP");
ESP_LOGI(TAG, "transformJSON SET_NETWORK 2");

I've been using Kolban Snippets/cpp_utils for this routine for quite awhile.
std::string JsonObject::getString(std::string name) {
cJSON *node = cJSON_GetObjectItem(m_node, name.c_str());
return std::string(node->valuestring);
} // getString

CONSOLE ERRORS
assertion "heap != NULL && "free() target pointer is outside heap areas"" failed: file "/home/rick/esp/esp-idf/components/heap/./heap_caps.c", line 261, function: heap_caps_free
abort() was called at PC 0x400df407 on core 0
0x400df407: __assert_func at /Users/ivan/e/newlib_xtensa-2.2.0-bin/newlib_xtensa-2.2.0/xtensa-esp32-elf/newlib/libc/stdlib/../../../.././newlib/libc/stdlib/assert.c:63 (discriminator 8)

ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: cJSON std::string heap corruption crash

Postby ESP_Angus » Thu Mar 29, 2018 5:00 am

Hi rwel59,

I've split this off to a new topic because, although the symptoms are similar to this thread, you don't mention needing to enable any of the heap corruption detection features in order to reproduce the problem - which was the case with that bug. (Also, the bug mentioned in that thread has been fixed.)

Can you please post the full stack trace printed when ESP-IDF crashes with a corrupt heap message?

Diagnosing heap corruption bugs can be very hard because usually the bug happens somewhere a little while before the actual crash. A number of strategies for chasing heap corruption issues can be found here: https://esp-idf.readthedocs.io/en/lates ... corruption

Angus

rwel59
Posts: 97
Joined: Thu Oct 12, 2017 3:32 pm

Re: cJSON std::string heap corruption crash

Postby rwel59 » Fri Mar 30, 2018 12:58 am

Angus,
attached is full console log where heap corruption starts. This code was working fine before recent update to espidf, toolchain with a few exceptions - I've seen it a couple of times in the past but ignored it. Now it happens every time I go through this cycle. This is the code that is failing... when I uncomment the 'getString' lines, it fails. When they are commented out and I leave just the getInt() lines, I do not get a failure
EDIT: just noticed that this is a different error from the original post. It is in the exact same spot as before but I made some changes to the struct variable thinking that may be the cause. I'll have to go back and do some more work to see if I can get a consistent error.
case SET_NETWORK:
ESP_LOGI(TAG, "transformJSON::setSettings: %d", heap_caps_check_integrity_all(true));
//setup.network.hubIP = obj.getString("hubIP");
ESP_LOGI(TAG, "transformJSON::setSettings 1");
//setup.network.hubPwd = obj.getString("hubPwd");
ESP_LOGI(TAG, "transformJSON::setSettings 2");
setup.network.hubPort = obj.getInt("hubPort");
ESP_LOGI(TAG, "transformJSON::setSettings 3");
//setup.network.webIP = obj.getString("webIP");
ESP_LOGI(TAG, "transformJSON::setSettings 4");
setup.network.webPwd = obj.getString("webPwd");
ESP_LOGI(TAG, "transformJSON::setSettings 5");
setup.network.webPort = obj.getInt("webPort");
ESP_LOGI(TAG, "transformJSON::setSettings 6");


CONSOLE OUTPUT
I (51091) transformJSON: transformJSON::setSettings: 22, {"hubIP":"fgggg","hubPort":3011,"hubPwd":"hggg","webIP":"","webPort":1883,"wifi":[]}
I (51104) transformJSON: transformJSON::setSettings: 1
I (51108) transformJSON: transformJSON::setSettings 1
I (51113) transformJSON: transformJSON::setSettings 2
I (51118) transformJSON: transformJSON::setSettings 3
I (51123) transformJSON: transformJSON::setSettings 4
Guru Meditation Error: Core 1 panic'ed (LoadProhibited)
. Exception was unhandled.
Core 1 register dump:
PC : 0x401612ac PS : 0x00060930 A0 : 0x800da2ed A1 : 0x3fff18b0
0x401612ac: JsonObject::getString(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) at /home/rick/eclipse-test/OldOrb/components/cpp_utils/./JSON.cpp:287

A2 : 0x3fff1d48 A3 : 0x3fff1ec8 A4 : 0x3fff1d30 A5 : 0x00000000
A6 : 0x00000001 A7 : 0x00000005 A8 : 0x801612ac A9 : 0x3fff1890
A10 : 0x00000000 A11 : 0x3fff1d38 A12 : 0x00000006 A13 : 0x3fff1d3e
A14 : 0x00006477 A15 : 0x00000000 SAR : 0x00000004 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000010 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0xffffffff

Backtrace: 0x401612ac:0x3fff18b0 0x400da2ea:0x3fff18d0 0x400d6db9:0x3fff1f40 0x400d6f8b:0x3fff1ff0 0x400dd561:0x3fff2030 0x400dd65f:0x3fff20f0 0x400d6993:0x3fff2130 0x400d46c8:0x3fff2150 0x4015fed2:0x3fff2170
0x401612ac: JsonObject::getString(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) at /home/rick/eclipse-test/OldOrb/components/cpp_utils/./JSON.cpp:287

0x400da2ea: transformJSON::setSettings(int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) at /home/rick/eclipse-test/OldOrb/main/./transformJSON.cpp:392

0x400d6db9: manageTopic(int, int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) at /home/rick/eclipse-test/OldOrb/main/./CommService.cpp:204

0x400d6f8b: commService::receivedBle(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) at /home/rick/eclipse-test/OldOrb/main/./CommService.cpp:109

0x400dd561: bleReceive(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) at /home/rick/eclipse-test/OldOrb/main/./bleService.cpp:209 (discriminator 1)

0x400dd65f: bleService::processRequest() at /home/rick/eclipse-test/OldOrb/main/./bleService.cpp:86

0x400d6993: commService::bleProcessRequest() at /home/rick/esp/xtensa-esp32-elf/xtensa-esp32-elf/include/c++/5.2.0/ext/new_allocator.h:110

0x400d46c8: Task_comm_monitor::run(void*) at /home/rick/eclipse-test/OldOrb/main/./main.cpp:124

0x4015fed2: Task::runTask(void*) at /home/rick/eclipse-test/OldOrb/components/cpp_utils/./Task.cpp:110

rwel59
Posts: 97
Joined: Thu Oct 12, 2017 3:32 pm

Re: cJSON std::string heap corruption crash

Postby rwel59 » Fri Mar 30, 2018 2:22 pm

Added more error checks to validate json. code runs until setting the struct variable to obj.getString then fails...
CODE:
case SET_NETWORK:
ESP_LOGI(TAG, "getFreeHeapSize %d", System::getFreeHeapSize());
ESP_LOGI(TAG, "SET_NETWORK %d", heap_caps_check_integrity_all(true));
ESP_LOGI(TAG, "SET_NETWORK hubIP - %s", obj.getString("hubIP").c_str());
ESP_LOGI(TAG, "SET_NETWORK asItem - %d", obj.hasItem("hubIP"));
ESP_LOGI(TAG, "SET_NETWORK toString - %s", obj.toString().c_str());
str = obj.getString("hubIP");
setup.network.hubIP = "this is a test IP";
ESP_LOGI(TAG, "transformJSON::setSettings 0");
setup.network.hubIP = obj.getString("hubIP");

CONSOLE OUTPUT:
I (44088) transformJSON: getFreeHeapSize 51116
I (40116) transformJSON: SET_NETWORK 1
I (40118) transformJSON: SET_NETWORK hubIP - ffggg
I (40123) transformJSON: SET_NETWORK asItem - 1
I (40127) transformJSON: SET_NETWORK toString - {
"hubIP": "ffggg",
"hubPort": 3011,
"hubPwd": "hh",
"webIP": "",
"webPort": 1883,
"wifi": []
}
I (40141) transformJSON: transformJSON::setSettings 0
assertion "heap != NULL && "free() target pointer is outside heap areas"" failed: file "/home/rick/esp/esp-idf/components/heap/./heap_caps.c", line 261, function: heap_caps_free

rwel59
Posts: 97
Joined: Thu Oct 12, 2017 3:32 pm

Re: cJSON std::string heap corruption crash

Postby rwel59 » Fri Mar 30, 2018 5:31 pm

UPDATE:

Couple of observations. I had my setup structure defined in another cpp (stores.cpp) and declared extern in TransformJSON.cpp - this was the situation when getting the crash. I defined a new structure variable in transformJSON.cpp and did not get the failure.

I am loading the setup struct from nvs, checking for saved version number and variable length. Both of these checks were saying I was retrieving valid nvs data, however all of the struct's string variables were being set to arrays of '\0' (str length = length of originally saved data) in the nvs read although str.length() was returning >0.

I changed the settings version # so that my nvs read routine would not load from nvs, and everything works again.

Tried to mimic this by setting my struct str = "\x00\x00\x00"; then setting it to the json objString where the failure was occurring but that did not cause any failure.

I'm guessing this doesn't have anything to do with json and the heap corruption is initiated when I load struct from nvs which seems to contain partially corrupted data. Is there a reason this nvs data would get corrupted by flashing new code?

Who is online

Users browsing this forum: Majestic-12 [Bot] and 262 guests