Skip to content

Commit c591230

Browse files
committed
chore(crashtracking): Redact unknown memory
1 parent ab51afc commit c591230

3 files changed

Lines changed: 61 additions & 1 deletion

File tree

dd-java-agent/agent-crashtracking/src/main/java/datadog/crashtracking/parsers/RedactUtils.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ public final class RedactUtils {
5454
private static final Pattern IS_AN_OOP =
5555
Pattern.compile("(is an oop: )([A-Za-z][A-Za-z0-9$]*(?:\\.[A-Za-z][A-Za-z0-9$]*)*)");
5656

57+
// Hex-dump bytes in "points into unknown readable memory:" lines.
58+
// Two formats produced by os::print_location():
59+
// "memory: 0x<addr> | ff ff ff ff ..." (Linux/macOS amd64 — address + pipe + bytes)
60+
// "memory: ff ff ff ff ..." (Linux aarch64 — bytes only)
61+
// The address (when present) is kept; only the raw bytes are redacted.
62+
private static final Pattern READABLE_MEMORY_HEX_DUMP =
63+
Pattern.compile(
64+
"(points into unknown readable memory: (?:0x[0-9a-fA-F]+ \\| )?)([0-9a-fA-F]{2}(?: [0-9a-fA-F]{2})*)");
65+
5766
private RedactUtils() {}
5867

5968
/**
@@ -79,6 +88,7 @@ private static String redactLine(String line) {
7988
line = redactLibraryPath(line);
8089
line = redactDottedClassOopRef(line);
8190
line = redactOopClassName(line);
91+
line = redactReadableMemoryHexDump(line);
8292
return line;
8393
}
8494

@@ -144,6 +154,20 @@ static String redactOopClassName(String line) {
144154
return replaceAll(IS_AN_OOP, line, m -> m.group(1) + redactDottedClassName(m.group(2)));
145155
}
146156

157+
/**
158+
* Redacts hex-dump bytes in <code>points into unknown readable memory:</code> lines, keeping the
159+
* optional leading address. Handles two formats:
160+
*
161+
* <ul>
162+
* <li><code>memory: 0x&lt;addr&gt; | ff ff ff ff</code> to <code>memory: 0x&lt;addr&gt; |
163+
* REDACTED</code>
164+
* <li><code>memory: ff ff ff ff</code> to <code>memory: REDACTED</code>
165+
* </ul>
166+
*/
167+
static String redactReadableMemoryHexDump(String line) {
168+
return replaceAll(READABLE_MEMORY_HEX_DUMP, line, m -> m.group(1) + REDACTED_STRING);
169+
}
170+
147171
/**
148172
* Redacts the package of a slash-separated JVM class name, unless it belongs to a known package.
149173
* <code>com/company/SomeType</code> to <code>redacted/redacted/SomeType</code>; <code>

dd-java-agent/agent-crashtracking/src/test/java/datadog/crashtracking/parsers/HotspotCrashLogParserTest.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ public void testRegisterToMemoryMappingMacosAarch64() throws Exception {
115115
.isEqualTo(
116116
"0x0000000106c1ccc0: _ZN19TemplateInterpreter13_active_tableE+0 in /redacted/redacted/redacted/redacted/redacted/redacted/redacted/redacted/redacted/server/libjvm.dylib at 0x0000000105efc000");
117117

118+
// macOS aarch64 uses address+pipe format — address kept, bytes redacted
119+
assertThat(mapping)
120+
.extractingByKey("x17", STRING)
121+
.isEqualTo(
122+
"0x0000000100a17cb0 points into unknown readable memory: 0x00000000ffffffff | REDACTED");
123+
118124
// "Top of Stack: (sp=0x...)" and "Instructions: (pc=0x...)" must not leak into register values
119125
assertThat(mapping).doesNotContainKey("Top of Stack");
120126
assertThat(mapping)
@@ -154,7 +160,7 @@ public void testRegisterToMemoryMapping() throws Exception {
154160
.isNotNull()
155161
.containsEntry(
156162
"RAX",
157-
"0x00007f36ccfbf170 points into unknown readable memory: 0x00007f3600000758 | 58 07 00 00 36 7f 00 00")
163+
"0x00007f36ccfbf170 points into unknown readable memory: 0x00007f3600000758 | REDACTED")
158164
.containsEntry(
159165
"RSP", "0x00007f35e6253190 is pointing into the stack for thread: 0x00007f36cd96cc80")
160166
.containsEntry("RDI", "0x0 is NULL")
@@ -183,6 +189,11 @@ public void testRegisterToMultilineMemoryMapping() throws Exception {
183189
.contains("\n - ---- fields (total size 25 words):")
184190
.contains(
185191
"\n - private transient 'name' 'Ljava/lang/String;' @44 \"jdk.internal.misc.Unsafe\"");
192+
193+
// Linux aarch64 uses bytes-only format (no address prefix before hex dump)
194+
assertThat(crashLog.experimental.registerToMemoryMapping)
195+
.extractingByKey("R9", STRING)
196+
.isEqualTo("0x0000ffff9f686ca4 points into unknown readable memory: REDACTED");
186197
}
187198

188199
@Test

dd-java-agent/agent-crashtracking/src/test/java/datadog/crashtracking/parsers/RedactUtilsTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,4 +247,29 @@ void testRedactRegisterToMemoryMapping_safeValuesUnchanged() {
247247
assertThat(RedactUtils.redactRegisterToMemoryMapping("0x000000008fd66048 is an unknown value"))
248248
.isEqualTo("0x000000008fd66048 is an unknown value");
249249
}
250+
251+
@Test
252+
void testRedactReadableMemoryHexDump_withAddressAndPipe() {
253+
// Linux/macOS amd64: address + " | " + bytes — keep address, redact bytes
254+
assertThat(
255+
RedactUtils.redactReadableMemoryHexDump(
256+
"0x0000000100a17cb0 points into unknown readable memory: 0x00000000ffffffff | ff ff ff ff 00 00 00 00"))
257+
.isEqualTo(
258+
"0x0000000100a17cb0 points into unknown readable memory: 0x00000000ffffffff | REDACTED");
259+
}
260+
261+
@Test
262+
void testRedactReadableMemoryHexDump_withoutAddress() {
263+
// Linux aarch64: bytes only — redact everything after the colon
264+
assertThat(
265+
RedactUtils.redactReadableMemoryHexDump(
266+
"0x0000ffff9f686ca4 points into unknown readable memory: 06 00 00 00"))
267+
.isEqualTo("0x0000ffff9f686ca4 points into unknown readable memory: REDACTED");
268+
}
269+
270+
@Test
271+
void testRedactReadableMemoryHexDump_leavesUnrelatedLinesUnchanged() {
272+
assertThat(RedactUtils.redactReadableMemoryHexDump("0x00007f37a16e2590 is an unknown value"))
273+
.isEqualTo("0x00007f37a16e2590 is an unknown value");
274+
}
250275
}

0 commit comments

Comments
 (0)