@@ -65,8 +65,12 @@ module _pdb
6565
6666#if defined(__APPLE__ ) && TARGET_OS_OSX
6767static uintptr_t
68- return_section_address (const char * section , mach_port_t proc_ref , uintptr_t base , void * map )
69- {
68+ return_section_address (
69+ const char * section ,
70+ mach_port_t proc_ref ,
71+ uintptr_t base ,
72+ void * map
73+ ) {
7074 struct mach_header_64 * hdr = (struct mach_header_64 * )map ;
7175 int ncmds = hdr -> ncmds ;
7276
@@ -76,35 +80,37 @@ return_section_address(const char* section, mach_port_t proc_ref, uintptr_t base
7680 mach_vm_size_t size = 0 ;
7781 mach_msg_type_number_t count = sizeof (vm_region_basic_info_data_64_t );
7882 mach_vm_address_t address = (mach_vm_address_t )base ;
79- vm_region_basic_info_data_64_t region_info ;
83+ vm_region_basic_info_data_64_t r_info ;
8084 mach_port_t object_name ;
8185 uintptr_t vmaddr = 0 ;
8286
8387 for (int i = 0 ; cmd_cnt < 2 && i < ncmds ; i ++ ) {
8488 if (cmd -> cmd == LC_SEGMENT_64 && strcmp (cmd -> segname , "__TEXT" ) == 0 ) {
85- vmaddr = cmd -> vmaddr ;
89+ vmaddr = cmd -> vmaddr ;
8690 }
8791 if (cmd -> cmd == LC_SEGMENT_64 && strcmp (cmd -> segname , "__DATA" ) == 0 ) {
8892 while (cmd -> filesize != size ) {
8993 address += size ;
90- if (mach_vm_region (
91- proc_ref ,
92- & address ,
93- & size ,
94- VM_REGION_BASIC_INFO_64 ,
95- (vm_region_info_t )& region_info , // cppcheck-suppress [uninitvar]
96- & count ,
97- & object_name )
98- != KERN_SUCCESS )
99- {
100- PyErr_SetString (PyExc_RuntimeError , "Cannot get any more VM maps.\n" );
94+ kern_return_t ret = mach_vm_region (
95+ proc_ref ,
96+ & address ,
97+ & size ,
98+ VM_REGION_BASIC_INFO_64 ,
99+ (vm_region_info_t )& r_info , // cppcheck-suppress [uninitvar]
100+ & count ,
101+ & object_name
102+ );
103+ if (ret != KERN_SUCCESS ) {
104+ PyErr_SetString (
105+ PyExc_RuntimeError , "Cannot get any more VM maps.\n" );
101106 return 0 ;
102107 }
103108 }
104109
105110 int nsects = cmd -> nsects ;
106- struct section_64 * sec =
107- (struct section_64 * )((void * )cmd + sizeof (struct segment_command_64 ));
111+ struct section_64 * sec = (struct section_64 * )(
112+ (void * )cmd + sizeof (struct segment_command_64 )
113+ );
108114 for (int j = 0 ; j < nsects ; j ++ ) {
109115 if (strcmp (sec [j ].sectname , section ) == 0 ) {
110116 return base + sec [j ].addr - vmaddr ;
@@ -115,6 +121,10 @@ return_section_address(const char* section, mach_port_t proc_ref, uintptr_t base
115121
116122 cmd = (struct segment_command_64 * )((void * )cmd + cmd -> cmdsize );
117123 }
124+
125+ // We should not be here, but if we are there, we should say about this
126+ PyErr_SetString (
127+ PyExc_RuntimeError , "Cannot find section address.\n" );
118128 return 0 ;
119129}
120130
@@ -204,10 +214,16 @@ search_map_for_section(pid_t pid, const char* secname, const char* substr) {
204214 VM_REGION_BASIC_INFO_64 ,
205215 (vm_region_info_t )& region_info ,
206216 & count ,
207- & object_name )
208- == KERN_SUCCESS )
217+ & object_name ) == KERN_SUCCESS )
209218 {
210- int path_len = proc_regionfilename (pid , address , map_filename , MAXPATHLEN );
219+ if ((region_info .protection & VM_PROT_READ ) == 0
220+ || (region_info .protection & VM_PROT_EXECUTE ) == 0 ) {
221+ address += size ;
222+ continue ;
223+ }
224+
225+ int path_len = proc_regionfilename (
226+ pid , address , map_filename , MAXPATHLEN );
211227 if (path_len == 0 ) {
212228 address += size ;
213229 continue ;
@@ -222,11 +238,15 @@ search_map_for_section(pid_t pid, const char* secname, const char* substr) {
222238
223239 if (!match_found && strncmp (filename , substr , strlen (substr )) == 0 ) {
224240 match_found = 1 ;
225- return search_section_in_file (secname , map_filename , address , size , proc_ref );
241+ return search_section_in_file (
242+ secname , map_filename , address , size , proc_ref );
226243 }
227244
228245 address += size ;
229246 }
247+
248+ PyErr_SetString (PyExc_RuntimeError ,
249+ "mach_vm_region failed to find the section" );
230250 return 0 ;
231251}
232252
@@ -359,6 +379,8 @@ get_py_runtime(pid_t pid)
359379{
360380 uintptr_t address = search_map_for_section (pid , "PyRuntime" , "libpython" );
361381 if (address == 0 ) {
382+ // TODO: Differentiate between not found and error
383+ PyErr_Clear ();
362384 address = search_map_for_section (pid , "PyRuntime" , "python" );
363385 }
364386 return address ;
@@ -413,6 +435,9 @@ read_memory(pid_t pid, uintptr_t remote_address, size_t len, void* dst)
413435 }
414436 total_bytes = len ;
415437#else
438+ PyErr_SetString (
439+ PyExc_RuntimeError ,
440+ "Memory reading is not supported on this platform" );
416441 return -1 ;
417442#endif
418443 return total_bytes ;
@@ -507,6 +532,12 @@ _PySysRemoteDebug_SendExec(int pid, int tid, const char *debugger_script_path)
507532 }
508533
509534 uintptr_t runtime_start_address = get_py_runtime (pid );
535+ if (runtime_start_address == 0 ) {
536+ if (!PyErr_Occurred ()) {
537+ PyErr_SetString (PyExc_RuntimeError , "Failed to get .PyRuntime address" );
538+ }
539+ return -1 ;
540+ }
510541 struct _Py_DebugOffsets local_debug_offsets ;
511542
512543 if (read_offsets (pid , & runtime_start_address , & local_debug_offsets )) {
0 commit comments