perf-map parser silently rejects all entries when addresses are 0x-prefixed (JDK 25 `jcmd Compiler.perfmap` format) — all JIT frames become `Anonymous`
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 84/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Domain
- observability-sre, performance
Research direction
Start in src/runtime_symbol_lookup.cc at the sscanf parsing and insert_or_replace() validity check, then reproduce with a JDK 25 perf map containing 0x-prefixed address and size fields. Update the parsing so both prefixed and bare-hex formats are accepted, and confirm the entries are retained and JIT frames no longer render as Anonymous.
Written by the indexing model from the issue text.
Description
Summary
ddprof fails to symbolicate any JIT frames from a /tmp/perf-<pid>.map file whose
address/size fields are 0x-prefixed — the format jcmd <pid> Compiler.perfmap emits
on OpenJDK 25. Every line of the map is rejected at parse time, the runtime symbol map
stays empty, and all JIT-compiled Java frames render as Anonymous in profiles. The
failure is silent above debug log level.
Environment
- ddprof v0.26.0 (the parser is unchanged on current
main) - OpenJDK 25 (
java-25-openjdk), Linux container - ddprof in wrapper mode (
ddprof --preset alloc_live_heap ... /usr/bin/java ...),
JVM running with-XX:+PreserveFramePointer - Perf map regenerated every 300s via
jcmd <pid> Compiler.perfmap
Reproduction
-
Run a JVM under ddprof wrapper mode with any preset.
-
Generate the map with
jcmd <pid> Compiler.perfmap. On JDK 25 the file contains
(captured from our production pod):0x00007f6cc9200100 0x0000000000000368 java.lang.Object jdk.internal.misc.Unsafe.getReferenceVolatile(java.lang.Object, long) 0x00007f6cc9200580 0x0000000000000178 int jdk.internal.misc.Unsafe.getInt(java.lang.Object, long) -
Observe profiles: JIT regions never resolve; all such frames show as
Anonymous.
Rewriting the same file to bare hex (7f6cc9200100 368 <symbol>) makes
symbolication work immediately.
Root cause
In src/runtime_symbol_lookup.cc, each line is parsed with:
sscanf(line, "%16s %8s %300[^\t\n]", address_buff, size_buff, buffer)
A 0x-prefixed 64-bit address token is 18 characters (0x + 16 hex digits):
%16struncates the address to0x00007f6cc92001(corrupting it), and%8sthen consumes the leftover00of the address token as the size field,
so the real size is never read andcode_sizeparses to0.
The subsequent validity check in insert_or_replace() (!address || !code_size)
rejects the entry. This happens for every line, so the map is 100% discarded.
Because a failed lookup only logs at debug, nothing surfaces at default/warn levels —
we confirmed 72h of profiles with zero resolved Java JIT frames before finding this.
Suggested fix
Widen the field buffers (e.g. %18s) and parse both fields with
strtoul(str, NULL, 16), which accepts the 0x prefix natively; the same code path
then handles both the classic bare-hex format and the JDK 25 output.
A warn-level log when a large fraction of perf-map lines is rejected would also make
this failure mode diagnosable.
Workaround
Post-process the JDK dump before ddprof reads it, publishing atomically:
jcmd "$pid" Compiler.perfmap "/tmp/perf-$pid.map.jvm" &&
gawk '{ a = strtonum($1 ~ /^0x/ ? $1 : "0x" $1);
s = strtonum($2 ~ /^0x/ ? $2 : "0x" $2);
$1 = ""; $2 = ""; sub(/^ */, "");
printf "%x %x %s\n", a, s, $0 }' "/tmp/perf-$pid.map.jvm" \
> "/tmp/perf-$pid.map.tmp" &&
mv "/tmp/perf-$pid.map.tmp" "/tmp/perf-$pid.map"
- Dominant language
- C++
- Stars
- 62
- Forks
- 15
- PR merge metrics
- No merged PRs in 30d
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from DataDog/ddprof
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
-
Difficulty 5/5 Over a week Newbie friendliness 15/100
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
-
Difficulty 5/5 Over a week Newbie friendliness 25/100
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 90/100
AXERA-TECH/ax-llm#77 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
-
bug-unconfirmed
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
NVIDIA/cuda-samples#453 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
infiniflow/infinity#3502 ·