Skip to content

strnlen_P causes crash when used on object allocated on 2nd heap #8169

@TD-er

Description

@TD-er

Basic Infos

  • This issue complies with the issue POLICY doc.
  • I have read the documentation at readthedocs and the issue is not addressed there.
  • I have tested that the issue is present in current master branch (aka latest git).
  • I have searched the issue tracker for a similar issue.
  • If there is a stack dump, I have decoded it.
  • I have filled out all fields below.

Platform

  • Hardware: [ESP-12|ESP-01|ESP-07|ESP8285 device|other]
  • Core Version: [latest git hash or date]
  • Development Env: [Platformio]
  • Operating System: [Windows]

Settings in IDE

  • Module: [Generic ESP8266 Module]
  • Flash Mode: [dio]
  • Flash Size: [4MB]

PIO flags:

                            -DPIO_FRAMEWORK_ARDUINO_MMU_CUSTOM                            
                            -DMMU_IRAM_SIZE=0xC000 
                            -DMMU_ICACHE_SIZE=0x4000 
                            -DMMU_IRAM_HEAP

Problem Description

I have been working on this new (very nice) feature of using the 2nd heap to store some run time data.
For example I keep a queue of my events (String objects) and fetch them.

This did cause a crash on my project which eventually pointed to the use of strnlen_P (mind the 'n') which is not used in my code, but it is used in the String class.
The crash was about the loadprohibited errors you typically get when trying to use strlen like calls on flash strings:

LoadProhibited: A load referenced a page mapped with an attribute that does not permit loads
  epc1=0x40283620 in strnlen_P at /workdir/repo/newlib/newlib/libc/sys/xtensa/string_pgmspace.c:51

But now the really strange issue here and that's why I can't (yet) include a MCVE...
It does occur when interacting with data from the 2nd heap, but to fix it I have to alter calls to functions which may expect a const String& which and being called with a flash string.
For example when serving a web page, I enter code like this:

void Web_StreamingBuffer::sendHeaderBlocking(bool json, const String& origin) {
  #ifndef BUILD_NO_RAM_TRACKER
  checkRAM(String(F("sendHeaderBlocking")));
  #endif

This already includes the 'fix' to wrap the flash string in a String constructor. But this function checkRAM does have a function definition which accepts a flash string.

So it 'feels' like this web serving call is happening right when data was being stored in my event queue which does swap the heap to the iram heap.

I will try to see if I can also fix it by explicitly switching to the DRAM heap when serving a web page, but it does feel a bit tricky to say the least.

Also I am having a hard time in getting this 2nd heap thing to work reliable.
It feels like random if the 2nd heap is active or not when compiling it using PlatformIO.
Using PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48_SECHEAP_SHARED as PIO define does randomly have it compiled in.
When it doesn't work, calling ESP.getFreeHeap() returns the same value always regardless the selected heap.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions