Skip to content

[Bug]: datadog-profiling 1.19.x/1.20.0 aborts FrankenPHP with "Out of memory" when opcache.preload is set #3896

@Gaitholabi

Description

@Gaitholabi

Bug report

With dd-trace 1.19.01.20.0 installed via datadog-setup.php --enable-profiling, FrankenPHP exits within ~1s of startup with a bare Out of memory on stdout whenever opcache.preload is configured — even when the preload file is just <?php. The crash happens during PHP module init, before any request is served. With DD_PROFILING_LOG_LEVEL=trace, the last log line is always a datadog_php_profiling::timeline "Compile file" event for the preload. Pinning back to 1.18.0 makes the same image boot cleanly.

Environment

  • Base image: dunglas/frankenphp:1.12.3-php8.5.6-bookworm
  • Install: datadog-setup.php --php-bin=all --enable-profiling
  • Trigger: opcache.preload=<any .php file> + DD_PROFILING_LOG_LEVEL=trace

This is also reproducible in our Symfony app without setting any debugging DD_x vars.

Underlying error

An earlier capture printed the Rust allocator panic before the terse Out of memory:

memory allocation of 7218835291860648052 bytes failed

≈ 6.5 EB — a corrupted/uninitialised size inside the profiler's timeline allocator.

Sample reproducer:

# Reproducer for dd-trace 1.19.x/1.20.0 "Out of memory" on FrankenPHP.
# Build: docker build --build-arg DD_VERSION=1.20.0 -t ddoom .
# Run:   docker run --rm -e DD_TRACE_DEBUG=1 -e DD_PROFILING_LOG_LEVEL=trace ddoom

ARG DD_VERSION=1.20.0
FROM dunglas/frankenphp:1.12.3-php8.5.6-bookworm
ARG DD_VERSION
USER root

RUN install-php-extensions opcache \
 && curl -fsSL "https://github.com/DataDog/dd-trace-php/releases/download/${DD_VERSION}/datadog-setup.php" \
      | php -- --php-bin=all --enable-profiling

RUN mkdir -p /app/public \
 && echo '<?php phpinfo();' > /app/public/index.php \
 && echo '<?php' > /app/preload.php \
 && printf '%s\n' \
      "opcache.enable=1" "opcache.enable_cli=1" \
      "opcache.preload=/app/preload.php" "opcache.preload_user=www-data" \
    > /usr/local/etc/php/conf.d/zzz-app.ini \
 && chown -R www-data:www-data /app /data/caddy /config/caddy

USER www-data
WORKDIR /app
ENV APP_ENV=prod
#!/usr/bin/env bash
# Builds the Dockerfile for dd-trace 1.18.0 and 1.20.0, runs each container
# with profiling debug envs, and reports whether it crashed.
# Containers are left around for inspection: `docker logs <name>`,
# `docker inspect <name>`, etc. Remove them with `docker rm -f <name>`.

set -euo pipefail
cd "$(dirname "$0")"

check() {
    local v="$1" name="ddoom-${1//./-}"
    echo "── dd-trace $v ──"

    echo "→ building image"
    local img; img=$(docker build -q --build-arg "DD_VERSION=$v" .)

    echo "→ starting container $name with DD_TRACE_DEBUG=1, DD_PROFILING_LOG_LEVEL=trace"
    docker rm -f "$name" >/dev/null 2>&1 || true
    docker run -d --name "$name" \
        -e DD_TRACE_DEBUG=1 -e DD_PROFILING_LOG_LEVEL=trace \
        "$img" >/dev/null

    echo "→ waiting 5s, then inspecting"
    sleep 5
    local st ec
    st=$(docker inspect "$name" --format '{{.State.Status}}')
    ec=$(docker inspect "$name" --format '{{.State.ExitCode}}')
    echo "  status=$st exit=$ec"

    if docker logs "$name" 2>&1 | grep -q "^Out of memory"; then
        echo "  ✗ crashed: \"Out of memory\" in stdout"
        echo "  last profiler trace:"
        docker logs "$name" 2>&1 | grep datadog_php_profiling | tail -1 | sed 's/^/    /'
    else
        echo "  ✓ no \"Out of memory\" in stdout"
    fi
    echo "  inspect with: docker logs $name | tail -20"
    echo
}

check 1.18.0
check 1.20.0

PHP version

8.5.6

Tracer or profiler version

1.20.0

Installed extensions

No response

Output of phpinfo()

No response

Upgrading from

No response

Metadata

Metadata

Labels

🐛 bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions