Skip to content

Add heap alignment workaround for ESP32-S3 operator new#42

Open
ltowarek wants to merge 1 commit into
mainfrom
fix/heap-align-workaround
Open

Add heap alignment workaround for ESP32-S3 operator new#42
ltowarek wants to merge 1 commit into
mainfrom
fix/heap-align-workaround

Conversation

@ltowarek
Copy link
Copy Markdown
Owner

@ltowarek ltowarek commented May 10, 2026

Summary

  • Adds src/esp_heap_align.cpp — replaces the six standard replaceable allocation operators (operator new, operator new[], and their delete counterparts) with versions backed by heap_caps_aligned_alloc(alignof(max_align_t), ...), making operator new conforming on ESP32-S3
  • Adds Kconfig with a new ESP_OPENTELEMETRY_HEAP_ALIGN_WORKAROUND bool option (default y)
  • Updates CMakeLists.txt to conditionally compile esp_heap_align.cpp and pull it onto the link line via -Wl,--undefined=_Znwj
  • Adds two standalone test applications under test/:
    • heap_align_idf — pure ESP-IDF alignment survey (no external libs); shows which allocations violate the C/C++ standard
    • heap_align_protobuf — uses protobuf's Arena with the exact ArenaOptions from OtlpHttpExporter; reproduces the InstrFetchProhibited crash at PC=0x00010000 without the workaround

Background

ESP-IDF's multi_heap.c uses sizeof(void*)=4 as its alignment granularity. The ESP32-S3 toolchain reports alignof(std::max_align_t)==8. Protobuf's TaggedAllocationPolicyPtr stores control flags in the low 3 bits of a pointer (kPtrMask = ~7), requiring 8-byte alignment. When operator new returns a 4-byte-aligned block, get() computes ptr & ~7 = ptr - 4, reading max_block_size (0x00010000) as the block_alloc function pointer — crashing with InstrFetchProhibited at PC=0x00010000. Tracked in issue #32.

Test plan

  • Build test/heap_align_protobuf with CONFIG_ESP_OPENTELEMETRY_HEAP_ALIGN_WORKAROUND=y (default) — confirm it prints PASS: Arena survived second-block allocation
  • Build with CONFIG_ESP_OPENTELEMETRY_HEAP_ALIGN_WORKAROUND=n — confirm it crashes with InstrFetchProhibited at PC=0x00010000
  • Build test/heap_align_idf — confirm Non-conforming: 0 / 16 with workaround enabled

ESP-IDF's heap allocator returns 4-byte-aligned blocks on 32-bit Xtensa,
but the ESP32-S3 toolchain reports alignof(max_align_t)=8. Non-conforming
blocks crash protobuf's TaggedAllocationPolicyPtr via InstrFetchProhibited
at PC=0x00010000. Replaces global operator new/delete with versions backed
by heap_caps_aligned_alloc(alignof(max_align_t), ...). Tracked in issue #32.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ltowarek ltowarek force-pushed the fix/heap-align-workaround branch from e345fe4 to 2b5e2a2 Compare May 10, 2026 21:40
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