leftmike / foment

Foment is an implementation of R7RS Scheme.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Assertion fails in foment.hpp, line 336

jpellegrini opened this issue · comments

Hello,

I have compiled Foment for a little endian MIPS platform, and got a failed assertion:

assert: Size * AllSlots() * 2 + ExtraSlots() >= Padding() / sizeof(FObject) (336)../src/foment.hpp

I'm not sure wether it's a bug or if I actually did something wrong when compiling. Basically, I ser FOMENT_LITTLE_ENDIAN=1

Any idea of what could have caused this?

And thanks for the great work on Foment!

It looks like you are compiling for 32 bit. I am not sure what is happening. Can you give me more details about the environment you are trying to run it in?

FYI, FOMENT_LITTLE_ENDIAN is the default, so you shouldn't need to set it.

I have compiled it for a MIPS 24KEc V5.0 system -- it is a wireless router.
I had done that before on a big endian system, and it worked fine; the little endian one doesn't.
This was compiled inside the OpenWRT buildroot, usinf gcc 7.5.0 and linked with musl and uClibc++.
What else could I do to help diagnose this?

In this page -- https://gitlab.com/jpellegrini/openwrt-packages -- there is a description of what I have been doing (Foment is one cool Scheme to have on a wifi router, since it's very small)

I added support for printing a C/C++ stack backtrace when an assertion is hit; please pull the latest and send me the backtrace that you get.

When does the assert happen?

The crash happens at startup, before anything is printed:

root@router:~# foment 

assert: Size * AllSlots() * 2 + ExtraSlots() >= Padding() / sizeof(FObject) (336)../src/foment.hpp
root@router:~# 

I tried the new version with the stacktrace printing code, but it doesn't compile, because execinfo.h is not available (it is part of gnulib, which is not available for this platform).

It seems to be related to endianness -- the same source for Foment compiles and runs perfectly on big endian MIPS, but not on little endian MIPS.

I am trying to build and reproduce on openwrt. Are you running on hardware or an emulator? Should I use MIPS Malta CoreLV board (qemu) for the target system?

I am trying to build and reproduce on openwrt. Are you running on hardware or an emulator? Should I use MIPS Malta CoreLV board (qemu) for the target system?

The crash happens on little endian MIPS (it does work fine on big endian). Specifically, I compiled for

target = MediaTek Ralink MIPS
subtarget = MT7620 based boards

which is what my device is compatible with.

I did not try building for the emulator, but perhaps the MIPS Malta qemu with little endian subtarget is enough to trigger it. I'll also try that later.

I have included a debugging print line, just because it was easy to do:

    std::cerr << "Size = " 
                  << Size <<  std::endl 
                  << "AllSlots() = " << AllSlots() <<  std::endl
                  << "ExtraSlots() = " << ExtraSlots() <<  std::endl
                  << "Pading() = "     << Padding() <<  std::endl
                  << "sizeof(FObject) = " << sizeof(FObject) <<  std::endl;
     FAssert(Size * AllSlots() * 2 + ExtraSlots() >= Padding() / sizeof(FObject));

The last part of the output is shown below.

Size = 1
AllSlots() = 0
ExtraSlots() = 0
Pading() = 0
sizeof(FObject) = 4
Size = 2048
AllSlots() = 1
ExtraSlots() = 0
Pading() = 0
sizeof(FObject) = 4
Size = 2048
AllSlots() = 1
ExtraSlots() = 0
Pading() = 0
sizeof(FObject) = 4
Size = 3
AllSlots() = 0
ExtraSlots() = 3
Pading() = 0
sizeof(FObject) = 4
Size = 3
AllSlots() = 0
ExtraSlots() = 3
Pading() = 0
sizeof(FObject) = 4
Size = 2048
AllSlots() = 1
ExtraSlots() = 0
Pading() = 0
sizeof(FObject) = 4
Size = 2048
AllSlots() = 1
ExtraSlots() = 0
Pading() = 0
sizeof(FObject) = 4
Size = 8
AllSlots() = 0
ExtraSlots() = 0
Pading() = 4
sizeof(FObject) = 4

assert: Size * AllSlots() * 2 + ExtraSlots() >= Padding() / sizeof(FObject) (344)../src/foment.hpp

So at some moment, AllSlots() and ExtraSlots() returned zero, but Padding() was non-zero. It looks like that is not supposed to happen (?)

I have compiled and installed several versions, and I believe the problem was introduced with commit 7b8acf6 (simplify objhdr and allow more tags)

And that commit indeed deals with object sizes.

Hello!
I'm not sure if you'd have the time to look into this; I have managed to compile Foment on a big endian device, but it still fails at that same assertion,

# foment 

assert: Size * AllSlots() * 2 + ExtraSlots() >= Padding() / sizeof(FObject) (322)../src/foment.hpp

If it's not something you'd be able (or willing) to fix, tell me -- this issue wouldn't need to stay open then.

The package I build is here,

https://gitlab.com/jpellegrini/openwrt-packages/-/tree/master/not-yet-working/package/foment/20220409-07b8724b3a14bba7188245fea2415daad4ec64d0

but I have built it for a physical device. Maybe it will also fail the same assertion on qemu (?).
The instructions to run it are here: https://gitlab.com/jpellegrini/openwrt-packages/-/blob/master/instructions.md

I am planning to get it fixed. I am currently simplifying the memory management code. Once I am done with that, I will figure this defect out -- if it still happens.

Can you try it again using the gc branch?

git pull
git checkout gc
make clean
make test-all

I simplified memory management and made sure that it works on 32 bit Windows (x86).

Can you try it again using the gc branch?

It works! :)
It's not only windows... I was using it on a 32-bit Linux device (wireless router). And it's ok now!
Thank you!

Already made this new version available at https://gitlab.com/jpellegrini/openwrt-packages !

Fixed by 12a71f5.