Skip to content

Commit 38a4d51

Browse files
committed
Factor running a debugger script into a helper function
1 parent d51dda0 commit 38a4d51

1 file changed

Lines changed: 66 additions & 52 deletions

File tree

Python/ceval_gil.c

Lines changed: 66 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,6 +1192,71 @@ _PyEval_DisableGIL(PyThreadState *tstate)
11921192
}
11931193
#endif
11941194

1195+
#ifdef Py_REMOTE_DEBUG
1196+
// Note that this function is inline to avoid creating a PLT entry
1197+
// that would be an easy target for a ROP gadget.
1198+
static inline void run_remote_debugger_script(const char *path)
1199+
{
1200+
if (0 != PySys_Audit("remote_debugger_script", "s", path)) {
1201+
PyErr_FormatUnraisable("Error when auditing remote debugger script %s", path);
1202+
return;
1203+
}
1204+
1205+
// Open the debugger script with the open code hook. Unfortunately this forces us to handle
1206+
// the resulting Python object, which is a file object and therefore we need to call
1207+
// Python methods on it instead of the simpler C equivalents.
1208+
PyObject* fileobj = PyFile_OpenCode(path);
1209+
if (!fileobj) {
1210+
PyErr_FormatUnraisable("Error when opening debugger script %s", path);
1211+
return;
1212+
}
1213+
1214+
#ifdef MS_WINDOWS
1215+
PyObject* path_obj = PyUnicode_FromString(path);
1216+
if (!path_obj) {
1217+
PyErr_FormatUnraisable("Error when converting remote debugger script path %s to Unicode", path);
1218+
return;
1219+
}
1220+
wchar_t* wpath = PyUnicode_AsWideCharString(path_obj, NULL);
1221+
Py_DECREF(path_obj);
1222+
if (!wpath) {
1223+
PyErr_FormatUnraisable("Error when converting remote debugger script path %s to wide char", path);
1224+
return;
1225+
}
1226+
FILE* f = _wfopen(wpath, L"r");
1227+
#else
1228+
int fd = PyObject_AsFileDescriptor(fileobj);
1229+
if (fd == -1) {
1230+
PyErr_FormatUnraisable("Error when getting file descriptor for debugger script %s", path);
1231+
return;
1232+
}
1233+
FILE* f = fdopen(fd, "r");
1234+
#endif
1235+
1236+
if (!f) {
1237+
PyErr_SetFromErrno(PyExc_OSError);
1238+
} else {
1239+
PyRun_AnyFile(f, path);
1240+
}
1241+
1242+
#ifdef MS_WINDOWS
1243+
PyMem_Free(wpath);
1244+
fclose(f);
1245+
#endif
1246+
1247+
if (PyErr_Occurred()) {
1248+
PyErr_FormatUnraisable("Error executing debugger script %s", path);
1249+
}
1250+
1251+
PyObject* res = PyObject_CallMethod(fileobj, "close", "");
1252+
if (!res) {
1253+
PyErr_FormatUnraisable("Error when closing debugger script %s", path);
1254+
} else {
1255+
Py_DECREF(res);
1256+
}
1257+
Py_DECREF(fileobj);
1258+
}
1259+
#endif
11951260

11961261
/* Do periodic things, like check for signals and async I/0.
11971262
* We need to do reasonably frequently, but not too frequently.
@@ -1327,58 +1392,7 @@ _Py_HandlePending(PyThreadState *tstate)
13271392
tstate->remote_debugger_support.debugger_pending_call = 0;
13281393
const char *path = tstate->remote_debugger_support.debugger_script_path;
13291394
if (*path) {
1330-
if (0 != PySys_Audit("remote_debugger_script", "s", path)) {
1331-
PyErr_FormatUnraisable("Error when auditing remote debugger script %s", path);
1332-
} else {
1333-
// Open the debugger script with the open code hook. Unfortunately this forces us to handle
1334-
// the resulting Python object, which is a file object and therefore we need to call
1335-
// Python methods on it instead of the simpler C equivalents.
1336-
PyObject* fileobj = PyFile_OpenCode(path);
1337-
if (!fileobj) {
1338-
PyErr_FormatUnraisable("Error when opening debugger script %s", path);
1339-
return 0;
1340-
}
1341-
#ifdef MS_WINDOWS
1342-
PyObject* path_obj = PyUnicode_FromString(path);
1343-
if (!path_obj) {
1344-
PyErr_FormatUnraisable("Error when converting remote debugger script path %s to Unicode", path);
1345-
return 0;
1346-
}
1347-
wchar_t* wpath = PyUnicode_AsWideCharString(path_obj, NULL);
1348-
Py_DECREF(path_obj);
1349-
if (!wpath) {
1350-
PyErr_FormatUnraisable("Error when converting remote debugger script path %s to wide char", path);
1351-
return 0;
1352-
}
1353-
FILE* f = _wfopen(wpath, L"r");
1354-
#else
1355-
int fd = PyObject_AsFileDescriptor(fileobj);
1356-
if (fd == -1) {
1357-
PyErr_FormatUnraisable("Error when getting file descriptor for debugger script %s", path);
1358-
return 0;
1359-
}
1360-
FILE* f = fdopen(fd, "r");
1361-
#endif
1362-
if (!f) {
1363-
PyErr_SetFromErrno(PyExc_OSError);
1364-
} else {
1365-
PyRun_AnyFile(f, path);
1366-
}
1367-
#ifdef MS_WINDOWS
1368-
PyMem_Free(wpath);
1369-
fclose(f);
1370-
#endif
1371-
if (PyErr_Occurred()) {
1372-
PyErr_FormatUnraisable("Error executing debugger script %s", path);
1373-
}
1374-
PyObject* res = PyObject_CallMethod(fileobj, "close", "");
1375-
if (!res) {
1376-
PyErr_FormatUnraisable("Error when closing debugger script %s", path);
1377-
} else {
1378-
Py_DECREF(res);
1379-
}
1380-
Py_DECREF(fileobj);
1381-
}
1395+
run_remote_debugger_script(path);
13821396
}
13831397
}
13841398
}

0 commit comments

Comments
 (0)