| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1709,6 +1709,9 @@ def test_audit_run_stdin(self): | |||
| 1709 | 1709 | timeout=support.SHORT_TIMEOUT, | |
| 1710 | 1710 | returncode=1) | |
| 1711 | 1711 | ||
| 1712 | + def test_get_incomplete_frame(self): | ||
| 1713 | + self.run_embedded_interpreter("test_get_incomplete_frame") | ||
| 1714 | + | ||
| 1712 | 1715 | ||
| 1713 | 1716 | class MiscTests(EmbeddingTestsMixin, unittest.TestCase): | |
| 1714 | 1717 | def test_unicode_id_init(self): | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + Fix a crash occurring when :c:func:`PyEval_GetFrame` is called while the | ||
| 2 | + topmost Python frame is in a partially-initialized state. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1950,6 +1950,73 @@ static int test_repeated_init_and_inittab(void) | |||
| 1950 | 1950 | return 0; | |
| 1951 | 1951 | } | |
| 1952 | 1952 | ||
| 1953 | + static void wrap_allocator(PyMemAllocatorEx *allocator); | ||
| 1954 | + static void unwrap_allocator(PyMemAllocatorEx *allocator); | ||
| 1955 | + | ||
| 1956 | + static void * | ||
| 1957 | + malloc_wrapper(void *ctx, size_t size) | ||
| 1958 | + { | ||
| 1959 | + PyMemAllocatorEx *allocator = (PyMemAllocatorEx *)ctx; | ||
| 1960 | + unwrap_allocator(allocator); | ||
| 1961 | + PyEval_GetFrame(); // BOOM! | ||
| 1962 | + wrap_allocator(allocator); | ||
| 1963 | + return allocator->malloc(allocator->ctx, size); | ||
| 1964 | + } | ||
| 1965 | + | ||
| 1966 | + static void * | ||
| 1967 | + calloc_wrapper(void *ctx, size_t nelem, size_t elsize) | ||
| 1968 | + { | ||
| 1969 | + PyMemAllocatorEx *allocator = (PyMemAllocatorEx *)ctx; | ||
| 1970 | + return allocator->calloc(allocator->ctx, nelem, elsize); | ||
| 1971 | + } | ||
| 1972 | + | ||
| 1973 | + static void * | ||
| 1974 | + realloc_wrapper(void *ctx, void *ptr, size_t new_size) | ||
| 1975 | + { | ||
| 1976 | + PyMemAllocatorEx *allocator = (PyMemAllocatorEx *)ctx; | ||
| 1977 | + return allocator->realloc(allocator->ctx, ptr, new_size); | ||
| 1978 | + } | ||
| 1979 | + | ||
| 1980 | + static void | ||
| 1981 | + free_wrapper(void *ctx, void *ptr) | ||
| 1982 | + { | ||
| 1983 | + PyMemAllocatorEx *allocator = (PyMemAllocatorEx *)ctx; | ||
| 1984 | + allocator->free(allocator->ctx, ptr); | ||
| 1985 | + } | ||
| 1986 | + | ||
| 1987 | + static void | ||
| 1988 | + wrap_allocator(PyMemAllocatorEx *allocator) | ||
| 1989 | + { | ||
| 1990 | + PyMem_GetAllocator(PYMEM_DOMAIN_OBJ, allocator); | ||
| 1991 | + PyMemAllocatorEx wrapper = { | ||
| 1992 | + .malloc = &malloc_wrapper, | ||
| 1993 | + .calloc = &calloc_wrapper, | ||
| 1994 | + .realloc = &realloc_wrapper, | ||
| 1995 | + .free = &free_wrapper, | ||
| 1996 | + .ctx = allocator, | ||
| 1997 | + }; | ||
| 1998 | + PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &wrapper); | ||
| 1999 | + } | ||
| 2000 | + | ||
| 2001 | + static void | ||
| 2002 | + unwrap_allocator(PyMemAllocatorEx *allocator) | ||
| 2003 | + { | ||
| 2004 | + PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, allocator); | ||
| 2005 | + } | ||
| 2006 | + | ||
| 2007 | + static int | ||
| 2008 | + test_get_incomplete_frame(void) | ||
| 2009 | + { | ||
| 2010 | + _testembed_Py_Initialize(); | ||
| 2011 | + PyMemAllocatorEx allocator; | ||
| 2012 | + wrap_allocator(&allocator); | ||
| 2013 | + // Force an allocation with an incomplete (generator) frame: | ||
| 2014 | + int result = PyRun_SimpleString("(_ for _ in ())"); | ||
| 2015 | + unwrap_allocator(&allocator); | ||
| 2016 | + Py_Finalize(); | ||
| 2017 | + return result; | ||
| 2018 | + } | ||
| 2019 | + | ||
| 1953 | 2020 | ||
| 1954 | 2021 | /* ********************************************************* | |
| 1955 | 2022 | * List of test cases and the function that implements it. | |
@@ -2032,6 +2099,7 @@ static struct TestCase TestCases[] = { | |||
| 2032 | 2099 | #ifndef MS_WINDOWS | |
| 2033 | 2100 | {"test_frozenmain", test_frozenmain}, | |
| 2034 | 2101 | #endif | |
| 2102 | + {"test_get_incomplete_frame", test_get_incomplete_frame}, | ||
| 2035 | 2103 | ||
| 2036 | 2104 | {NULL, NULL} | |
| 2037 | 2105 | }; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7116,11 +7116,14 @@ _PyEval_GetFrame(void) | |||
| 7116 | 7116 | PyFrameObject * | |
| 7117 | 7117 | PyEval_GetFrame(void) | |
| 7118 | 7118 | { | |
| 7119 | - PyThreadState *tstate = _PyThreadState_GET(); | ||
| 7120 | - if (tstate->cframe->current_frame == NULL) { | ||
| 7119 | + _PyInterpreterFrame *frame = _PyEval_GetFrame(); | ||
| 7120 | + while (frame && _PyFrame_IsIncomplete(frame)) { | ||
| 7121 | + frame = frame->previous; | ||
| 7122 | + } | ||
| 7123 | + if (frame == NULL) { | ||
| 7121 | 7124 | return NULL; | |
| 7122 | 7125 | } | |
| 7123 | - PyFrameObject *f = _PyFrame_GetFrameObject(tstate->cframe->current_frame); | ||
| 7126 | + PyFrameObject *f = _PyFrame_GetFrameObject(frame); | ||
| 7124 | 7127 | if (f == NULL) { | |
| 7125 | 7128 | PyErr_Clear(); | |
| 7126 | 7129 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments