Skip to content

Commit c49f01f

Browse files
committed
RUM-16442: Fix profiler safe memory reads
1 parent 2df6422 commit c49f01f

3 files changed

Lines changed: 691 additions & 170 deletions

File tree

DatadogProfiling/Mach/include/safe_read_testing.h

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,56 @@
77
#ifndef DD_PROFILER_SAFE_READ_TESTING_H_
88
#define DD_PROFILER_SAFE_READ_TESTING_H_
99

10-
#include <stdbool.h>
1110
#include <stddef.h>
11+
#include <stdint.h>
1212

1313
#ifdef __APPLE__
1414
#include <TargetConditionals.h>
1515
#if !TARGET_OS_WATCH
1616

17+
#include "dd_profiler.h" // stack_trace_t
18+
1719
#ifdef __cplusplus
1820
extern "C" {
1921
#endif
2022

2123
/**
22-
* Helper to manually re-install handlers if needed by tests.
24+
* Reads a contiguous region of the calling task's virtual memory starting at sp
25+
* into buf (which must be at least buf_size bytes).
26+
*
27+
* Mirrors the production read_stack_region used inside stack_trace_sample_thread.
28+
* Returns the number of contiguous bytes actually read from sp; returns 0 if sp
29+
* itself is unmapped or invalid.
2330
*/
24-
void init_safe_read_handlers_for_testing(void);
31+
size_t read_stack_region_for_testing(void* sp, void* buf, size_t buf_size);
2532

2633
/**
27-
* Validates the Safe Read mechanism.
34+
* Walks a frame pointer chain entirely from a pre-populated local buffer.
35+
*
36+
* This is the same walk used inside stack_trace_sample_thread, extracted so tests
37+
* can exercise the bounds-check guards and cycle-termination behavior directly
38+
* without needing to suspend a real thread or craft live stack memory.
39+
*
40+
* @param trace Pre-allocated trace; trace->frames must point to at least
41+
* max_depth entries. frame_count is reset to 0 on entry.
42+
* @param initial_fp First frame pointer to walk from (typically the suspended
43+
* thread's FP register).
44+
* @param initial_pc First program counter to record (typically the suspended
45+
* thread's PC register).
46+
* @param stack_base Base address that stack_buf was read from (typically SP).
47+
* @param stack_buf Buffer containing a snapshot of stack memory.
48+
* @param bytes_read Valid bytes in stack_buf.
49+
* @param max_depth Hard cap on frames to record.
2850
*/
29-
bool safe_read_memory_for_testing(void* addr, void* buffer, size_t size);
51+
void walk_frames_in_buffer(
52+
stack_trace_t* trace,
53+
void* initial_fp,
54+
void* initial_pc,
55+
uintptr_t stack_base,
56+
const uint8_t* stack_buf,
57+
size_t bytes_read,
58+
uint32_t max_depth
59+
);
3060

3161
#ifdef __cplusplus
3262
}

0 commit comments

Comments
 (0)