Skip to content

Commit af84100

Browse files
committed
Some fixes
1 parent 9b86022 commit af84100

File tree

2 files changed

+53
-22
lines changed

2 files changed

+53
-22
lines changed

Lib/test/test_sys.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2096,7 +2096,7 @@ def test_remote_exec_disabled_by_xoption(self):
20962096
def test_remote_exec_invalid_pid(self):
20972097
"""Test remote exec with invalid process ID"""
20982098
with self.assertRaises(OSError):
2099-
sys.remote_exec(999999, "print('should not run')")
2099+
sys.remote_exec(99999, "print('should not run')")
21002100

21012101
def test_remote_exec_syntax_error(self):
21022102
"""Test remote exec with syntax error in script"""

Python/remote_debugging.c

Lines changed: 52 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,12 @@ module _pdb
6565

6666
#if defined(__APPLE__) && TARGET_OS_OSX
6767
static 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

Comments
 (0)