@@ -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