stacktrace: Don't allocate module paths when no frame has a line by gabrielmancini · Pull Request #2436 · atomvm/AtomVM · GitHub
Skip to content

stacktrace: Don't allocate module paths when no frame has a line - #2436

Open
gabrielmancini wants to merge 1 commit into
atomvm:release-0.7from
iobee-io:stacktrace-malloc-zero
Open

gabrielmancini wants to merge 1 commit into
atomvm:release-0.7from
iobee-io:stacktrace-malloc-zero

Conversation

@gabrielmancini

Copy link
Copy Markdown

stacktrace_build() allocates num_mods module path pairs, one per frame location with line information, and returns the raw stacktrace when malloc fails. When no frame has line information, num_mods is 0, and on ESP-IDF malloc(0) returns NULL (heap_caps_base.c), so the stacktrace comes back raw ({NumFrames, 0, 0, 0, [{ModIndex, Offset}, ...], Class}) instead of a list, and stderr shows:

Unable to allocate space for module paths.  Returning raw stacktrace.

That covers every application packed without line information on ESP32: we saw it on all our boards (ESP32 and ESP32-S3 with 8 MB of PSRAM), never related to memory. glibc returns a non-NULL pointer for malloc(0), which is why generic_unix never shows it.

The fix allocates only when num_mods > 0. With 0 the loop never touches module_paths, and free(NULL) is fine.

Test. test_stacktrace (ESP32) raises in a module compiled with no_line_info and checks that the stacktrace is a list with a frame of that module. The ESP32 test project never declared AVM_CREATE_STACKTRACES, so stacktraces were undefined there; it now enables it as src/platforms/esp32/CMakeLists.txt does, which is what a device runs with.

  • QEMU esp32, without the fix: the message above, and {not_a_list,{2,0,0,0,[{0,25},{0,20,erlang,error,1}],error}}; with it, test_stacktrace passes (test_socket fails here as it does on plain release-0.7, no network inside QEMU).
  • generic_unix test-erlang: all pass.
  • On hardware: one ESP32 with the fix printed the message 0 times in two days; boards without it, 109 and 13 times in the same period.

These changes are made under both the "Apache 2.0" and the "GNU Lesser General Public License 2.1 or later" license terms (dual license).

SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later

stacktrace_build() allocated num_mods module path pairs, one per frame
with line information, and returned the raw stacktrace when malloc
failed. With no such frame num_mods is 0, and malloc(0) returns NULL on
ESP-IDF, so every stacktrace of modules without line information came
back raw, with "Unable to allocate space for module paths" on stderr.
Allocate only when there is something to store.

The ESP32 test project now creates stacktraces like the firmware build
does, so test_stacktrace sees what a device sees.

Signed-off-by: Gabriel Mancini <gabriel.mancini@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant