@@ -67,6 +67,7 @@ extern "C" {
6767#include <tlhelp32.h>
6868#endif
6969
70+ #include <assert.h>
7071#include <errno.h>
7172#include <fcntl.h>
7273#include <stddef.h>
@@ -165,6 +166,7 @@ _Py_RemoteDebug_InitProcHandle(proc_handle_t *handle, pid_t pid) {
165166 handle -> task = pid_to_task (handle -> pid );
166167 if (handle -> task == 0 ) {
167168 _set_debug_exception_cause (PyExc_RuntimeError , "Failed to initialize macOS process handle" );
169+ assert (PyErr_Occurred ());
168170 return -1 ;
169171 }
170172#elif defined(MS_WINDOWS )
@@ -174,6 +176,7 @@ _Py_RemoteDebug_InitProcHandle(proc_handle_t *handle, pid_t pid) {
174176 if (handle -> hProcess == NULL ) {
175177 PyErr_SetFromWindowsErr (0 );
176178 _set_debug_exception_cause (PyExc_RuntimeError , "Failed to initialize Windows process handle" );
179+ assert (PyErr_Occurred ());
177180 return -1 ;
178181 }
179182#elif defined(__linux__ )
@@ -248,6 +251,7 @@ return_section_address64(
248251 "mach_vm_region failed while parsing 64-bit Mach-O binary "
249252 "at base address 0x%lx (kern_return_t: %d)" ,
250253 base , ret );
254+ assert (PyErr_Occurred ());
251255 return 0 ;
252256 }
253257 }
@@ -311,6 +315,7 @@ return_section_address32(
311315 "mach_vm_region failed while parsing 32-bit Mach-O binary "
312316 "at base address 0x%lx (kern_return_t: %d)" ,
313317 base , ret );
318+ assert (PyErr_Occurred ());
314319 return 0 ;
315320 }
316321 }
@@ -352,13 +357,15 @@ return_section_address_fat(
352357 "Failed to determine CPU type via sysctlbyname "
353358 "for fat binary analysis at 0x%lx: %s" ,
354359 base , strerror (errno ));
360+ assert (PyErr_Occurred ());
355361 return 0 ;
356362 }
357363 if (sysctlbyname ("hw.cpu64bit_capable" , & is_abi64 , & abi64_size , NULL , 0 ) != 0 ) {
358364 PyErr_Format (PyExc_OSError ,
359365 "Failed to determine CPU ABI capability via sysctlbyname "
360366 "for fat binary analysis at 0x%lx: %s" ,
361367 base , strerror (errno ));
368+ assert (PyErr_Occurred ());
362369 return 0 ;
363370 }
364371
@@ -403,6 +410,7 @@ return_section_address_fat(
403410 "No matching architecture found for CPU type 0x%x "
404411 "in fat binary at base 0x%lx (%u architectures examined)" ,
405412 cpu , base , nfat_arch );
413+ assert (PyErr_Occurred ());
406414 return 0 ;
407415}
408416
@@ -414,6 +422,7 @@ search_section_in_file(const char* secname, char* path, uintptr_t base, mach_vm_
414422 PyErr_Format (PyExc_OSError ,
415423 "Cannot open binary file '%s' for section '%s' search: %s" ,
416424 path , secname , strerror (errno ));
425+ assert (PyErr_Occurred ());
417426 return 0 ;
418427 }
419428
@@ -423,6 +432,7 @@ search_section_in_file(const char* secname, char* path, uintptr_t base, mach_vm_
423432 "Cannot get file size for binary '%s' during section '%s' search: %s" ,
424433 path , secname , strerror (errno ));
425434 close (fd );
435+ assert (PyErr_Occurred ());
426436 return 0 ;
427437 }
428438
@@ -432,6 +442,7 @@ search_section_in_file(const char* secname, char* path, uintptr_t base, mach_vm_
432442 "Cannot memory map binary file '%s' (size: %lld bytes) for section '%s' search: %s" ,
433443 path , (long long )fs .st_size , secname , strerror (errno ));
434444 close (fd );
445+ assert (PyErr_Occurred ());
435446 return 0 ;
436447 }
437448
@@ -455,6 +466,7 @@ search_section_in_file(const char* secname, char* path, uintptr_t base, mach_vm_
455466 PyErr_Format (PyExc_RuntimeError ,
456467 "Unrecognized Mach-O magic number 0x%x in binary file '%s' for section '%s' search" ,
457468 magic , path , secname );
469+ assert (PyErr_Occurred ());
458470 break ;
459471 }
460472
@@ -486,6 +498,7 @@ pid_to_task(pid_t pid)
486498 "Cannot get task port for PID %d (kern_return_t: %d). "
487499 "This typically requires running as root or having the 'com.apple.system-task-ports' entitlement." ,
488500 pid , result );
501+ assert (PyErr_Occurred ());
489502 return 0 ;
490503 }
491504 return task ;
@@ -506,6 +519,7 @@ search_map_for_section(proc_handle_t *handle, const char* secname, const char* s
506519 "Cannot get task port for PID %d during section search" ,
507520 handle -> pid );
508521 }
522+ assert (PyErr_Occurred ());
509523 return 0 ;
510524 }
511525
@@ -671,6 +685,7 @@ search_linux_map_for_section(proc_handle_t *handle, const char* secname, const c
671685 PyErr_Format (PyExc_OSError ,
672686 "Cannot open process memory map file '%s' for PID %d section search: %s" ,
673687 maps_file_path , handle -> pid , strerror (errno ));
688+ assert (PyErr_Occurred ());
674689 return 0 ;
675690 }
676691
@@ -832,6 +847,8 @@ static void* analyze_pe(const wchar_t* mod_path, BYTE* remote_base, const char*
832847 CloseHandle (hMap );
833848 CloseHandle (hFile );
834849
850+ /* Assert that if we're returning NULL, an exception should be set somewhere up the call stack */
851+ assert (runtime_addr != NULL || PyErr_Occurred ());
835852 return runtime_addr ;
836853}
837854
@@ -850,6 +867,7 @@ search_windows_map_for_section(proc_handle_t* handle, const char* secname, const
850867 "Unable to create module snapshot for PID %d section '%s' "
851868 "search (error %lu). Check permissions or PID validity" ,
852869 handle -> pid , secname , error );
870+ assert (PyErr_Occurred ());
853871 return 0 ;
854872 }
855873
@@ -923,6 +941,7 @@ _Py_RemoteDebug_GetPyRuntimeAddress(proc_handle_t* handle)
923941#else
924942 _set_debug_exception_cause (PyExc_RuntimeError ,
925943 "Reading the PyRuntime section is not supported on this platform" );
944+ assert (PyErr_Occurred ());
926945 return 0 ;
927946#endif
928947
@@ -942,6 +961,7 @@ open_proc_mem_fd(proc_handle_t *handle)
942961 PyErr_SetFromErrno (PyExc_OSError );
943962 _set_debug_exception_cause (PyExc_OSError ,
944963 "failed to open file %s: %s" , mem_file_path , strerror (errno ));
964+ assert (PyErr_Occurred ());
945965 return -1 ;
946966 }
947967 return 0 ;
@@ -974,6 +994,7 @@ read_remote_memory_fallback(proc_handle_t *handle, uintptr_t remote_address, siz
974994 "preadv failed for PID %d at address 0x%lx "
975995 "(size %zu, partial read %zd bytes): %s" ,
976996 handle -> pid , remote_address + result , len - result , result , strerror (errno ));
997+ assert (PyErr_Occurred ());
977998 return -1 ;
978999 }
9791000
@@ -998,6 +1019,7 @@ _Py_RemoteDebug_ReadRemoteMemory(proc_handle_t *handle, uintptr_t remote_address
9981019 if (!is_process_alive (handle -> hProcess )) {
9991020 _set_errno (ESRCH );
10001021 PyErr_SetFromErrno (PyExc_OSError );
1022+ assert (PyErr_Occurred ());
10011023 return -1 ;
10021024 }
10031025 PyErr_SetFromWindowsErr (0 );
@@ -1006,6 +1028,7 @@ _Py_RemoteDebug_ReadRemoteMemory(proc_handle_t *handle, uintptr_t remote_address
10061028 "ReadProcessMemory failed for PID %d at address 0x%lx "
10071029 "(size %zu, partial read %zu bytes): Windows error %lu" ,
10081030 handle -> pid , remote_address + result , len - result , result , error );
1031+ assert (PyErr_Occurred ());
10091032 return -1 ;
10101033 }
10111034 result += read_bytes ;
@@ -1033,12 +1056,14 @@ _Py_RemoteDebug_ReadRemoteMemory(proc_handle_t *handle, uintptr_t remote_address
10331056 }
10341057 PyErr_SetFromErrno (PyExc_OSError );
10351058 if (errno == ESRCH ) {
1059+ assert (PyErr_Occurred ());
10361060 return -1 ;
10371061 }
10381062 _set_debug_exception_cause (PyExc_OSError ,
10391063 "process_vm_readv failed for PID %d at address 0x%lx "
10401064 "(size %zu, partial read %zd bytes): %s" ,
10411065 handle -> pid , remote_address + result , len - result , result , strerror (errno ));
1066+ assert (PyErr_Occurred ());
10421067 return -1 ;
10431068 }
10441069
@@ -1094,6 +1119,7 @@ _Py_RemoteDebug_ReadRemoteMemory(proc_handle_t *handle, uintptr_t remote_address
10941119 "(size %zu): kern_return_t %d" ,
10951120 handle -> pid , remote_address , len , kr );
10961121 }
1122+ assert (PyErr_Occurred ());
10971123 return -1 ;
10981124 }
10991125 return 0 ;
@@ -1108,6 +1134,7 @@ _Py_RemoteDebug_PagedReadRemoteMemory(proc_handle_t *handle,
11081134 size_t size ,
11091135 void * out )
11101136{
1137+ int result = 0 ;
11111138 size_t page_size = handle -> page_size ;
11121139 uintptr_t page_base = addr & ~(page_size - 1 );
11131140 size_t offset_in_page = addr - page_base ;
@@ -1136,6 +1163,7 @@ _Py_RemoteDebug_PagedReadRemoteMemory(proc_handle_t *handle,
11361163 "Cannot allocate %zu bytes for page cache entry "
11371164 "during read from PID %d at address 0x%lx" ,
11381165 page_size , handle -> pid , addr );
1166+ assert (PyErr_Occurred ());
11391167 return -1 ;
11401168 }
11411169 }
@@ -1155,7 +1183,9 @@ _Py_RemoteDebug_PagedReadRemoteMemory(proc_handle_t *handle,
11551183
11561184fallback :
11571185 // Cache full — fallback to uncached read
1158- return _Py_RemoteDebug_ReadRemoteMemory (handle , addr , size , out );
1186+ result = _Py_RemoteDebug_ReadRemoteMemory (handle , addr , size , out );
1187+ assert (result == 0 || PyErr_Occurred ());
1188+ return result ;
11591189}
11601190
11611191static int
@@ -1172,11 +1202,13 @@ _Py_RemoteDebug_ReadDebugOffsets(
11721202 handle -> pid );
11731203 }
11741204 _set_debug_exception_cause (PyExc_RuntimeError , "PyRuntime address lookup failed during debug offsets initialization" );
1205+ assert (PyErr_Occurred ());
11751206 return -1 ;
11761207 }
11771208 size_t size = sizeof (struct _Py_DebugOffsets );
11781209 if (0 != _Py_RemoteDebug_ReadRemoteMemory (handle , * runtime_start_address , size , debug_offsets )) {
11791210 _set_debug_exception_cause (PyExc_RuntimeError , "Failed to read debug offsets structure from remote process" );
1211+ assert (PyErr_Occurred ());
11801212 return -1 ;
11811213 }
11821214 return 0 ;
0 commit comments