c3d / db48x

RPL runtime for the DM42 calculator, in the spirit of HP48/49/50
http://48calc.org
GNU Lesser General Public License v3.0
85 stars 10 forks source link

Calculator crash evaluating simple sum in a for loop #101

Closed c3d closed 1 year ago

c3d commented 1 year ago

Evaluating the following test program:

« 0 0 7199
for i
    i sin exp +
next »
'DM32' STO

on a physical calculator, editing it and re-evaluting it leads to a random crash with alarming regularity.

This does not seem to happen on the simulator.

c3d commented 1 year ago

@balta1980 has preported something that looks similar (case 2 in the comment)](https://github.com/c3d/DB48X-on-DM42/discussions/75#discussioncomment-6388919)

c3d commented 1 year ago

I get a systematric crash at startup when loading the following default state:

« Ticks 0 0 7199
for i
    i sin exp +
next Ticks Rot - »
'DM32' STO

« Ticks 0
do
    8 Swap 1 +
    while
        Duplicate2
        do
            1 -
        until
            Duplicate2 5 + Pick - abs Duplicate2 - × not
        end
    repeat
        Drop
        while
            Swap Duplicate 1 same
        repeat
            -
        end 1 - Swap
    end Drop
until
    Duplicate 8 same
end →List Ticks Rot - »
'NQueens' STO

« Ticks 0 1 1000
start
    Drop 0
    do
        8 Swap 1 +
        while
            Duplicate2
            do
                1 -
            until
                Duplicate2 5 + Pick - abs Duplicate2 - × not
            end
        repeat
            Drop
            while
                Swap Duplicate 1 same
            repeat
                -
            end 1 - Swap
        end Drop
    until
        Duplicate 8 same
    end →List
next Ticks Rot - »
'SLOWQ' STO

« 1 Swap
while
    Duplicate 0 same not
repeat
    Swap Over × Swap 1 -
end Drop »
'Fact' STO

9.116089785555425022891285278437473⁳3
4750
VariablesMenu

It works if the big decimal128 number at the end is stored in a variable and not on the stack.

The crash is the following:

Hard Fault
r0=00006784 r1=00006784
r2=0000000c r3=0000000c
r12=00000089 lr=00000015
pc=0806b00c psr=21000000
c3d commented 1 year ago

The symbols surrounding 0806b00c are:

                0x0806adc0       0x2c build/release/file.o
                0x0806adc0                file::rfind(unsigned int)
 .text._ZN8graphics4blitILNS_8clippingE6ENS_7surfaceILNS_4modeE1EEES4_LS3_1EEEvRT0_RKT1_RKNS_4rectERKNS_5pointEPFmmmmENS_7patternIXT2_EEE.isra.0
                0x0806adec      0x1f8 build/release/stack.o
 .text._ZN8graphics7surfaceILNS_4modeE1EE4textILNS_8clippingE2EEEsssPKhjPK4fontNS_7patternILS1_1EEEPFmmmmE.isra.0
                0x0806afe4       0xf0 build/release/stack.o
 .text._ZN5stack10draw_stackEv
                0x0806b0d4      0xcb0 build/release/stack.o
                0x0806b0d4                stack::draw_stack()
 .text._Z4beepii
                0x0806bd84       0x28 build/release/util.o
                0x0806bd84                beep(int, int)

That seems to indicate a problem at offset 0x28 in short graphics::surface<(graphics::mode)1>::text<(graphics::clipping)2>(short, short, unsigned char const*, unsigned int, font const*, graphics::pattern<(graphics::mode)1>, unsigned long (*)(unsigned long, unsigned long, unsigned long))

The LR also looks bogus.

c3d commented 1 year ago

Trying to disassemble with

arm-none-eabi-objdump -d -S build/release/DB48X.elf > disass.s

Getting updated list of symbols with

arm-none-eabi-objdump --sort -t build/release/DB48X.elf > symbols.txt
c3d commented 1 year ago

Apparently, text rendering goes into the woods. One reason this could happen is malformed UTF8 input that is not consistent with the given length. Adding a bit of defensive coding apparently fixes the two cases where this is known to happen.