extend.c limit?
Jos-Ven opened this issue · 18 comments
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?
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.
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.
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).
Attach a tccalls.fth that fails. It is near-impossible to debug a problem without complete context.
tccalls.txt
Just done. Needed to change the extension to txt.
Many thanks in advance.
18 and 114 are missing a space before the closing }, so the Forth parser includes the } as part of the preceding word.
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.
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
Push everything to a branch in your repo and provide instructions on exactly how to repro the problem.
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.
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
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
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
The easy solution is to remove the call to short-timeout from xmodem.fth, letting start-receiver handle the initialization of the timeout.
I found the problem very quickly with the "add .( 0) cr lines" trick.
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.
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.
I will remember the.( 0) cr lines" trick!