Skip to content

Commit fb313a3

Browse files
authored
[3.14] gh-158539: Fix macOS runtime section lookup for remote debugging (GH-158874) (#158906)
1 parent 2d4d26d commit fb313a3

2 files changed

Lines changed: 13 additions & 58 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix macOS runtime section lookup for remote debugging when virtual memory
2+
region sizes differ from Mach-O segment file sizes.

‎Python/remote_debug.h‎

Lines changed: 11 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,6 @@ _Py_RemoteDebug_CleanupProcHandle(proc_handle_t *handle) {
274274
static uintptr_t
275275
return_section_address64(
276276
const char* section,
277-
mach_port_t proc_ref,
278277
uintptr_t base,
279278
void* map
280279
) {
@@ -284,37 +283,15 @@ return_section_address64(
284283
int cmd_cnt = 0;
285284
struct segment_command_64* cmd = map + sizeof(struct mach_header_64);
286285

287-
mach_vm_size_t size = 0;
288-
mach_msg_type_number_t count = sizeof(vm_region_basic_info_data_64_t);
289-
mach_vm_address_t address = (mach_vm_address_t)base;
290-
vm_region_basic_info_data_64_t r_info;
291-
mach_port_t object_name;
292286
uintptr_t vmaddr = 0;
293287

294288
for (int i = 0; cmd_cnt < 2 && i < ncmds; i++) {
295289
if (cmd->cmd == LC_SEGMENT_64 && strcmp(cmd->segname, "__TEXT") == 0) {
296290
vmaddr = cmd->vmaddr;
297291
}
298292
if (cmd->cmd == LC_SEGMENT_64 && strcmp(cmd->segname, "__DATA") == 0) {
299-
while (cmd->filesize != size) {
300-
address += size;
301-
kern_return_t ret = mach_vm_region(
302-
proc_ref,
303-
&address,
304-
&size,
305-
VM_REGION_BASIC_INFO_64,
306-
(vm_region_info_t)&r_info, // cppcheck-suppress [uninitvar]
307-
&count,
308-
&object_name
309-
);
310-
if (ret != KERN_SUCCESS) {
311-
PyErr_Format(PyExc_RuntimeError,
312-
"mach_vm_region failed while parsing 64-bit Mach-O binary "
313-
"at base address 0x%lx (kern_return_t: %d)",
314-
base, ret);
315-
return 0;
316-
}
317-
}
293+
// The section address only needs the image's ASLR slide.
294+
// VM regions need not match the segment's on-disk size.
318295

319296
int nsects = cmd->nsects;
320297
struct section_64* sec = (struct section_64*)(
@@ -337,7 +314,6 @@ return_section_address64(
337314
static uintptr_t
338315
return_section_address32(
339316
const char* section,
340-
mach_port_t proc_ref,
341317
uintptr_t base,
342318
void* map
343319
) {
@@ -347,37 +323,15 @@ return_section_address32(
347323
int cmd_cnt = 0;
348324
struct segment_command* cmd = map + sizeof(struct mach_header);
349325

350-
mach_vm_size_t size = 0;
351-
mach_msg_type_number_t count = sizeof(vm_region_basic_info_data_t);
352-
mach_vm_address_t address = (mach_vm_address_t)base;
353-
vm_region_basic_info_data_t r_info;
354-
mach_port_t object_name;
355326
uintptr_t vmaddr = 0;
356327

357328
for (int i = 0; cmd_cnt < 2 && i < ncmds; i++) {
358329
if (cmd->cmd == LC_SEGMENT && strcmp(cmd->segname, "__TEXT") == 0) {
359330
vmaddr = cmd->vmaddr;
360331
}
361332
if (cmd->cmd == LC_SEGMENT && strcmp(cmd->segname, "__DATA") == 0) {
362-
while (cmd->filesize != size) {
363-
address += size;
364-
kern_return_t ret = mach_vm_region(
365-
proc_ref,
366-
&address,
367-
&size,
368-
VM_REGION_BASIC_INFO,
369-
(vm_region_info_t)&r_info, // cppcheck-suppress [uninitvar]
370-
&count,
371-
&object_name
372-
);
373-
if (ret != KERN_SUCCESS) {
374-
PyErr_Format(PyExc_RuntimeError,
375-
"mach_vm_region failed while parsing 32-bit Mach-O binary "
376-
"at base address 0x%lx (kern_return_t: %d)",
377-
base, ret);
378-
return 0;
379-
}
380-
}
333+
// The section address only needs the image's ASLR slide.
334+
// VM regions need not match the segment's on-disk size.
381335

382336
int nsects = cmd->nsects;
383337
struct section* sec = (struct section*)(
@@ -400,7 +354,6 @@ return_section_address32(
400354
static uintptr_t
401355
return_section_address_fat(
402356
const char* section,
403-
mach_port_t proc_ref,
404357
uintptr_t base,
405358
void* map
406359
) {
@@ -450,11 +403,11 @@ return_section_address_fat(
450403
switch (hdr->magic) {
451404
case MH_MAGIC:
452405
case MH_CIGAM:
453-
return return_section_address32(section, proc_ref, base, (void*)hdr);
406+
return return_section_address32(section, base, (void*)hdr);
454407

455408
case MH_MAGIC_64:
456409
case MH_CIGAM_64:
457-
return return_section_address64(section, proc_ref, base, (void*)hdr);
410+
return return_section_address64(section, base, (void*)hdr);
458411

459412
default:
460413
PyErr_Format(PyExc_RuntimeError,
@@ -473,7 +426,7 @@ return_section_address_fat(
473426
}
474427

475428
static uintptr_t
476-
search_section_in_file(const char* secname, char* path, uintptr_t base, mach_vm_size_t size, mach_port_t proc_ref)
429+
search_section_in_file(const char* secname, char* path, uintptr_t base)
477430
{
478431
int fd = open(path, O_RDONLY);
479432
if (fd == -1) {
@@ -510,15 +463,15 @@ search_section_in_file(const char* secname, char* path, uintptr_t base, mach_vm_
510463
switch (magic) {
511464
case MH_MAGIC:
512465
case MH_CIGAM:
513-
result = return_section_address32(secname, proc_ref, base, map);
466+
result = return_section_address32(secname, base, map);
514467
break;
515468
case MH_MAGIC_64:
516469
case MH_CIGAM_64:
517-
result = return_section_address64(secname, proc_ref, base, map);
470+
result = return_section_address64(secname, base, map);
518471
break;
519472
case FAT_MAGIC:
520473
case FAT_CIGAM:
521-
result = return_section_address_fat(secname, proc_ref, base, map);
474+
result = return_section_address_fat(secname, base, map);
522475
break;
523476
default:
524477
PyErr_Format(PyExc_RuntimeError,
@@ -621,7 +574,7 @@ search_map_for_section(proc_handle_t *handle, const char* secname, const char* s
621574
if (strncmp(filename, substr, strlen(substr)) == 0) {
622575
PyErr_Clear();
623576
uintptr_t result = search_section_in_file(
624-
secname, map_filename, address, size, proc_ref);
577+
secname, map_filename, address);
625578
if (result != 0) {
626579
if (validator == NULL || validator(handle, result)) {
627580
return result;

0 commit comments

Comments
 (0)