B4R Question B4R NumberFormat string buffer overwrite or out-of-bounds?

emexes

Well-Known Member
Licensed User
I am sending ASCII text lines via the serial-over-USB ESP32-PC link, and it was working great until I used NumberFormat. I have tried this code on two different ESP32 modules:
B4X:
Private Sub AppStart
   
    Serial1.Initialize(115200)
    Log("AppStart")
   
    Dim B1() As Byte = "Packet #"
    Dim B3(1) As Byte = Array As Byte(13)    'end-of-line = CR
   
    For I = 1 To 10000
       
        Serial1.Stream.WriteBytes(B1, 0, B1.Length)
       
        Log( NumberFormat(I, 1, 0) )
        '''Log(I)
       
        Serial1.Stream.WriteBytes(B3, 0, B3.Length)
       
        Delay(200)
    Next

End Sub
and on both modules, the program repeatedly crashes and reboots:
B4X:
...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
********************* PROGRAM STARTING ****************
ets Jun  8 2016 00:22:57
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:928
ho 0 tail 12 room 4
load:0x40078000,len:8424
ho 0 tail 12 room 4
load:0x40080400,len:5868
entry 0x4008069c
AppStart
Packet #1
Packet #2
Packet #3
Packet #4
Packet #5
Packet #6
Packet #7
Packet #8
Packet #9
Packet #10
Packet #11
Packet #12
Packet #13
Packet #14
Packet #15
Packet #16
Packet #17
Packet #18
Packet #19
Packet #X�
Packet #21
Packet #22Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC      : 0x40087f5f  PS      : 0x00060533  A0      : 0x80086e51  A1      : 0x3ffb1dd0 
A2      : 0x0000001d  A3      : 0x3ffb8058  A4      : 0x00000001  A5      : 0x00000001 
A6      : 0x00060523  A7      : 0x00000000  A8      : 0x00000000  A9      : 0x3ffb1db0 
A10     : 0x00000001  A11     : 0x3ffb8058  A12     : 0x00000001  A13     : 0x00000001 
A14     : 0x00060323  A15     : 0x00000000  SAR     : 0x0000001c  EXCCAUSE: 0x0000001c 
EXCVADDR: 0x0000002d  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xffffffff 
Backtrace: 0x40087f5f:0x3ffb1dd0 0x40086e4e:0x3ffb1df0 0x4008541d:0x3ffb1e10 0x400d1cfd:0x3ffb1e50 0x400d1385:0x3ffb1e70 0x400d155e:0x3ffb1e90 0x400d1585:0x3ffb1eb0 0x400d10d4:0x3ffb1ed0 0x400d103a:0x3ffb1ef0 0x400d1268:0x3ffb1f50 0x400d12ce:0x3ffb1f90 0x400d20db:0x3ffb1fb0 0x40087911:0x3ffb1fd0
Rebooting...
ets Jun  8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:928
ho 0 tail 12 room 4
load:0x40078000,len:8424
ho 0 tail 12 room 4
load:0x40080400,len:5868
entry 0x4008069c
AppStart
Packet #1
Packet #2
Packet #3
Packet #4
Packet #5
Packet #6
Packet #7
Packet #8
Packet #9
Packet #10
Packet #11
Packet #12
Packet #13
Packet #14
Packet #15
Packet #16
Packet #17
Packet #18
Packet #19
Packet #X�
Packet #21
Packet #22Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC      : 0x40087f5f  PS      : 0x00060533  A0      : 0x80086e51  A1      : 0x3ffb1dd0 
A2      : 0x0000001d  A3      : 0x3ffb8058  A4      : 0x00000001  A5      : 0x00000001 
A6      : 0x00060523  A7      : 0x00000000  A8      : 0x00000000  A9      : 0x3ffb1db0 
A10     : 0x00000001  A11     : 0x3ffb8058  A12     : 0x00000001  A13     : 0x00000001 
A14     : 0x00060323  A15     : 0x00000000  SAR     : 0x0000001c  EXCCAUSE: 0x0000001c 
EXCVADDR: 0x0000002d  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xffffffff 
Backtrace: 0x40087f5f:0x3ffb1dd0 0x40086e4e:0x3ffb1df0 0x4008541d:0x3ffb1e10 0x400d1cfd:0x3ffb1e50 0x400d1385:0x3ffb1e70 0x400d155e:0x3ffb1e90 0x400d1585:0x3ffb1eb0 0x400d10d4:0x3ffb1ed0 0x400d103a:0x3ffb1ef0 0x400d1268:0x3ffb1f50 0x400d12ce:0x3ffb1f90 0x400d20db:0x3ffb1fb0 0x40087911:0x3ffb1fd0
Rebooting...
etc
If I replace NumberFormat with default Int-to-String casting:
B4X:
'''Log( NumberFormat(I, 1, 0) )
Log(I)
then on both modules it runs without crashing:
B4X:
AppStart
Packet #1
Packet #2
Packet #3
Packet #4
Packet #5
Packet #6
Packet #7
Packet #8
Packet #9
Packet #10
Packet #11
Packet #12
Packet #13
Packet #14
Packet #15
Packet #16
Packet #17
Packet #18
Packet #19
Packet #20
Packet #21
Packet #22
Packet #23
Packet #24
Packet #25
Packet #26
Packet #27
Packet #28
Packet #29
...
Packet #1197
Packet #1198
Packet #1199
Packet #1200
Packet #1201
Packet #1202
Packet #1203
etc...
If I change the length of the NumberFormat return string, by varying the MinimumIntegers through 2..10 then the revealed data-corruption changes too, and at MinimumIntegers = 8, the error changes from "Guru Meditation Error" to "assert failed!" :
B4X:
Log( NumberFormat(I, 2, 0) )
 '''Log(I)
B4X:
AppStart
Packet #01
Packet #02
Packet #03
Packet #04
Packet #05
Packet #06
Packet #07
Packet #08
Packet #09
Packet #10
Packet #11
Packet #12
Packet #13
Packet #14
Packet #15
Packet #16
Packet #17
Packet #18
Packet #19
Packet #X�
Packet #21
Packet #22Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
B4X:
Packet #018
Packet #019
Packet #X��
Packet #021
Packet #022Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
B4X:
Packet #0018
Packet #0019
Packet #X��?
Packet #0021
Packet #0022Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
B4X:
Packet #00018
Packet #00019
Packet #X��?0
Packet #00021
Packet #00022Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
B4X:
Packet #000018
Packet #000019
Packet #X��?20
Packet #000021
Packet #000022Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
B4X:
Packet #0000018
Packet #0000019
Packet #X��?020
Packet #0000021
Packet #0000022Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
B4X:
Packet #00000011
Packet #00000012
Packet #00000013
Packet #/Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/tasks.c:3121 (xTaskRemoveFromEventList)- assert failed!
abort() was called at PC 0x40086e46 on core 1
Backtrace: 0x40088dc4:0x3ffb1db0 0x40088ff1:0x3ffb1dd0 0x40086e46:0x3ffb1df0 0x40085781:0x3ffb1e10 0x400d1cc5:0x3ffb1e50 0x400d1385:0x3ffb1e70 0x400d155e:0x3ffb1e90 0x400d1585:0x3ffb1eb0 0x400d10d4:0x3ffb1ed0 0x400d103a:0x3ffb1ef0 0x400d1268:0x3ffb1f50 0x400d12ce:0x3ffb1f90 0x400d20db:0x3ffb1fb0 0x40087911:0x3ffb1fd0
Rebooting...
B4X:
Packet #000000011
Packet #000000012
Packet #000000013
Packet #/Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/tasks.c:3121 (xTaskRemoveFromEventList)- assert failed!
abort() was called at PC 0x40086e46 on core 1
Backtrace: 0x40088dc4:0x3ffb1db0 0x40088ff1:0x3ffb1dd0 0x40086e46:0x3ffb1df0 0x40085781:0x3ffb1e10 0x400d1cc5:0x3ffb1e50 0x400d1385:0x3ffb1e70 0x400d155e:0x3ffb1e90 0x400d1585:0x3ffb1eb0 0x400d10d4:0x3ffb1ed0 0x400d103a:0x3ffb1ef0 0x400d1268:0x3ffb1f50 0x400d12ce:0x3ffb1f90 0x400d20db:0x3ffb1fb0 0x40087911:0x3ffb1fd0
Rebooting...
B4X:
Log( NumberFormat(I, 10, 0) )
 '''Log(I)
B4X:
Packet #0000000011
Packet #0000000012
Packet #0000000013
Packet #/Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/tasks.c:3121 (xTaskRemoveFromEventList)- assert failed!
abort() was called at PC 0x40086e46 on core 1
Backtrace: 0x40088dc4:0x3ffb1db0 0x40088ff1:0x3ffb1dd0 0x40086e46:0x3ffb1df0 0x40085781:0x3ffb1e10 0x400d1cc5:0x3ffb1e50 0x400d1385:0x3ffb1e70 0x400d155e:0x3ffb1e90 0x400d1585:0x3ffb1eb0 0x400d10d4:0x3ffb1ed0 0x400d103a:0x3ffb1ef0 0x400d1268:0x3ffb1f50 0x400d12ce:0x3ffb1f90 0x400d20db:0x3ffb1fb0 0x40087911:0x3ffb1fd0
Rebooting...
If the above doesn't pinpoint the cause, then I guess the next step is to remove the Serial comms so that only the NumberFormat remains, and signal reboots by flashing a LED, but... I'll wait see what happens.

I am mildly confused that there are no reports of this already (that I could find). I have tried the usual tricks like Tools, Clean project, reboots, using intermediate String variables, but... no difference.
 

Erel

Administrator
Staff member
Licensed User
Moved to the questions forum.

NumberFormat creates a string. The string must be stored somewhere. It uses the stack buffer for this. You can add Log(StackBufferUsage) to see the number rises.

The best solution for such cases is to move the loop code to a different sub:
B4X:
For i = 1 To 100000
 DoSomething(i)
Next
This way the stack buffer will be released every iteration.
 
Top