If I manually call abort() within the code, once the device has rebooted I can call a command to read the cordump partition to UART, which works successfully and I can see that the base64 encoded core dump starts with:
However, if the firmware crashes for some other reason (e.g. Heap Memory poisoning) and after rebooting I then call the same command to read the coredump partition, I get a very different looking response, starting as follows:f0VMRgEBAQAAAAAAAAAAAAQAXgABAAAAAAAAADQAAAAAAAAAAAAAADQAIAAsACgAAAAAAAQAAAC0BQAAAAAAAAAAAADgMQAA4DEAAAYAAAAAAAAAAQAAAJQ3AADYycw/2MnMP1wBAABcAQAABgAAAAAAAAABAAAA8DgAALBaGzywWhs8QAMAAEADAAAGAAAAAAAAAAEAAAAwPAAA+GjLP/hoyz9cAQAAXAEAAAYAAAAAAAAAAQAAAIw9AAAAZss/AGbLP6ACAACgAgAABgAAAAAAAAABAAAALEAAAPBwyz/wcMs/XAEAAFwBAAAGAAAAAAAAAAEAAACIQQAAAG7LPwBuyz+gAgAAoAIAAAYAAAAAAAAAAQAAAChEAAAwI84/MCPOP1wBAABcAQAABgAAAAAAAAABAAAAhEUAAIBsGjyAbBo80AMAANADAAAGAAAAAAAAAAEAAABUSQAAxDDMP8QwzD9cAQAAXAEAAAYAAAAAAAAAAQAAALBKAACgK8w/oCvMPxADAAAQAwAABgAAAAAAAAABAAAAwE0AAFyYzD9cmMw/XAEAAFwBAAAGAAAAAAAAAAEAAAAcTwAAcJTMP3CUzD/gAgAA
Note that currently I'm trimming the first 24 bytes of the partition data, so that when working correctly, the decoded data starts with \x7fELF630b1pcoDKbNIrI76sCdTgUUVt2r4/oYDPIn6rDrtCKhZomDTMDG62Cu/BobAezrz1WLZQzA9ogCy/75VLC9stc4BHg9GnaW/pwcb8ZoEZvmEYLUFy0shsZ4Lf66YslIIVBahj0+eqaMNAGM4jzNZn1EwJLg/kbxR8VGd0Ou7mcvw0n4cfE/TjjxjCbu6sKAbFhLDCtmfo1ADX5Nbay3wvwkegrfw3cOcSBy8cVMUh0RSsF/NqyL62PCDy1ZYyrDr2RFxpdwkqlB2S40Lhf8hQ20Qx4IMxIAm0YR6Zf+Gpe830ZSkIwLbYYh5Ll8ZcWNT2hsxRtf2ir80aVTL4/7wtaGqBy1VMilCwb9oXuSfmtLPERjOyZN5x80HxB8ShHJ5NZvjOZBJr/BqBsTnNWxwcdr5XiwnM6BwqwyfP5hAryLnyC+eYGc6UVTdx7Q3dv8xzIK99XTzZu8yPm66kTwejWcZQbYvWLgPmCXbg5jrNLd0ryBCQ39Vci7iL3zEfuUf/hfx2UxHtwk0IeHtKJscoA8fZCXYOYPBTKyurGyb7aYHTcidfIloySul4YHsZxdFJsmNBOQbR5RfK0LkL0Ixm0a8HdzA6
Here is the function I'm using to read the coredump data from the partition:
Code: Select all
// Find the coredump partition
const esp_partition_t *core_dump_partition = esp_partition_find_first(
ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_COREDUMP, "coredump");
if (!core_dump_partition)
{
ESP_LOGE(TAG, "Core dump partition not found!");
args->result = ipb_strdup("Core dump partition not found!"); // freed in calling function
xSemaphoreGive(args->semaphore);
vTaskDelete(NULL);
}
ESP_LOGI(TAG, "Core dump partition: %s, size: %ld", core_dump_partition->label, core_dump_partition->size);
// Read the core dump size
size_t core_dump_size = core_dump_partition->size;
uint8_t *core_dump_data = malloc(core_dump_size + 1);
if (!core_dump_data)
{
ESP_LOGE(TAG, "Failed to allocate memory for core dump");
args->result = NULL;
xSemaphoreGive(args->semaphore);
vTaskDelete(NULL);
}
esp_err_t err = esp_partition_read(core_dump_partition, 0, core_dump_data, core_dump_size);
if (err != ESP_OK)
{
ESP_LOGE(TAG, "Failed to read core dump data: %s", esp_err_to_name(err));
free(core_dump_data);
args->result = ipb_strdup("Failed to read core dump data"); // freed in calling function
xSemaphoreGive(args->semaphore);
vTaskDelete(NULL);
}
// Trim the first 20 bytes
uint8_t *trimmed_core_dump_data = core_dump_data + 24;
size_t trimmed_core_dump_size = core_dump_size - 24;
// Calculate Base64 encoded size
size_t encoded_size = 0;
mbedtls_base64_encode(NULL, 0, &encoded_size, trimmed_core_dump_data, trimmed_core_dump_size);
uint8_t *encoded_data = malloc(encoded_size + 1); // used as return, so freed in calling function
if (!encoded_data)
{
ESP_LOGE(TAG, "Failed to allocate memory for encoded data");
free(core_dump_data); // Free original buffer
args->result = NULL;
xSemaphoreGive(args->semaphore);
vTaskDelete(NULL);
}
// Encode core dump to Base64
err = mbedtls_base64_encode(encoded_data, encoded_size, &encoded_size, trimmed_core_dump_data, trimmed_core_dump_size);
if (err != 0)
{
ESP_LOGE(TAG, "Failed to encode core dump data to Base64");
free(core_dump_data); // Free original buffer
free(encoded_data); // Free allocated memory
args->result = NULL;
xSemaphoreGive(args->semaphore);
vTaskDelete(NULL);
}
encoded_data[encoded_size] = '\0'; // Null-terminate the Base64 string
ESP_LOGI(TAG, "Core dump encoded size: %d", encoded_size);
// Debug logs for verification
ESP_LOGI(TAG, "Encoded core dump: %.16s", encoded_data);
// Clean up and set the result
free(core_dump_data); // Free original buffer
args->result = (char *)encoded_data;
// Signal task completion
xSemaphoreGive(args->semaphore);