| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Based on async-profiler 2.8.3
This is not a fork of async-profiler. This is a work derived from async-profiler but tailored very specifically for Datadog needs. See gritty details for more info. If you need a full-fledged Java profiler head back to async-profiler
git clone https://github.com/DataDog/java-profiler.git
cd java-profiler./gradlew buildReleaseThe resulting artifact will be in ddprof-lib/build/libs/ddprof-<version>.jar
Since the upstream code might not be 100% compatible with the current version of the project, we extend the base classes with Datadog-specific functionality. These extensions are integrated directly into the base files (e.g., stackWalker.h) with optional parameters and backward-compatible interfaces.
See ddprof-lib/src/main/cpp/stackWalker.h for an example of how we extend the upstream code with additional features like truncation detection.
This project includes Claude Code commands for streamlined development workflows when using Claude Code:
Automated build execution with intelligent log analysis:
# Build with automated analysis
/build-and-summarize buildRelease
# Run tests with summary
/build-and-summarize testDebug
# Custom gradle tasks
/build-and-summarize clean buildDebug testDebugFeatures:
Upstream/local file comparison and patch analysis:
# Analyze differences between upstream and local versions
/compare-and-patch stackFrame.h
/compare-and-patch symbols.cpp
/compare-and-patch buffers.hFeatures:
These commands complement the existing patching workflow by providing:
The generated reports integrate seamlessly with the existing gradle/patching.gradle configuration system, making it easier to maintain and update patches as the upstream codebase evolves.
The project includes both Java and C++ unit tests. You can run them using:
# Run all tests
./gradlew test
# Run specific test configurations
./gradlew testRelease # Run release build tests
./gradlew testDebug # Run debug build tests
./gradlew testAsan # Run tests with ASan
./gradlew testTsan # Run tests with TSan
# Run C++ unit tests only
./gradlew gtestDebug # Run C++ tests in debug mode
./gradlew gtestRelease # Run C++ tests in release modeJAVA_TEST_HOME=<path to test JDK> ./gradlew testDebug
Run tests in containers to test on different libc implementations. The script defaults to Podman; use --container=docker to use Docker instead. Uses two-level container image caching for fast subsequent runs:
By default, the script clones the repository at the current commit for clean builds. Use --mount to mount the local directory instead (faster but may have stale artifacts).
# Run specific test on musl (Alpine) with JDK 21 (clone mode - clean build)
./utils/run-containers-tests.sh --libc=musl --jdk=21 --tests="CTimerGCStressTest"
# Run all tests on glibc (Ubuntu) with JDK 17
./utils/run-containers-tests.sh --libc=glibc --jdk=17
# Run tests on aarch64 architecture (requires container runtime with multi-arch support)
./utils/run-containers-tests.sh --libc=musl --jdk=21 --arch=aarch64
# Mount local repo for faster iteration (may have stale artifacts)
./utils/run-containers-tests.sh --libc=musl --jdk=21 --mount --tests="MyTest"
# Drop to interactive shell in musl container
./utils/run-containers-tests.sh --libc=musl --jdk=21 --shell
# Run one C++ gtest binary only
./utils/run-containers-tests.sh --libc=glibc --config=asan --gtest-task=elfparser_ut
# Use Docker instead of the default Podman runtime
./utils/run-containers-tests.sh --container=docker --libc=glibc --jdk=21
# Force rebuild of all cached container images
./utils/run-containers-tests.sh --libc=musl --jdk=21 --rebuild
# Force rebuild of base image only (useful after Alpine/Ubuntu updates)
./utils/run-containers-tests.sh --libc=musl --rebuild-base
# Preview all supported musl cells (sanitizer configs are skipped, matching CI policy)
./utils/run-containers-tests.sh --matrix --libc=musl
# Run all supported musl cells without an interactive prompt
./utils/run-containers-tests.sh --matrix --libc=musl --run
# Preview selected JDKs across every supported libc/architecture pair
./utils/run-containers-tests.sh --libc=all --jdk=8,17,21 --arch=all
# Run all OpenJ9 cells
./utils/run-containers-tests.sh --matrix --jdk=j9 --run
# Show options
./utils/run-containers-tests.sh --helpSupported options:
Single-value commands run one configuration immediately. When any dimension expands to multiple cells, the script prints a compact status table first; interactive terminals ask for confirmation, while non-interactive runs require --run to execute. Matrix execution prints the status table again after all cells finish and writes summaries to build/reports/container-matrix/summary.md and build/reports/container-matrix/summary.json. Cells not run because of --fail-fast are reported as cancelled separately from unsupported cells that are skipped.
The project includes a comprehensive unwinding validation tool that tests JIT compilation unwinding scenarios to detect stack frame issues. This tool validates the profiler's ability to correctly unwind stack frames during complex JIT compilation scenarios.
# Run all unwinding validation scenarios (release or debug build required)
./gradlew :ddprof-test:runUnwindingValidator
# Run specific scenario
./gradlew :ddprof-test:runUnwindingValidator -PvalidatorArgs="--scenario=C2CompilationTriggers"
# Generate markdown report for CI
./gradlew :ddprof-test:unwindingReport
# Show available options
./gradlew :ddprof-test:runUnwindingValidator -PvalidatorArgs="--help"The validator includes 13 specialized scenarios targeting different unwinding challenges:
The validator supports multiple output formats:
# Text output (default)
./gradlew :ddprof-test:runUnwindingValidator
# JSON format for programmatic analysis
./gradlew :ddprof-test:runUnwindingValidator -PvalidatorArgs="--output-format=json --output-file=unwinding-report.json"
# Markdown format for documentation
./gradlew :ddprof-test:runUnwindingValidator -PvalidatorArgs="--output-format=markdown --output-file=unwinding-report.md"The unwinding validator is automatically integrated into GitHub Actions CI pipeline:
The validator provides immediate visibility into unwinding quality across all supported platforms and Java versions without requiring artifact downloads.
The tool analyzes JFR (Java Flight Recorder) data to measure:
Results are categorized as:
The profiler version is computed at build time from git tags — no version is stored in any file. The single source of truth is utils/compute-version.sh, which derives the version from the most recent reachable v_X.Y.Z tag.
| Branch | Most recent tag | Computed version |
|---|---|---|
| main | v_X.Y.Z | X.(Y+1).0-SNAPSHOT |
| release/X.Y._ | v_X.Y.Z | X.Y.(Z+1)-SNAPSHOT |
| Feature branch | (same as base) | snapshot + -<branch>-SNAPSHOT |
| Tag commit | v_X.Y.Z | X.Y.Z (release) |
On release/X.Y._ branches, only tags matching v_X.Y.* are considered, so a merged mainline tag can't produce a wrong-series version.
Gradle computes the version at configuration time via providers.exec. CI environments that pass -Pddprof_version skip the computation entirely. If no tags are available (e.g. CodeQL's shallow autobuild), the build falls back to 0.0.0-SNAPSHOT with a visible warning — this never affects publish builds, which always set -Pddprof_version.
Releases create only an annotated tag (and a release branch for minor/major). No file modifications, no bump PRs. See utils/README.md for the release workflow.
Release builds automatically generate split debug information to optimize deployment size while preserving debugging capabilities:
ddprof-lib/build/
├── lib/main/release/linux/x64/
│ ├── libjavaProfiler.so # Original library with debug symbols
│ ├── stripped/
│ │ └── libjavaProfiler.so # Stripped library (83% smaller)
│ └── debug/
│ └── libjavaProfiler.so.debug # Debug symbols only
├── native/release/
│ └── META-INF/native-libs/linux-x64/
│ └── libjavaProfiler.so # Final stripped library (deployed)
└── native/release-debug/
└── META-INF/native-libs/linux-x64/
└── libjavaProfiler.so.debug # Debug symbols package
The build system automatically detects the best available C++ compiler (prefers clang++, falls back to g++).
# Auto-detection (default)
./gradlew build
# Force specific compiler
./gradlew build -Pnative.forceCompiler=clang++
./gradlew build -Pnative.forceCompiler=g++
./gradlew build -Pnative.forceCompiler=/usr/bin/g++-13
# Test with specific compiler
./gradlew testDebug -Pnative.forceCompiler=g++This is useful for:
The project uses several tools for code quality:
Run code quality checks:
# Run scan-build (this will use the scan-build binary)
./gradlew scanBuild
# Run cppcheck (if configured)
./gradlew cppcheck
# Run spotless (including code formatting)
./gradlew spotlessApply!TODO!
The project includes JMH-based stress tests:
# Run all stress tests
./gradlew :ddprof-stresstest:runStressTests
### Common Issues
1. If you encounter strange crashes Asan:
```bash
sudo sysctl vm.mmap_rnd_bits=28This section documents important architectural decisions and enhancements made to the profiler core.
Introduced race-free critical section management using atomic compare-and-swap operations instead of expensive signal blocking syscalls:
Key files: criticalSection.h, criticalSection.cpp
Enhanced the call trace storage system from double-buffered to triple-buffered architecture with hazard pointer-based memory reclamation:
Key changes:
Key files: callTraceStorage.h, callTraceStorage.cpp, callTraceHashTable.h, callTraceHashTable.cpp
Comprehensive testing improvements for better debugging and stress testing:
Key files: gtest_crash_handler.h, stress_callTraceStorage.cpp
Improved thread-local storage initialization to prevent race conditions:
These architectural improvements focus on eliminating race conditions, improving performance in high-throughput scenarios, and providing better debugging capabilities for the native profiling engine.
Added support for remote symbolication to enable offloading symbol resolution from the agent to backend services:
Benefits:
Key files: elfBuildId.h, elfBuildId.cpp, profiler.cpp, flightRecorder.cpp
For detailed documentation, see doc/RemoteSymbolication.md.
The utils/ directory contains helper scripts for common workflows. See utils/README.md for full documentation.
| Script | Description |
|---|---|
| release.sh | Trigger a validated release (major/minor/patch) via GitHub Actions |
| prepare-patch.sh | Backport a batch of pending main PRs onto a release branch before a patch release |
| backport-pr.sh | Cherry-pick a merged PR onto a release branch and open a backport PR |
| patch-dd-java-agent.sh | Patch dd-java-agent.jar with a local ddprof build for quick testing |
| run-containers-tests.sh | Run tests in containers (musl/glibc, multiple JDKs) |
| check_upstream_changes.sh | Check for upstream async-profiler changes locally |
| track_upstream_changes.sh | Track upstream changes and generate reports |
| generate_tracked_files.sh | Generate the list of files tracked from upstream |
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Download the latest version of dd-trace-java and add -Ddd.profiling.ddprof.debug.lib. Example of a command line:
DD_SERVICE=your-service DD_TRACE_DEBUG=true java -javaagent:./temp/dd-java-agent.jar -Ddd.profiling.enabled=true -Ddd.profiling.ddprof.enabled=true -Ddd.profiling.ddprof.liveheap.enabled=true -Ddd.profiling.upload.period=10 -Ddd.profiling.start-force-first=true -Ddd.profiling.ddprof.debug.lib=~/dd/java-profiler/ddprof-lib/build/lib/main/debug/linux/x64/libjavaProfiler.so -XX:ErrorFile=${PWD}/hs_err_pid%p.log -XX:OnError='java -jar temp/dd-java-agent.jar uploadCrash hs_err_pid%p.log' -jar ./temp/renaissance-gpl-0.15.0.jar akka-uct -r 5For dd-trace-java you just need to set the ddprof.jar project property. Eg. you can run the gradle build like this - ./gradlew clean -Pddprof.jar=file://<path-to-artifact.jar> :dd-java-agent:shadowJar- which will result in a customdd-java-agent.jar` build containing your test version of Java profiler.
| Back | FazBrowse Home | New Git URL |