Skip to content

Commit b427981

Browse files
authored
[ESP32] Provide core dump summary in response to crash diagnostic log requests (#32331)
* [ESP32] Provide core dump summary in response to crash diagnostic log requests. * use esp_core_dump_image_check when core dump size is requested
1 parent 33119dc commit b427981

File tree

5 files changed

+56
-61
lines changed

5 files changed

+56
-61
lines changed

examples/temperature-measurement-app/esp32/README.md

+4-11
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ contains three files:
3434

3535
```
3636
main/diagnostic_logs
37-
├── crash.log
3837
├── end_user_support.log
3938
└── network_diag.log
4039
```
@@ -53,8 +52,8 @@ chip-tool diagnosticlogs retrieve-logs-request 0 0 1 0
5352
# Read network diagnostic using BDX protocol
5453
chip-tool interactive start
5554
> diagnosticlogs retrieve-logs-request 1 1 1 0 --TransferFileDesignator network-diag.log
56-
# Retrieve crash over BDX
57-
> diagnosticlogs retrieve-logs-request 1 1 1 0 --TransferFileDesignator crash.bin
55+
# Retrieve crash summary over BDX
56+
> diagnosticlogs retrieve-logs-request 2 1 1 0 --TransferFileDesignator crash-summary.bin
5857
```
5958

6059
esp-idf supports storing and retrieving
@@ -73,15 +72,9 @@ This example's partition table and sdkconfig.default are already modified
7372
- Retrieve the core dump using diagnostic logs cluster
7473

7574
```
76-
# Read crash logs over BDX
75+
# Read crash summary over BDX
7776
chip-tool interactive start
78-
> diagnosticlogs retrieve-logs-request 1 1 1 0 --TransferFileDesignator crash.bin
79-
```
80-
81-
- Decode the crash logs, using espcoredump.py
82-
```
83-
espcoredump.py --chip (CHIP) info_corefile --core /tmp/crash.bin \
84-
--core-format elf build/chip-temperature-measurement-app.elf
77+
> diagnosticlogs retrieve-logs-request 2 1 1 0 --TransferFileDesignator crash-summary.bin
8578
```
8679
8780
## Optimization

examples/temperature-measurement-app/esp32/main/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ set(SRC_DIRS_LIST
5555
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers"
5656
)
5757

58-
set(PRIV_REQUIRES_LIST chip QRCode bt nvs_flash bootloader_support espcoredump)
58+
set(PRIV_REQUIRES_LIST chip QRCode bt nvs_flash espcoredump)
5959

6060
if (CONFIG_ENABLE_PW_RPC)
6161
# Append additional directories for RPC build

examples/temperature-measurement-app/esp32/main/diagnostic-logs-provider-delegate-impl.cpp

+33-37
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@
2121

2222
#if defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF)
2323
#include <esp_core_dump.h>
24-
#include <esp_flash_encrypt.h>
25-
// Its a bit hackish but we need this in order to pull in the sizeof(core_dump_header_t)
26-
// we can even use the static 20 but, what if that gets chagned?
27-
#include "../include_core_dump/esp_core_dump_types.h"
2824
#endif // defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF)
2925

3026
using namespace chip;
@@ -95,34 +91,16 @@ size_t LogProvider::GetCrashSize()
9591
size_t outSize = 0;
9692

9793
#if defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF)
98-
size_t unusedOutAddr;
99-
esp_err_t esp_err = esp_core_dump_image_get(&unusedOutAddr, &outSize);
100-
VerifyOrReturnValue(esp_err == ESP_OK, 0, ChipLogError(DeviceLayer, "Failed to get core dump image, esp_err:%d", esp_err));
94+
// Verify that the crash is present and sane
95+
esp_err_t esp_err = esp_core_dump_image_check();
96+
VerifyOrReturnValue(esp_err == ESP_OK, 0, ChipLogError(DeviceLayer, "Core dump image check failed, esp_err:%d", esp_err));
97+
98+
outSize = sizeof(esp_core_dump_summary_t);
10199
#endif // defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF)
102100

103101
return outSize;
104102
}
105103

106-
CHIP_ERROR LogProvider::MapCrashPartition(CrashLogContext * context)
107-
{
108-
#if defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF)
109-
size_t outAddr, outSize;
110-
esp_err_t esp_err = esp_core_dump_image_get(&outAddr, &outSize);
111-
VerifyOrReturnError(esp_err == ESP_OK, CHIP_ERROR(ChipError::Range::kPlatform, esp_err),
112-
ChipLogError(DeviceLayer, "Failed to get core dump image, esp_err:%d", esp_err));
113-
114-
/* map the full core dump parition, including the checksum. */
115-
esp_err = spi_flash_mmap(outAddr, outSize, SPI_FLASH_MMAP_DATA, &context->mappedAddress, &context->mappedHandle);
116-
VerifyOrReturnError(esp_err == ESP_OK, CHIP_ERROR(ChipError::Range::kPlatform, esp_err),
117-
ChipLogError(DeviceLayer, "Failed to mmap the crash partition, esp_err:%d", esp_err));
118-
119-
context->crashSize = static_cast<uint32_t>(outSize);
120-
return CHIP_NO_ERROR;
121-
#else
122-
return CHIP_ERROR_NOT_FOUND;
123-
#endif // defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF)
124-
}
125-
126104
CHIP_ERROR LogProvider::PrepareLogContextForIntent(LogContext * context, IntentEnum intent)
127105
{
128106
context->intent = intent;
@@ -146,11 +124,24 @@ CHIP_ERROR LogProvider::PrepareLogContextForIntent(LogContext * context, IntentE
146124
sCrashLogContext.Reset();
147125
context->Crash.logContext = &sCrashLogContext;
148126

149-
CHIP_ERROR err = MapCrashPartition(context->Crash.logContext);
150-
VerifyOrReturnError(err == CHIP_NO_ERROR, err, context->Crash.logContext = nullptr);
127+
size_t crashSize = GetCrashSize();
128+
VerifyOrReturnError(crashSize > 0, CHIP_ERROR_NOT_FOUND);
129+
130+
esp_core_dump_summary_t * summary =
131+
reinterpret_cast<esp_core_dump_summary_t *>(Platform::MemoryCalloc(1, sizeof(esp_core_dump_summary_t)));
132+
VerifyOrReturnError(summary != nullptr, CHIP_ERROR_NO_MEMORY);
133+
134+
esp_err_t esp_err = esp_core_dump_get_summary(summary);
135+
if (esp_err != ESP_OK)
136+
{
137+
ChipLogError(DeviceLayer, "Failed to get core dump image, esp_err:%d", esp_err);
138+
Platform::MemoryFree(summary);
139+
return CHIP_ERROR_NOT_FOUND;
140+
}
151141

152-
context->Crash.logContext->readOffset = sizeof(core_dump_header_t);
153-
context->Crash.logContext->isMapped = true;
142+
context->Crash.logContext->crashSize = crashSize;
143+
context->Crash.logContext->readOffset = 0;
144+
context->Crash.logContext->summary = summary;
154145
#else
155146
return CHIP_ERROR_NOT_FOUND;
156147
#endif // defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF)
@@ -177,7 +168,7 @@ void LogProvider::CleanupLogContextForIntent(LogContext * context)
177168
case IntentEnum::kCrashLogs: {
178169
#if defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF)
179170
CrashLogContext * logContext = context->Crash.logContext;
180-
spi_flash_munmap(logContext->mappedHandle);
171+
// Reset() frees the summary if allocated
181172
logContext->Reset();
182173
#endif // defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF)
183174
}
@@ -227,12 +218,15 @@ CHIP_ERROR LogProvider::GetDataForIntent(LogContext * context, MutableByteSpan &
227218
case IntentEnum::kCrashLogs: {
228219
#if defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF)
229220
CrashLogContext * logContext = context->Crash.logContext;
230-
size_t dataSize = logContext->crashSize - logContext->readOffset;
231-
auto count = std::min(dataSize, outBuffer.size());
221+
222+
VerifyOrReturnError(logContext->readOffset < logContext->crashSize, CHIP_ERROR_INCORRECT_STATE, outBuffer.reduce_size(0));
223+
224+
size_t dataSize = logContext->crashSize - logContext->readOffset;
225+
auto count = std::min(dataSize, outBuffer.size());
232226

233227
VerifyOrReturnError(CanCastTo<off_t>(count), CHIP_ERROR_INVALID_ARGUMENT, outBuffer.reduce_size(0));
234228

235-
const uint8_t * readAddr = reinterpret_cast<const uint8_t *>(logContext->mappedAddress) + logContext->readOffset;
229+
const uint8_t * readAddr = reinterpret_cast<const uint8_t *>(logContext->summary) + logContext->readOffset;
236230
memcpy(outBuffer.data(), readAddr, count);
237231
outBuffer.reduce_size(count);
238232

@@ -257,12 +251,14 @@ CHIP_ERROR LogProvider::StartLogCollection(IntentEnum intent, LogSessionHandle &
257251
{
258252
VerifyOrReturnValue(IsValidIntent(intent), CHIP_ERROR_INVALID_ARGUMENT);
259253

254+
#if defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF)
260255
// In case of crash logs we can only mmap at max once, so check before doing anything
261256
if (intent == IntentEnum::kCrashLogs)
262257
{
263-
VerifyOrReturnError(sCrashLogContext.isMapped == false, CHIP_ERROR_INCORRECT_STATE,
264-
ChipLogError(DeviceLayer, "Crash partition already mapped"));
258+
VerifyOrReturnError(sCrashLogContext.summary == nullptr, CHIP_ERROR_INCORRECT_STATE,
259+
ChipLogError(DeviceLayer, "Crash summary already allocated"));
265260
}
261+
#endif // defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF)
266262

267263
LogContext * context = reinterpret_cast<LogContext *>(Platform::MemoryCalloc(1, sizeof(LogContext)));
268264
VerifyOrReturnValue(context != nullptr, CHIP_ERROR_NO_MEMORY);

examples/temperature-measurement-app/esp32/main/include/diagnostic-logs-provider-delegate-impl.h

+17-11
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@
2020

2121
#include <app/clusters/diagnostic-logs-server/DiagnosticLogsProviderDelegate.h>
2222
#include <map>
23-
#include <spi_flash_mmap.h>
23+
24+
#if defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF)
25+
#include <esp_core_dump.h>
26+
#endif // defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF)
2427

2528
namespace chip {
2629
namespace app {
@@ -57,20 +60,23 @@ class LogProvider : public DiagnosticLogsProviderDelegate
5760

5861
struct CrashLogContext
5962
{
60-
spi_flash_mmap_handle_t mappedHandle = 0;
61-
const void * mappedAddress = nullptr;
62-
uint32_t crashSize = 0;
63-
uint32_t readOffset = 0;
64-
bool isMapped = 0;
63+
#if defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF)
64+
uint32_t crashSize = 0;
65+
uint32_t readOffset = 0;
66+
esp_core_dump_summary_t * summary = nullptr;
6567

6668
void Reset()
6769
{
68-
this->mappedHandle = 0;
69-
this->mappedAddress = nullptr;
70-
this->crashSize = 0;
71-
this->readOffset = 0;
72-
this->isMapped = 0;
70+
this->crashSize = 0;
71+
this->readOffset = 0;
72+
73+
if (this->summary)
74+
{
75+
Platform::MemoryFree(this->summary);
76+
this->summary = nullptr;
77+
}
7378
}
79+
#endif // defined(CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH) && defined(CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF)
7480
};
7581

7682
static CrashLogContext sCrashLogContext;

examples/temperature-measurement-app/esp32/partitions.csv

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ nvs, data, nvs, , 0xC000,
44
phy_init, data, phy, , 0x1000,
55
# Factory partition size about 1.5MB
66
factory, app, factory, , 1536K,
7-
coredump, data, coredump,, 64K
7+
coredump, data, coredump,, 64K, encrypted

0 commit comments

Comments
 (0)