Skip to content

uasyncio : missing RuntimeError: This event loop is already running #8515

Open

Description

@fragmuffin

I've just spent far too long debugging, what is essentially the following code:

#!/usr/bin/env python
try:
    import asyncio
except ImportError:
    import uasyncio as asyncio

loop = asyncio.get_event_loop()

async def foo():
    print('foo()')

async def main():
    loop.run_until_complete(foo())
    while True:
        print('app_loop()')
        await asyncio.sleep(1)

if __name__ == '__main__':
    loop.run_until_complete(main())

I know what you're thinking.... why run_until_complete inside an async function.
I completely agree, and now that I have the root cause, it's easy to fix.

However: this was nested inside a relatively large code-base, and I had no trace-back leading me to the root cause.
Finding this required a lot of cutting code until the problem went away, which wasn't helped by it being in 2 places.

Run on CPython

When run on Python 3.9.9, it raises.

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/usr/lib/python3.9/asyncio/base_events.py", line 647, in run_until_complete
    return future.result()
  File "<stdin>", line 2, in main
  File "/usr/lib/python3.9/asyncio/base_events.py", line 623, in run_until_complete
    self._check_running()
  File "/usr/lib/python3.9/asyncio/base_events.py", line 583, in _check_running
    raise RuntimeError('This event loop is already running')
RuntimeError: This event loop is already running

Run on micropython

When the above code is executed in micropython I get the following output.

MicroPython v1.17 on 2021-09-02; PYBD-SF6W with STM32F767IIK
Type "help()" for more information.
>>> 
paste mode; Ctrl-C to cancel, Ctrl-D to finish
=== # ... above code pasted here
=== 
foo()
app_loop()
>>> 

Execution took 1 second, no exception raised.

Activity

  1. added
    extmodRelates to extmod/ directory in source
    on Apr 11, 2022
  2. dpgeorge commented on Apr 11, 2022

    @dpgeorge
    Member

    Idea for a fix: track if the event loop is already running is by using the cur_task variable. It can be None if no loop is running.

    See related #7471. Also #8340.

  3. added a commit that references this issue on Oct 24, 2023
  4. agatti commented on Mar 23, 2026

    @agatti
    Contributor

    Well, the sample code on git master now crashes :|

    Stack trace:

    (gdb) r a2.py
    Starting program: /home/agatti/src/micropython/ports/unix/build-standard/micropython a2.py
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/usr/lib/libthread_db.so.1".
    foo()
    app_loop()
    
    Program received signal SIGSEGV, Segmentation fault.
    task_queue_push (n_args=3, args=0x7fffffff9630) at ../../extmod/modasyncio.c:118
    118         task->data = mp_const_none;
    (gdb) bt
    #0  task_queue_push (n_args=3, args=0x7fffffff9630) at ../../extmod/modasyncio.c:118
    #1  0x000055555559bc61 in fun_builtin_var_call (self_in=0x55555564b020 <task_queue_push_obj>, n_args=3, n_kw=0, args=0x7fffffff9630) at ../../py/objfun.c:123
    #2  0x0000555555591afc in mp_call_function_n_kw (fun_in=0x55555564b020 <task_queue_push_obj>, n_args=3, n_kw=0, args=0x7fffffff9630) at ../../py/runtime.c:716
    #3  0x0000555555591cb3 in mp_call_method_n_kw (n_args=<optimized out>, n_kw=<optimized out>, args=args@entry=0x7fffffff9628) at ../../py/runtime.c:732
    #4  0x00005555555afda8 in mp_execute_bytecode (code_state=code_state@entry=0x7fffffff9600, inject_exc=inject_exc@entry=0x0) at ../../py/vm.c:1069
    #5  0x000055555559be65 in fun_bc_call (self_in=0x7ffff7a449a0, n_args=1, n_kw=0, args=0x7fffffff9708) at ../../py/objfun.c:294
    #6  0x0000555555591afc in mp_call_function_n_kw (fun_in=0x7ffff7a449a0, n_args=1, n_kw=n_kw@entry=0, args=0x7fffffff9708) at ../../py/runtime.c:716
    #7  0x0000555555591cb3 in mp_call_method_n_kw (n_args=n_args@entry=0, n_kw=n_kw@entry=0, args=args@entry=0x7fffffff9700) at ../../py/runtime.c:732
    #8  0x00005555555922d0 in mp_resume (self_in=0x7ffff7a44860, send_value=0x6, throw_value=throw_value@entry=0x0, ret_val=ret_val@entry=0x7fffffff9798) at ../../py/runtime.c:1454
    #9  0x00005555555b1133 in mp_execute_bytecode (code_state=code_state@entry=0x7ffff7a45230, inject_exc=inject_exc@entry=0x0) at ../../py/vm.c:1230
    #10 0x000055555559c618 in mp_obj_gen_resume (self_in=0x7ffff7a45220, send_value=<optimized out>, throw_value=throw_value@entry=0x0, ret_val=ret_val@entry=0x7fffffff9870) at ../../py/objgenerator.c:210
    #11 0x000055555559c6b3 in gen_resume_and_raise (self_in=<optimized out>, send_value=<optimized out>, throw_value=throw_value@entry=0x0, raise_stop_iteration=raise_stop_iteration@entry=true) at ../../py/objgenerator.c:259
    #12 0x000055555559c75f in gen_instance_send (self_in=<optimized out>, send_value=<optimized out>) at ../../py/objgenerator.c:286
    #13 0x000055555559bb81 in fun_builtin_2_call (self_in=0x555555646c40 <gen_instance_send_obj>, n_args=<optimized out>, n_kw=<optimized out>, args=0x7ffff7a45690) at ../../py/objfun.c:82
    #14 0x0000555555591afc in mp_call_function_n_kw (fun_in=0x555555646c40 <gen_instance_send_obj>, n_args=2, n_kw=0, args=0x7ffff7a45690) at ../../py/runtime.c:716
    #15 0x0000555555591cb3 in mp_call_method_n_kw (n_args=<optimized out>, n_kw=<optimized out>, args=args@entry=0x7ffff7a45688) at ../../py/runtime.c:732
    #16 0x00005555555afda8 in mp_execute_bytecode (code_state=code_state@entry=0x7ffff7a45660, inject_exc=inject_exc@entry=0x0) at ../../py/vm.c:1069
    #17 0x000055555559be65 in fun_bc_call (self_in=0x7ffff7a44ac0, n_args=1, n_kw=0, args=0x7fffffff9ba0) at ../../py/objfun.c:294
    #18 0x0000555555591afc in mp_call_function_n_kw (fun_in=0x7ffff7a44ac0, n_args=1, n_kw=0, args=args@entry=0x7fffffff9ba0) at ../../py/runtime.c:716
    #19 0x00005555555afe07 in mp_execute_bytecode (code_state=code_state@entry=0x7fffffff9b70, inject_exc=inject_exc@entry=0x0) at ../../py/vm.c:984
    #20 0x000055555559be65 in fun_bc_call (self_in=0x7ffff7a44ea0, n_args=1, n_kw=0, args=0x7fffffff9d88) at ../../py/objfun.c:294
    #21 0x0000555555591afc in mp_call_function_n_kw (fun_in=0x7ffff7a44ea0, n_args=1, n_kw=0, args=0x7fffffff9d88) at ../../py/runtime.c:716
    #22 0x0000555555591cb3 in mp_call_method_n_kw (n_args=<optimized out>, n_kw=<optimized out>, args=args@entry=0x7fffffff9d78) at ../../py/runtime.c:732
    #23 0x00005555555afda8 in mp_execute_bytecode (code_state=code_state@entry=0x7fffffff9d50, inject_exc=inject_exc@entry=0x0) at ../../py/vm.c:1069
    #24 0x000055555559be65 in fun_bc_call (self_in=0x7ffff7a44280, n_args=0, n_kw=0, args=0x0) at ../../py/objfun.c:294
    #25 0x0000555555591afc in mp_call_function_n_kw (fun_in=fun_in@entry=0x7ffff7a44280, n_args=n_args@entry=0, n_kw=n_kw@entry=0, args=args@entry=0x0) at ../../py/runtime.c:716
    #26 0x0000555555591b42 in mp_call_function_0 (fun=fun@entry=0x7ffff7a44280) at ../../py/runtime.c:690
    #27 0x00005555555fe77c in parse_compile_execute (source=<optimized out>, input_kind=input_kind@entry=MP_PARSE_FILE_INPUT, exec_flags=exec_flags@entry=32) at ../../shared/runtime/pyexec.c:137
    #28 0x00005555555fed1a in pyexec_file (filename=<optimized out>) at ../../shared/runtime/pyexec.c:737
    #29 0x00005555555fadbd in do_file (file=<optimized out>) at main.c:269
    #30 0x00005555555fb42d in main_ (argc=argc@entry=2, argv=argv@entry=0x7fffffffa188) at main.c:692
    #31 0x00005555555fb63c in main (argc=2, argv=0x7fffffffa188) at main.c:452
    (gdb) 
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    extmodRelates to extmod/ directory in sourceport-unix

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions