Added heaptrace module.

This commit is contained in:
Johny Mattsson 2021-09-16 13:54:55 +10:00
parent b84138595d
commit 5e52a9e200
5 changed files with 201 additions and 0 deletions

View File

@ -9,6 +9,7 @@ set(module_srcs
"encoder.c" "encoder.c"
"file.c" "file.c"
"gpio.c" "gpio.c"
"heaptrace.c"
"http.c" "http.c"
"i2c.c" "i2c.c"
"i2c_hw_master.c" "i2c_hw_master.c"

View File

@ -74,6 +74,15 @@ menu "NodeMCU modules"
help help
Includes the GPIO module (recommended). Includes the GPIO module (recommended).
config NODEMCU_CMODULE_HEAPTRACE
bool "Heap trace debug module"
default "n"
depends on HEAP_TRACING_STANDALONE
help
Includes the heap tracing module. This provides an interface to
the IDF's heap tracing API, allowing interactive tracing
sessions via the Lua command line.
config NODEMCU_CMODULE_HTTP config NODEMCU_CMODULE_HTTP
bool "HTTP module" bool "HTTP module"
default "y" default "y"

View File

@ -0,0 +1,84 @@
#include "module.h"
#include "lauxlib.h"
#include "esp_heap_trace.h"
static heap_trace_record_t *buffer = NULL;
static int lht_init(lua_State *L)
{
int records = luaL_checkint(L, 1);
if (records <= 0)
return luaL_error(L, "invalid trace buffer size");
heap_trace_stop();
free(buffer);
buffer = calloc(sizeof(heap_trace_record_t), records);
if (!buffer)
return luaL_error(L, "out of memory");
esp_err_t err = heap_trace_init_standalone(buffer, records);
if (err != ESP_OK)
return luaL_error(L, "failed to init heap tracing; code %d", err);
return 0;
}
static int lht_start(lua_State *L)
{
esp_err_t err;
switch(luaL_checkint(L, 1))
{
case HEAP_TRACE_ALL: err = heap_trace_start(HEAP_TRACE_ALL); break;
case HEAP_TRACE_LEAKS: err = heap_trace_start(HEAP_TRACE_LEAKS); break;
default: return luaL_error(L, "invalid trace mode");
}
if (err != ESP_OK)
return luaL_error(L, "failed to start heap tracing; code %d", err);
return 0;
}
static int lht_stop(lua_State *L)
{
esp_err_t err = heap_trace_stop();
if (err != ESP_OK)
return luaL_error(L, "failed to stop heap tracing; code %d", err);
return 0;
}
static int lht_resume(lua_State *L)
{
esp_err_t err = heap_trace_resume();
if (err != ESP_OK)
return luaL_error(L, "failed to resume heap tracing; code %d", err);
return 0;
}
static int lht_dump(lua_State *L)
{
(void)L;
heap_trace_dump();
return 0;
}
LROT_BEGIN(heaptrace, NULL, 0)
LROT_FUNCENTRY( init, lht_init )
LROT_FUNCENTRY( start, lht_start )
LROT_FUNCENTRY( stop, lht_stop )
LROT_FUNCENTRY( resume, lht_resume )
LROT_FUNCENTRY( dump, lht_dump )
LROT_NUMENTRY( TRACE_ALL, HEAP_TRACE_ALL )
LROT_NUMENTRY( TRACE_LEAKS, HEAP_TRACE_LEAKS )
LROT_END(heaptrace, NULL, 0)
NODEMCU_MODULE(HEAPTRACE, "heaptrace", heaptrace, NULL);

106
docs/modules/heaptrace.md Normal file
View File

@ -0,0 +1,106 @@
# Heaptrace Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2021-09-16 | [Johny Mattsson](https://github.com/jmattsson) |[Johny Mattsson](https://github.com/jmattsson) | [heaptrace.c](../../components/modules/heaptrace.c)|
The heaptrace module is a debug aid for diagnosing heap allocations and
leaks thereof. It provides an interface to the [built-in heap tracing
support in the IDF](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/heap_debug.html), enabling interactive heap tracing
from the Lua command line.
To use this module, "standalone" heap tracing must be enabled in Kconfig
first. This setting is found (at the time of writing) under
"Component config" > "Heap memory debugging" > "Heap tracing". The depth
of the call chain to capture can also be configured there. It can be very
beneficial to set that to its max, but it comes at significantly increased
memory requirements in turn.
A typical sequence of commands for a heap tracing session will be:
```lua
heaptrace.init(200) -- your needed buffer size will depend on your use case
collectgarbage() -- start with as clean a slate as possible
heaptrace.start(heaptrace.TRACE_LEAKS) -- start in leak tracing mode
heaptrace.dump() -- dump the current state of allocations
... -- do the thing that is leaking memory
collectgarbage() -- free things that can be freed, to avoid false positives
heaptrace.stop() -- optional, but provides higher quality output next
heaptrace.dump() -- dump the current state of allocations, hopefully showing the leaked entries and where they got allocated from
-- heaptrace.resume() -- optionally resume the tracing, if stopped previously
```
## heaptrace.init
Allocates and registers the heap tracing buffer.
#### Syntax
```lua
heaptrace.init(bufsz)
```
#### Parameters
- `bufsz` the size of the heap tracing buffer, expressed as number of heap tracing records. The actual size depends on the call chain depth configured in Kconfig.
#### Returns
`nil`
## heaptrace.start
Starts the heap tracing. All allocations and frees will be recorded in the
heap tracing buffer, subject to availability within the buffer.
#### Syntax
```lua
heaptrace.start(mode)
```
#### Parameters
- `mode` the heap tracing mode to use. One of:
- `heaptrace.TRACE_LEAKS`
- `heaptrace.TRACE_ALL`
#### Returns
`nil`
## heaptrace.stop
Stops the heap tracing session. A stopped session may be resumed later.
#### Syntax
```lua
heaptrace.stop()
```
#### Parameters
None.
#### Returns
`nil`
## heaptrace.resume
Resumes a previously stopped heap tracing session.
#### Syntax
```lua
heaptrace.resume()
```
#### Parameters
None.
#### Returns
`nil`
## heaptrace.dump
Dumps the heap trace buffer to the console.
#### Syntax
```lua
heaptrace.dump()
```
#### Parameters
None.
#### Returns
`nil`

View File

@ -51,6 +51,7 @@ pages:
- 'eth': 'modules/eth.md' - 'eth': 'modules/eth.md'
- 'file': 'modules/file.md' - 'file': 'modules/file.md'
- 'gpio': 'modules/gpio.md' - 'gpio': 'modules/gpio.md'
- 'heaptrace': 'modules/heaptrace.md'
- 'http': 'modules/http.md' - 'http': 'modules/http.md'
- 'i2c': 'modules/i2c.md' - 'i2c': 'modules/i2c.md'
- 'i2s': 'modules/i2s.md' - 'i2s': 'modules/i2s.md'