Nikita.tkachenko/runtime code coverage by nikita-tkachenko-datadog · Pull Request #10951 · DataDog/dd-trace-java
added 3 commits
March 23, 2026 14:47Implement Coverage Binary Protocol v1 (CoverageBinaryEncoder) using two bit vectors per record for executable and covered lines. Switch from LCOV text format to the new "ddcov" binary format for coverage uploads. Add className to ClassProbeMapping, key coverage data by CoverageKey (sourceFile + className), and include language/env tags in upload metadata. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
`new int[probeCount][]` creates an array of null references. When the collector iterates `probeToLines[p]`, it NPEs on classes that have probes but no executable lines (no debug info, interfaces). Initialize each entry to `new int[0]` instead. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Skip classes without a SourceFile attribute in the collector to prevent NPE in the binary encoder (null is not a valid string in the coverage binary protocol) - Log instrumentation failures at debug level so they are visible when troubleshooting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ClassProbeMappingBuilder previously ran JaCoCo's Analyzer N+1 times per class (once per probe + once for executable lines). For a class with 200 probes, that meant 201 full ASM parses of the same bytecode. The new implementation parses the class once using ClassProbesAdapter, builds a simplified instruction graph (ProbeNode with predecessor links), and walks predecessor chains to determine which lines each probe covers. ~200x faster for large classes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… scan On cache miss, try ClassLoader.getResourceAsStream() first (O(1) per class) before scanning all classpath jars/directories. Uses the system classloader (application classpath) first, then context classloader. CRC64 is verified after reading to ensure bytes match what was instrumented. Falls back to full classpath scan for any classes the classloader can't resolve. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace custom ScheduledExecutorService with a dedicated AgentTaskScheduler(CODE_COVERAGE) instance, following the same pattern as Profiler, Debugger, Remote Config, and Tracer Flare. This gives us proper daemon thread in the dd-trace-java thread group, null context classloader, uncaught exception handler, and shutdown hook handling for free. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters