Skip to content

Commit a9d1b19

Browse files
authored
[PROF-12372] Update process context support with version 0.0.7 of reference library (#268)
1 parent a2f46f5 commit a9d1b19

File tree

2 files changed

+61
-12
lines changed

2 files changed

+61
-12
lines changed

ddprof-lib/src/main/cpp/otel_process_ctx.cpp

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache License (Version 2.0).
2+
// This product includes software developed at Datadog (https://www.datadoghq.com/) Copyright 2025 Datadog, Inc.
3+
14
#include "otel_process_ctx.h"
25

3-
#include <limits.h>
6+
#ifndef _GNU_SOURCE
7+
#define _GNU_SOURCE
8+
#endif
9+
410
#ifdef __cplusplus
511
#include <atomic>
612
using std::atomic_thread_fence;
@@ -42,7 +48,7 @@ static const otel_process_ctx_data empty_data = {
4248
return (otel_process_ctx_result) {.success = false, .error_message = "OTEL_PROCESS_CTX_NOOP mode is enabled - no-op implementation (" __FILE__ ":" ADD_QUOTES(__LINE__) ")"};
4349
}
4450

45-
bool otel_process_ctx_drop(void) {
51+
bool otel_process_ctx_drop_current(void) {
4652
return true; // Nothing to do, this always succeeds
4753
}
4854

@@ -99,7 +105,7 @@ static otel_process_ctx_state published_state;
99105

100106
static otel_process_ctx_result otel_process_ctx_encode_payload(char **out, uint32_t *out_size, otel_process_ctx_data data);
101107

102-
// We use a mapping size of 3 pages explicitly as a hint when running on legacy kernels that don't support the
108+
// We use a mapping size of 2 pages explicitly as a hint when running on legacy kernels that don't support the
103109
// PR_SET_VMA_ANON_NAME prctl call; see below for more details.
104110
static long size_for_mapping(void) {
105111
long page_size_bytes = sysconf(_SC_PAGESIZE);
@@ -208,7 +214,7 @@ bool otel_process_ctx_drop_current(void) {
208214
// (due to the MADV_DONTFORK) and we don't need to do anything to it.
209215
if (state.mapping != NULL && state.mapping != MAP_FAILED && getpid() == state.publisher_pid) {
210216
long mapping_size = size_for_mapping();
211-
if (mapping_size == -1 || munmap(published_state.mapping, mapping_size) == -1) return false;
217+
if (mapping_size == -1 || munmap(state.mapping, mapping_size) == -1) return false;
212218
}
213219

214220
// The payload may have been inherited from a parent. This is a regular malloc so we need to free it so we don't leak.
@@ -321,15 +327,20 @@ static otel_process_ctx_result otel_process_ctx_encode_payload(char **out, uint3
321327
}
322328

323329
#ifndef OTEL_PROCESS_CTX_NO_READ
330+
#include <inttypes.h>
331+
#include <limits.h>
332+
#include <sys/uio.h>
333+
#include <sys/utsname.h>
334+
324335
// Note: The below parsing code is only for otel_process_ctx_read and is only provided for debugging
325336
// and testing purposes.
326337

327-
static bool is_otel_process_ctx_mapping(char *line) {
328-
size_t name_len = sizeof("[anon:OTEL_CTX]") - 1;
329-
size_t line_len = strlen(line);
330-
if (line_len < name_len) return false;
331-
if (line[line_len-1] == '\n') line[--line_len] = '\0';
332-
return memcmp(line + (line_len - name_len), "[anon:OTEL_CTX]", name_len) == 0;
338+
// Named mappings are supported on Linux 5.17+
339+
static bool named_mapping_supported(void) {
340+
struct utsname uts;
341+
int major, minor;
342+
if (uname(&uts) != 0 || sscanf(uts.release, "%d.%d", &major, &minor) != 2) return false;
343+
return (major > 5) || (major == 5 && minor >= 17);
333344
}
334345

335346
static void *parse_mapping_start(char *line) {
@@ -339,6 +350,41 @@ static otel_process_ctx_result otel_process_ctx_encode_payload(char **out, uint3
339350
return (void *)(uintptr_t) start;
340351
}
341352

353+
static bool is_otel_process_ctx_mapping(char *line) {
354+
size_t name_len = sizeof("[anon:OTEL_CTX]") - 1;
355+
size_t line_len = strlen(line);
356+
if (line_len < name_len) return false;
357+
if (line[line_len-1] == '\n') line[--line_len] = '\0';
358+
359+
// Validate expected permission
360+
if (strstr(line, " r--p ") == NULL) return false;
361+
362+
// Validate expected context size
363+
int64_t start, end;
364+
if (sscanf(line, "%" PRIx64 "-%" PRIx64, &start, &end) != 2) return false;
365+
if (start == 0 || end == 0 || end <= start) return false;
366+
if ((end - start) != size_for_mapping()) return false;
367+
368+
if (named_mapping_supported()) {
369+
// On Linux 5.17+, check if the line ends with [anon:OTEL_CTX]
370+
return memcmp(line + (line_len - name_len), "[anon:OTEL_CTX]", name_len) == 0;
371+
} else {
372+
// On older kernels, parse the address to to find the OTEL_CTX signature
373+
void *addr = parse_mapping_start(line);
374+
if (addr == NULL) return false;
375+
376+
// Read 8 bytes at the address using process_vm_readv (to avoid any issues with concurrency/races)
377+
char buffer[8];
378+
struct iovec local[] = {{.iov_base = buffer, .iov_len = sizeof(buffer)}};
379+
struct iovec remote[] = {{.iov_base = addr, .iov_len = sizeof(buffer)}};
380+
381+
ssize_t bytes_read = process_vm_readv(getpid(), local, 1, remote, 1, 0);
382+
if (bytes_read != sizeof(buffer)) return false;
383+
384+
return memcmp(buffer, "OTEL_CTX", sizeof(buffer)) == 0;
385+
}
386+
}
387+
342388
static otel_process_ctx_mapping *try_finding_mapping(void) {
343389
char line[8192];
344390
otel_process_ctx_mapping *result = NULL;

ddprof-lib/src/main/cpp/otel_process_ctx.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache License (Version 2.0).
2+
// This product includes software developed at Datadog (https://www.datadoghq.com/) Copyright 2025 Datadog, Inc.
3+
14
#pragma once
25

36
#define OTEL_PROCESS_CTX_VERSION_MAJOR 0
47
#define OTEL_PROCESS_CTX_VERSION_MINOR 0
5-
#define OTEL_PROCESS_CTX_VERSION_PATCH 5
6-
#define OTEL_PROCESS_CTX_VERSION_STRING "0.0.5"
8+
#define OTEL_PROCESS_CTX_VERSION_PATCH 7
9+
#define OTEL_PROCESS_CTX_VERSION_STRING "0.0.7"
710

811
#ifdef __cplusplus
912
extern "C" {

0 commit comments

Comments
 (0)