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

Signed-off-by: Pablo Galindo <pablogsal@gmail.com>
Co-authored-by: Łukasz Langa <lukasz@langa.pl>
This commit is contained in:
Pablo Galindo Salgado 2025-01-24 20:36:32 +00:00 committed by GitHub
parent e635bf2e49
commit 3a3a6b86f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 35 additions and 23 deletions

View file

@ -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

View file

@ -414,7 +414,11 @@ get_py_runtime(pid_t pid)
static uintptr_t
get_async_debug(pid_t pid)
{
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;
}
@ -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)
{
@ -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;
@ -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) {
@ -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);