Blender V5.0
bpy_threads.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11
12#include <Python.h>
13
14#include "python_compat.hh" /* IWYU pragma: keep. */
15
16#include "../BPY_extern.hh"
17
19{
20 /* Use `_PyThreadState_UncheckedGet()` instead of `PyThreadState_Get()`, to avoid a fatal error
21 * issued when a thread state is nullptr (the thread state can be nullptr when quitting Blender).
22 *
23 * `PyEval_SaveThread()` will release the GIL, so this thread has to have the GIL to begin with
24 * or badness will ensue. */
25 if (PyThreadState_GetUnchecked() && PyGILState_Check()) {
26 return (BPy_ThreadStatePtr)PyEval_SaveThread();
27 }
28 return nullptr;
29}
30
32{
33 if (tstate) {
34 PyEval_RestoreThread((PyThreadState *)tstate);
35 }
36}
37
39{
40 PyThreadState *tstate = PyGILState_GetThisThreadState();
41
42 if (tstate) {
43 PyFrameObject *frame = PyThreadState_GetFrame(tstate);
44
45 printf(frame ? "Python stack trace:\n" : "No Python stack trace available.\n");
46
47 while (frame) {
48 PyCodeObject *frame_co = PyFrame_GetCode(frame);
49 int line = PyFrame_GetLineNumber(frame);
50 const char *filename = PyUnicode_AsUTF8(frame_co->co_filename);
51 const char *funcname = PyUnicode_AsUTF8(frame_co->co_name);
52 printf(" %s:%d %s\n", filename, line, funcname);
53 Py_DECREF(frame_co);
54 PyFrameObject *frame_back = PyFrame_GetBack(frame);
55 Py_DECREF(frame);
56 frame = frame_back;
57 }
58 printf("\n");
59 }
60 else {
61 printf("No Python thread state available.\n");
62 }
63}
void * BPy_ThreadStatePtr
Definition BPY_extern.hh:40
void BPY_thread_restore(BPy_ThreadStatePtr tstate)
BPy_ThreadStatePtr BPY_thread_save()
void BPY_thread_backtrace_print()
#define printf(...)
header-only compatibility defines.
Py_DECREF(oname)
#define PyThreadState_GetUnchecked