Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Feb 13, 2025. It is now read-only.
This repository was archived by the owner on Feb 13, 2025. It is now read-only.

Assertion violation in tasklet_dealloc during PyThreadState_Clear #89

Closed
@ghost

Description

Originally reported by: Anselm Kruis (Bitbucket: akruis, GitHub: akruis)


Stackless 2.7.9-slp and 2.7-slp current (commit 782a1b292460), Win-7, VS 2008 debug build

This script

#!python
from __future__ import print_function, absolute_import
import threading
import stackless
import sys

def other_thread_main():
    print("other thread started")
    assert stackless.main is stackless.current
    tasklet2 = stackless.tasklet(apply)(stackless.main.run, ())
    print("OT Main:", stackless.main)
    print("OT tasklet2:", tasklet2)
    tasklet2.run()
    return

assert stackless.main is stackless.current
print("Main Thread:", stackless.main)
t = threading.Thread(target=other_thread_main, name="other thread")
t.start()
t.join()
print("OK")

triggers Assertion failed: t->cstate->task != t || t->cstate->ob_size == 0, file ..\Stackless\module\taskletobject.c, line 207 in thread "other thread".

C-Stacktrace

 	msvcr90d.dll!_NMSG_WRITE(int rterrnum=10)  Line 198	C
 	msvcr90d.dll!abort()  Line 59 + 0x7 bytes	C
 	msvcr90d.dll!_wassert(const wchar_t * expr=0x1e2e9f88, const wchar_t * filename=0x1e2e9e48, unsigned int lineno=207)  Line 346	C
 	python27_d.dll!tasklet_dealloc(_tasklet * t=0x0261db90)  Line 207 + 0x2f bytes	C
 	python27_d.dll!_Py_Dealloc(_object * op=0x0261db90)  Line 2262 + 0x7 bytes	C
 	python27_d.dll!slp_kill_tasks_with_stacks(_ts * target_ts=0x025e8780)  Line 406 + 0x51 bytes	C
>	python27_d.dll!PyThreadState_Clear(_ts * tstate=0x025e8780)  Line 251 + 0x9 bytes	C
 	python27_d.dll!t_bootstrap(void * boot_raw=0x007dc2f8)  Line 642 + 0x9 bytes	C
 	python27_d.dll!bootstrap(void * call=0x004b1990)  Line 122 + 0x7 bytes	C
 	msvcr90d.dll!_callthreadstartex()  Line 348 + 0xf bytes	C
 	msvcr90d.dll!_threadstartex(void * ptd=0x025a12c8)  Line 331	C
 	kernel32.dll!7679338a() 	
 	[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]	
 	ntdll.dll!76ec9902() 	
 	ntdll.dll!76ec98d5() 	

Tasklet 0x0261db90 (argument of tasklet_dealloc() is tasklet2.

Analysis

The problem is in slp_kill_tasks_with_stacks(). The relevant C-code is

#!C
        PyTasklet_Kill(t);
        PyErr_Clear();

        /* must clear the tstate */
        t->cstate->tstate = NULL;
        Py_DECREF(t);

The assertion violation happens in Py_DECREF(t). t is tasklet2. It looks like PyTasklet_Kill(t) didn't "remove" the C-state from the tasklet. Findings:

  • tstate->st.main == NULL
  • tstate->st.current == tasklet2
  • tstate->frame == NULL.
  • tasklet2->f.cframe != NULL

This is caused by tasklet_end(main tasklet of other thread). I think, this state is not OK. It signals, that tasklet2 is dead, but that is wrong. As a consequence, PyTasklet_Kill(tasklet2) returns without killing tasklet2.

Questions

  1. tasklet_end(a main tasklet) does not care about other scheduled tasklets. Perhaps this is the root cause of the problem?

  2. Because this assertion violation happens when the interpreter is fully operational, it must be fixed correctly. Unfortunately I don't understand the exact purpose of the failed assertion yet.

@ctismer or @krisvale, any help is highly appreciated.

Test case is commit 2cc41427a347 for 2.7-slp


Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions