Skip to content

Commit 46bf7d7

Browse files
committed
gh-91048: Refactor _testexternalinspection and add Windows support
Signed-off-by: Pablo Galindo <pablogsal@gmail.com>
1 parent 1007aab commit 46bf7d7

10 files changed

+493
-644
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#ifndef Py_INTERNAL_REMOTE_DEBUG_H
2+
#define Py_INTERNAL_REMOTE_DEBUG_H
3+
#ifdef __cplusplus
4+
extern "C" {
5+
#endif
6+
7+
#ifndef Py_BUILD_CORE
8+
# error "this header requires Py_BUILD_CORE define"
9+
#endif
10+
11+
#include <stdio.h>
12+
13+
#ifndef MS_WINDOWS
14+
#include <unistd.h>
15+
#endif
16+
17+
// Define a platform-independent process handle structure
18+
typedef struct {
19+
pid_t pid;
20+
#ifdef MS_WINDOWS
21+
HANDLE hProcess;
22+
#endif
23+
} proc_handle_t;
24+
25+
// Initialize a process handle
26+
PyAPI_FUNC(int) _Py_RemoteDebug_InitProcHandle(proc_handle_t *handle, pid_t pid);
27+
28+
// Cleanup a process handle
29+
PyAPI_FUNC(void) _Py_RemoteDebug_CleanupProcHandle(proc_handle_t *handle);
30+
31+
// Get the PyRuntime section address from a process
32+
PyAPI_FUNC(uintptr_t) _Py_RemoteDebug_GetPyRuntimeAddress(proc_handle_t *handle);
33+
34+
// Get the PyAsyncioDebug section address from a process
35+
PyAPI_FUNC(uintptr_t) _Py_RemoteDebug_GetAsyncioDebugAddress(proc_handle_t *handle);
36+
37+
// Read memory from a remote process
38+
PyAPI_FUNC(int) _Py_RemoteDebug_ReadRemoteMemory(proc_handle_t *handle, uintptr_t remote_address, size_t len, void* dst);
39+
40+
// Write memory to a remote process
41+
PyAPI_FUNC(int) _Py_RemoteDebug_WriteRemoteMemory(proc_handle_t *handle, uintptr_t remote_address, size_t len, const void* src);
42+
43+
// Read debug offsets from a remote process
44+
PyAPI_FUNC(int) _Py_RemoteDebug_ReadDebugOffsets(proc_handle_t *handle, uintptr_t *runtime_start_address, _Py_DebugOffsets* debug_offsets);
45+
46+
#ifdef __cplusplus
47+
}
48+
#endif
49+
#endif /* !Py_INTERNAL_DEBUG_OFFSETS_H */

Lib/test/test_external_inspection.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,13 @@ def _make_test_script(script_dir, script_basename, source):
2424
importlib.invalidate_caches()
2525
return to_return
2626

27+
skip_if_not_supported = unittest.skipIf((sys.platform != "darwin"
28+
and sys.platform != "linux"
29+
and sys.platform != "win32"),
30+
"Test only runs on Linux, Windows and MacOS")
2731
class TestGetStackTrace(unittest.TestCase):
2832

29-
@unittest.skipIf(sys.platform != "darwin" and sys.platform != "linux",
30-
"Test only runs on Linux and MacOS")
33+
@skip_if_not_supported
3134
@unittest.skipIf(sys.platform == "linux" and not PROCESS_VM_READV_SUPPORTED,
3235
"Test only runs on Linux with process_vm_readv support")
3336
def test_remote_stack_trace(self):
@@ -79,8 +82,7 @@ def foo():
7982
]
8083
self.assertEqual(stack_trace, expected_stack_trace)
8184

82-
@unittest.skipIf(sys.platform != "darwin" and sys.platform != "linux",
83-
"Test only runs on Linux and MacOS")
85+
@skip_if_not_supported
8486
@unittest.skipIf(sys.platform == "linux" and not PROCESS_VM_READV_SUPPORTED,
8587
"Test only runs on Linux with process_vm_readv support")
8688
def test_async_remote_stack_trace(self):
@@ -169,8 +171,7 @@ def new_eager_loop():
169171
]
170172
self.assertEqual(stack_trace, expected_stack_trace)
171173

172-
@unittest.skipIf(sys.platform != "darwin" and sys.platform != "linux",
173-
"Test only runs on Linux and MacOS")
174+
@skip_if_not_supported
174175
@unittest.skipIf(sys.platform == "linux" and not PROCESS_VM_READV_SUPPORTED,
175176
"Test only runs on Linux with process_vm_readv support")
176177
def test_asyncgen_remote_stack_trace(self):
@@ -227,8 +228,7 @@ async def main():
227228
]
228229
self.assertEqual(stack_trace, expected_stack_trace)
229230

230-
@unittest.skipIf(sys.platform != "darwin" and sys.platform != "linux",
231-
"Test only runs on Linux and MacOS")
231+
@skip_if_not_supported
232232
@unittest.skipIf(sys.platform == "linux" and not PROCESS_VM_READV_SUPPORTED,
233233
"Test only runs on Linux with process_vm_readv support")
234234
def test_async_gather_remote_stack_trace(self):
@@ -287,8 +287,7 @@ async def main():
287287
]
288288
self.assertEqual(stack_trace, expected_stack_trace)
289289

290-
@unittest.skipIf(sys.platform != "darwin" and sys.platform != "linux",
291-
"Test only runs on Linux and MacOS")
290+
@skip_if_not_supported
292291
@unittest.skipIf(sys.platform == "linux" and not PROCESS_VM_READV_SUPPORTED,
293292
"Test only runs on Linux with process_vm_readv support")
294293
def test_async_staggered_race_remote_stack_trace(self):
@@ -350,8 +349,7 @@ async def main():
350349
]
351350
self.assertEqual(stack_trace, expected_stack_trace)
352351

353-
@unittest.skipIf(sys.platform != "darwin" and sys.platform != "linux",
354-
"Test only runs on Linux and MacOS")
352+
@skip_if_not_supported
355353
@unittest.skipIf(sys.platform == "linux" and not PROCESS_VM_READV_SUPPORTED,
356354
"Test only runs on Linux with process_vm_readv support")
357355
def test_async_global_awaited_by(self):
@@ -470,8 +468,7 @@ async def main():
470468
p.terminate()
471469
p.wait(timeout=SHORT_TIMEOUT)
472470

473-
@unittest.skipIf(sys.platform != "darwin" and sys.platform != "linux",
474-
"Test only runs on Linux and MacOS")
471+
@skip_if_not_supported
475472
@unittest.skipIf(sys.platform == "linux" and not PROCESS_VM_READV_SUPPORTED,
476473
"Test only runs on Linux with process_vm_readv support")
477474
def test_self_trace(self):

Makefile.pre.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,6 +1290,7 @@ PYTHON_HEADERS= \
12901290
$(srcdir)/Include/internal/pycore_crossinterp.h \
12911291
$(srcdir)/Include/internal/pycore_crossinterp_data_registry.h \
12921292
$(srcdir)/Include/internal/pycore_debug_offsets.h \
1293+
$(srcdir)/Include/internal/pycore_remote_debug.h \
12931294
$(srcdir)/Include/internal/pycore_descrobject.h \
12941295
$(srcdir)/Include/internal/pycore_dict.h \
12951296
$(srcdir)/Include/internal/pycore_dict_state.h \

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy