MitchBradley / cforth

Mitch Bradley's CForth implementation
Other
155 stars 41 forks source link

extend.c limit? #118

Closed Jos-Ven closed 1 year ago

Jos-Ven commented 1 year ago

Hi, On the WIP branch I needed a wakeup from a deepsleep on an ESP32 by activating an GPIO pin. After extending ~/cforth/src/app/esp32/extend.c with:

 extern void esp_sleep_enable_ext0_wakeup(void);
 C(esp_sleep_enable_ext0_wakeup) //c esp-sleep-enable-ext0-wakeup { i.level i.pin -- i.error? }

Make failed and ended with:

MAKING FORTH
CC main.o io.o nullbi.o dictfile.o mallocl.o lineedit.o linux-kbd.o forth.o compiler.o syscall.o floatops.o extend.o -lm -o forth
CC ../../src/cforth/meta.c
CC ../../src/cforth/getc-kbd.c
CC meta.o
./meta ../../src/cforth/interp.fth kernel.dic
./forth kernel.dic ../../src/cforth/load.fth
./makeccalls <../../src/app/esp32/extend.c >tccalls.fth
CBP=/home/pi/cf/cforth/src ./forth forth.dic tccalls.fth ../../src/app/esp32/app.fth
Aborted
Aborted
Address exception
./makebi app.dic
Can't open input file app.dic
make: *** [../../src/cforth/embed/targets.mk:91: dict.h] Error 1

last line of tccalls.fth tells:

#127 ccall: esp-now-unregister-recv_cb { -- }

Further investigations revealed that if another function was removed then esp-sleep-enable-ext0-wakeup works without problems. (no matter which function) So it seems there is a limit on the number of functions that can be added in extend.c How can this limit (if there is one) be increased or bypassed?

quozl commented 1 year ago

https://github.com/MitchBradley/cforth/blob/master/src/cforth/forth.c#L1527 and the call to altocstr set a maximum line size, might you have hit that? I suggest using gdb to find where the exception happened.

quozl commented 1 year ago

My other guess is that you've filled the space allocated by MAXDICT and should increase it from the default using the build/esp32/Makefile, see build/host-serial-linux64 for an example.

Jos-Ven commented 1 year ago

After a while I found that the Address exception was created by Forth when it runs: ./forth forth.dic tccalls.fth ../../src/app/esp32/app.fth Aborted Aborted Address exception

As far as I understand there should also be textend.o That is missing when the extra function is added to extend.c The created object files are then:

compiler.o forth.o linux-kbd.o nullbi.o tconsio.o tlineedit.o dictfile.o getc-kbd.o main.o startapp.o tfileio.o tsyscall.o extend.o io.o mallocl.o syscall.o tfloatops.o ttmain.o floatops.o lineedit.o meta.o tcompiler.o tforth.o

The problem is not solved when
char cstr[4][128]; and .... altocstr((char )(sp++), ret, cstr[strn++], 128); break;\

are changed to
char cstr[4][140]; and .... altocstr((char )(sp++), ret, cstr[strn++], 140); break;\

or/and when MAXDICT is added to build/esp32/Makefile like: CONFIG += -DMAXDICT=0xA0000

No idea yet how ro resolve this quickly with GDB (sorry).

MitchBradley commented 1 year ago

Attach a tccalls.fth that fails. It is near-impossible to debug a problem without complete context.

Jos-Ven commented 1 year ago

tccalls.txt Just done. Needed to change the extension to txt. Many thanks in advance.

MitchBradley commented 1 year ago

18 and 114 are missing a space before the closing }, so the Forth parser includes the } as part of the preceding word.

quozl commented 1 year ago

I've reproduced Aborted by removing a space before } in my own ccalls.fth.

For diagnosing Address exception using gdb at this step, I added in the middle of ccalls.fth a 0 0 !, reproduced thus;

$ ./forth forth.dic ccalls.fth  ../../src/app/host-serial/app.fth
Address exception

then ran it with gdb;

$ gdb ./forth
(gdb) run forth.dic ccalls.fth  ../../src/app/host-serial/app.fth
Program received signal SIGSEGV, Segmentation fault.
0x000055555555be73 in inner_interpreter (
    up=up@entry=0x555555567a00 <variables>) at ../../src/cforth/forth.c:270
270         nstore((cell *)tos, *sp++);
(gdb) bt
#0  0x000055555555be73 in inner_interpreter (
    up=up@entry=0x555555567a00 <variables>) at ../../src/cforth/forth.c:270
#1  0x000055555555e0ce in execute_xt (xt=<optimized out>, 
    up=up@entry=0x555555567a00 <variables>) at ../../src/cforth/forth.c:1311
#2  0x000055555555e12a in execute_word (s=0x55555556203f "quit", 
    up=0x555555567a00 <variables>) at ../../src/cforth/forth.c:1337
#3  0x0000555555557d51 in main (argc=<optimized out>, argv=<optimized out>)
    at ../../src/cforth/main.c:76
(gdb) 

this tells me that the ! tried to write to read-only memory. Hope that helps, @Jos-Ven.

Jos-Ven commented 1 year ago

tccalls.txt Thanks, I changed extend.c That solved the 2* Aborted Aborted errors Unfortunately the Address exception is still there. By looking a bit closer I found a line: C(uart_read_bytes) //c uart-read-bytes { i.wait i.size i.buf i.uart_num - i.#bytes } And changed it into: C(uart_read_bytes) //c uart-read-bytes { i.wait i.size i.buf i.uart_num -- i.#bytes } That did not help. Replacing all the TABS into spaces as a test did also not help.

I have no idea where to look, or how to prevent the write to read-only memory. I attached the new tccalls.txt

MitchBradley commented 1 year ago

Push everything to a branch in your repo and provide instructions on exactly how to repro the problem.

MitchBradley commented 1 year ago

The "Aborted" is clearly caused by the missing space in tccalls.fth. The Address Exception could be caused by app.fth, which we cannot see. Hence my admonition about needing complete context.

One possible problem in app.fth is that it might be trying to call one of the ccalls functions at compile time. That would not work, because the command ./forth forth.dic tccalls.fth ../../src/app/esp32/app.fth runs on the host system, where the target ccalls functions are not present. Inside app.fth, it is okay to define Forth words that refer to ccall functions, but it is not okay to execute them until later, on the target system.

When I am debugging problems like this, I like to add lines like

.( 0) cr
...
.( 1) cr

at various places inside app.fth, to see how far it gets before the crash.

Jos-Ven commented 1 year ago

I pushed all the changed files to the my WIP branch at: https://github.com/Jos-Ven/cforth/tree/WIP The build/esp32/sdk_build/sdkconfig file was changed for my COM port. The problem occurs after: cd ~/cforth/build/esp32
rm . make flash

quozl commented 1 year ago

I've checked everything I could, but these files were not present; perhaps they invoke ccalls?

fl ../esp8266_jos/ledstrip_plotter.fth
fl ../esp8266_jos/squares.fth
MitchBradley commented 1 year ago

xmodem.fth calls short-timeout which calls timeout! which calls ms>ticks which is defined in app.fth in terms of esp-clk-cpu-freq which is implemented as a target ccall

MitchBradley commented 1 year ago

The easy solution is to remove the call to short-timeout from xmodem.fth, letting start-receiver handle the initialization of the timeout.

MitchBradley commented 1 year ago

I found the problem very quickly with the "add .( 0) cr lines" trick.

quozl commented 1 year ago

Sorry. I'd have used that if I had bothered with ESP-IDF. I'm only using it via PlatformIO lately. Some day I'll catch up.

Jos-Ven commented 1 year ago

Thank you Mitch, that is fast! Indeed after I disabled xmodem.fth I could make cforth again. I will look further into the xmodem problem. Normally I use a Wifi connection to upload files.

About: fl ../esp8266_jos/ledstrip_plotter.fth fl ../esp8266_jos/squares.fth

These lines escaped to GIT when solving so called "divergent branches" Thanks again for noticing.

Jos-Ven commented 1 year ago

I will remember the.( 0) cr lines" trick!