8000 gh-129223: Do not allow the compiler to optimise away symbols for debug sections by pablogsal · Pull Request #129225 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-129223: Do not allow the compiler to optimise away symbols for debug sections #129225

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions Include/internal/pycore_debug_offsets.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,32 @@ extern "C" {

// Macros to burn global values in custom sections so out-of-process
// profilers can locate them easily.

#define GENERATE_DEBUG_SECTION(name, declaration) \
_GENERATE_DEBUG_SECTION_WINDOWS(name) \
_GENERATE_DEBUG_SECTION_APPLE(name) \
declaration \
_GENERATE_DEBUG_SECTION_LINUX(name)
#define GENERATE_DEBUG_SECTION(name, declaration) \
_GENERATE_DEBUG_SECTION_WINDOWS(name) \
_GENERATE_DEBUG_SECTION_APPLE(name) \
declaration \
_GENERATE_DEBUG_SECTION_LINUX(name)

#if defined(MS_WINDOWS)
#define _GENERATE_DEBUG_SECTION_WINDOWS(name) \
_Pragma(Py_STRINGIFY(section(Py_STRINGIFY(name), read, write))) \
__declspec(allocate(Py_STRINGIFY(name)))
_Pragma(Py_STRINGIFY(section(Py_STRINGIFY(name), read, write))) \
__declspec(allocate(Py_STRINGIFY(name)))
#else
#define _GENERATE_DEBUG_SECTION_WINDOWS(name)
#endif

#if defined(__APPLE__)
#define _GENERATE_DEBUG_SECTION_APPLE(name) \
__attribute__((section(SEG_DATA "," Py_STRINGIFY(name))))
__attribute__((section(SEG_DATA "," Py_STRINGIFY(name)))) \
__attribute__((used))
#else
#define _GENERATE_DEBUG_SECTION_APPLE(name)
#endif

#if defined(__linux__) && (defined(__GNUC__) || defined(__clang__))
#define _GENERATE_DEBUG_SECTION_LINUX(name) \
__attribute__((section("." Py_STRINGIFY(name))))
__attribute__((section("." Py_STRINGIFY(name)))) \
__attribute__((used))
#else
#define _GENERATE_DEBUG_SECTION_LINUX(name)
#endif
Expand Down
37 changes: 24 additions & 13 deletions Modules/_testexternalinspection.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,11 @@ get_py_runtime(pid_t pid)
static uintptr_t
get_async_debug(pid_t pid)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is to avoid returning NULL without an error set as things under search_map_for_section may return without setting an error.

{
return search_map_for_section(pid, "AsyncioDebug", "_asyncio.cpython");
uintptr_t result = search_map_for_section(pid, "AsyncioDebug", "_asyncio.cpython");
if (result == 0 && !PyErr_Occurred()) {
PyErr_SetString(PyExc_RuntimeError, "Cannot find AsyncioDebug section");
}
return result;
}


Expand Down Expand Up @@ -560,6 +564,16 @@ read_int(pid_t pid, uintptr_t address, int *result)
return 0;
}

static int
read_unsigned_long(pid_t pid, uintptr_t address, unsigned long *result)
{
int bytes_read = read_memory(pid, address, sizeof(unsigned long), result);
if (bytes_read < 0) {
return -1;
}
return 0;
}

static int
read_pyobj(pid_t pid, uintptr_t address, PyObject *ptr_addr)
{
Expand Down Expand Up @@ -627,7 +641,7 @@ read_py_long(pid_t pid, _Py_DebugOffsets* offsets, uintptr_t address)
return 0;
}

char *digits = (char *)PyMem_RawMalloc(size * sizeof(digit));
digit *digits = (digit *)PyMem_RawMalloc(size * sizeof(digit));
if (!digits) {
PyErr_NoMemory();
return -1;
Expand All @@ -645,16 +659,13 @@ read_py_long(pid_t pid, _Py_DebugOffsets* offsets, uintptr_t address)

long value = 0;

// In theory this can overflow, but because of llvm/llvm-project#16778
// we can't use __builtin_mul_overflow because it fails to link with
// __muloti4 on aarch64. In practice this is fine because all we're
// testing here are task numbers that would fit in a single byte.
for (ssize_t i = 0; i < size; ++i) {
long long factor;
if (__builtin_mul_overflow(digits[i], (1UL << (ssize_t)(shift * i)),
&factor)
) {
goto error;
}
if (__builtin_add_overflow(value, factor, &value)) {
goto error;
}
long long factor = digits[i] * (1UL << (ssize_t)(shift * i));
value += factor;
}
PyMem_RawFree(digits);
if (negative) {
Expand Down Expand Up @@ -693,8 +704,8 @@ parse_task_name(
return NULL;
}

int flags;
err = read_int(
unsigned long flags;
err = read_unsigned_long(
pid,
(uintptr_t)task_name_obj.ob_type + offsets->type_object.tp_flags,
&flags);
Expand Down
Loading
0