Skip to content

Commit c4f8338

Browse files
committed
patch 8.0.0698: crash on exit when using Python function in timer.
Problem: When a timer uses ":pyeval" or another Python command and it happens to be triggered while exiting a Crash may happen. (Ricky Zhou) Solution: Avoid running a Python command after python_end() was called. Do not trigger timers while exiting. (closes #1824)
1 parent 8858498 commit c4f8338

4 files changed

Lines changed: 17 additions & 2 deletions

File tree

src/ex_cmds2.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,6 +1183,7 @@ timer_callback(timer_T *timer)
11831183
/*
11841184
* Call timers that are due.
11851185
* Return the time in msec until the next timer is due.
1186+
* Returns -1 if there are no pending timers.
11861187
*/
11871188
long
11881189
check_due_timer(void)
@@ -1197,6 +1198,10 @@ check_due_timer(void)
11971198
# ifdef WIN3264
11981199
LARGE_INTEGER fr;
11991200

1201+
/* Don't run any timers while exiting. */
1202+
if (exiting)
1203+
return next_due;
1204+
12001205
QueryPerformanceFrequency(&fr);
12011206
# endif
12021207
profile_start(&now);

src/if_python.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,7 @@ get_exceptions(void)
779779

780780
static int initialised = 0;
781781
#define PYINITIALISED initialised
782+
static int python_end_called = FALSE;
782783

783784
#define DESTRUCTOR_FINISH(self) self->ob_type->tp_free((PyObject*)self);
784785

@@ -878,6 +879,7 @@ python_end(void)
878879
if (recurse != 0)
879880
return;
880881

882+
python_end_called = TRUE;
881883
++recurse;
882884

883885
#ifdef DYNAMIC_PYTHON
@@ -1040,6 +1042,8 @@ DoPyCommand(const char *cmd, rangeinitializer init_range, runner run, void *arg)
10401042
}
10411043
++recursive;
10421044
#endif
1045+
if (python_end_called)
1046+
return;
10431047

10441048
#if defined(MACOS) && !defined(MACOS_X_UNIX)
10451049
GetPort(&oldPort);
@@ -1568,7 +1572,7 @@ do_pyeval (char_u *str, typval_T *rettv)
15681572
(rangeinitializer) init_range_eval,
15691573
(runner) run_eval,
15701574
(void *) rettv);
1571-
switch(rettv->v_type)
1575+
switch (rettv->v_type)
15721576
{
15731577
case VAR_DICT: ++rettv->vval.v_dict->dv_refcount; break;
15741578
case VAR_LIST: ++rettv->vval.v_list->lv_refcount; break;

src/if_python3.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -733,8 +733,8 @@ get_py3_exceptions(void)
733733
#endif /* DYNAMIC_PYTHON3 */
734734

735735
static int py3initialised = 0;
736-
737736
#define PYINITIALISED py3initialised
737+
static int python_end_called = FALSE;
738738

739739
#define DESTRUCTOR_FINISH(self) Py_TYPE(self)->tp_free((PyObject*)self)
740740

@@ -817,6 +817,7 @@ python3_end(void)
817817
if (recurse != 0)
818818
return;
819819

820+
python_end_called = TRUE;
820821
++recurse;
821822

822823
#ifdef DYNAMIC_PYTHON3
@@ -938,6 +939,9 @@ DoPyCommand(const char *cmd, rangeinitializer init_range, runner run, void *arg)
938939
PyObject *cmdbytes;
939940
PyGILState_STATE pygilstate;
940941

942+
if (python_end_called)
943+
goto theend;
944+
941945
#if defined(MACOS) && !defined(MACOS_X_UNIX)
942946
GetPort(&oldPort);
943947
/* Check if the Python library is available */

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,8 @@ static char *(features[]) =
764764

765765
static int included_patches[] =
766766
{ /* Add new patch number below this line */
767+
/**/
768+
698,
767769
/**/
768770
697,
769771
/**/

0 commit comments

Comments
 (0)