Assert error during garbage collection [Solved]

Discussion and questions about boards that can run MicroPython but don't have a dedicated forum.
Target audience: Everyone interested in running MicroPython on other hardware.
User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Assert error during garbage collection [Solved]

Post by Roberthh » Sat Apr 18, 2020 8:58 am

Hello Dave, hello @stijn aka stinos,
that was it, it seems. Inclduign the helper functions remove the error, as fas as I tested it.
Thanks a lot.

stijn
Posts: 735
Joined: Thu Apr 24, 2014 9:13 am

Re: Assert error during garbage collection [Solved]

Post by stijn » Sat Apr 18, 2020 9:19 am

Nice!

Can you post the diff here, or a link to it, so the solution is easy to find in the future? This might very well happen again and by now this thread has a bunch of interesting information (actually, almost to the point it should be in the documentation or wiki, or made stciky or so) so would be ideal if it's complete.

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Assert error during garbage collection [Solved]

Post by Roberthh » Sat Apr 18, 2020 12:15 pm

Hello Stijn,
the changed gc_collect() function/file reads as:

Code: Select all

#include <stdio.h>
#include <stdint.h>

#include "py/obj.h"
#include "py/gc.h"
#include "py/mpthread.h"
#include "lib/utils/gchelper.h"

void gc_collect(void) {
    // start the GC
    gc_collect_start();

    // get the registers and the sp
    uintptr_t regs[10];
    uintptr_t sp = gc_helper_get_regs_and_sp(regs);

    // trace the stack, including the registers (since they live [now] on the stack in this function)
#if MICROPY_PY_THREAD
    gc_collect_root((void **)sp, ((uint32_t)MP_STATE_THREAD(stack_top) - sp) / sizeof(uint32_t));
#else
    gc_collect_root((void **)sp, ((uint32_t)(mpy_task_stk + MPY_STACK_LEN) - sp) / sizeof(uint32_t));
#endif

    // trace root pointers from any threads
#if MICROPY_PY_THREAD
    mp_thread_gc_others();
#endif

    // end the GC
    gc_collect_end();
}
The change consisted of replacing the line:

Code: Select all

    uintptr_t sp = get_sp();
with

Code: Select all

    // get the registers and the sp
    uintptr_t regs[10];
    uintptr_t sp = gc_helper_get_regs_and_sp(regs);
and including the respective header file: #include "lib/utils/gchelper.h"
I did not test the non-threading variant, but opposed to the initial version it now uses the proper addresses for the stack.
The set of files I'm working with is available in my fork of MP as branch w60x. In contrast to the WinnerMicro version is is based on MP version 1.12. https://github.com/robert-hh/micropython/tree/w60x

stijn
Posts: 735
Joined: Thu Apr 24, 2014 9:13 am

Re: Assert error during garbage collection [Solved]

Post by stijn » Sat Apr 18, 2020 12:47 pm

From the looks of it the non-threading one should be fine as well since the registers were the clue.

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Assert error during garbage collection [Solved]

Post by Roberthh » Mon Apr 20, 2020 10:07 am

Just a question about gc_collect. What is the task gc_collect_root()? Do I understand it right that it searched the stack, or in general, all memory outside the Python heap, for pointers to objects acquired from the python heap and marks them as used?

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Assert error during garbage collection [Solved]

Post by dhylands » Mon Apr 20, 2020 1:38 pm

gc_collect_root scans a region of memory for root pointers (I.e pointers into the heap) and marks those heap blocks as in-use. gc_collect_start has some calls to gc_collect_root for known areas. The port implementation of gc_collect adds calls to any additional regions of memory which might contain root pointers.

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Assert error during garbage collection [Solved]

Post by Roberthh » Mon Apr 20, 2020 3:50 pm

Thank you. That is a very clear answer.

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Assert error during garbage collection [Solved]

Post by jimmo » Thu Apr 23, 2020 6:24 am

Roberthh wrote:
Mon Apr 20, 2020 10:07 am
Just a question about gc_collect. What is the task gc_collect_root()? Do I understand it right that it searched the stack, or in general, all memory outside the Python heap, for pointers to objects acquired from the python heap and marks them as used?
This thread is part of the inspiration behind https://github.com/micropython/micropython/pull/5961 (step one in some improvements for making it easier to get this right in ports). Although this change alone might not have been enough, there's so many little details that are hard to get right in a new port that it's worth trying to improve them.

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Assert error during garbage collection [Solved]

Post by Roberthh » Thu Apr 23, 2020 1:34 pm

Thanks, Jimmo. That is surely worth considering. The hint Dave gave was in the same direction and solved the problem. Your's seems a little bit more convenient to use being it a C file which is included, and it also already contains the statement for stack cleanup.
Still, there is some trouble in the code when using LittleFS. Both trouble to the RAM which leads to the file system inaccessible, which disappears after boot, and file corruption. Indeed, that may be related. No problem when using FAT.

Post Reply