Tencent/matrix · error · ParseException
utime
Error message
${statBuffer}
utime: ${num} What it means
ProcStatUtil.parseWithBuffer tokenizes the /proc/<pid>/stat byte array field-by-field; for field 14 (utime) it extracts the token and validates it with isNumeric(). If the token is not numeric it throws ParseException containing the whole stat line plus "utime: <token>", because assigning a non-numeric utime would corrupt CPU-time accounting.
Solutions
- Catch ParseException, log the embedded raw stat line (the message contains it), and skip this sample.
- Verify comm handling: the parser must skip the parenthesized name including any spaces/digits before counting fields.
- Use the embedded stat content in the message to diagnose the exact misalignment on the failing device.
- Update Matrix or patch parseWithBuffer to locate utime/stime relative to the last ')' instead of counting fields.
Example fix
// before
StatModel stat = ProcStatUtil.instance.parseWithBufferForPath(path);
// after
try {
StatModel stat = ProcStatUtil.instance.parseWithBufferForPath(path);
} catch (ProcStatUtil.ParseException e) {
Log.w(TAG, "bad stat line: " + e.getMessage()); // message contains raw buffer
} Defensive patterns
Strategy: try-catch
Validate before calling
String line = readStatLine(pid);
int close = line.lastIndexOf(')');
String[] fields = line.substring(close + 2).trim().split("\\s+");
boolean utimeOk = fields.length > 11 && fields[11].matches("\\d+"); Try / catch
try { StatModel s = ProcStatUtil.instance.parseWithBufferForPath(path); } catch (ProcStatUtil.ParseException e) { Log.w(TAG, "raw stat: " + e.getMessage()); } Prevention
- Use the raw stat line embedded in the exception message to diagnose field shifts
- Parse fields relative to the last ')' to be immune to odd comm values
- Test with process names containing spaces and digits
- Skip samples that fail numeric validation rather than defaulting values
When it happens
Trigger: Field 14 of the stat line does not parse as a number - usually the comm field contained spaces/digits shifting token positions, or the buffer was truncated mid-field.
Common situations: Processes whose names contain spaces or digits (comm not correctly bracketed), emulators/vendor kernels with unusual stat layout, partially read buffers.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08).
Data as JSON: /api/errors/bcd6c07b1e950967.
Report an issue: GitHub.
Appendix: source
Thrown at matrix/matrix-android/matrix-battery-canary/src/main/java/com/tencent/matrix/batterycanary/utils/ProcStatUtil.java:235
// seek next space
while (i < statBytes && !Character.isSpaceChar(statBuffer[i])) {
i++;
window++;
}
stat.stat = safeBytesToString(statBuffer, readIdx, window);
break;
}
case 14: { // utime
int readIdx = i, window = 0;
// seek next space
while (i < statBytes && !Character.isSpaceChar(statBuffer[i])) {
i++;
window++;
}
String num = safeBytesToString(statBuffer, readIdx, window);
if (!isNumeric(num)) {
throw new ParseException(safeBytesToString(statBuffer, 0, statBuffer.length) + "\nutime: " + num);
}
stat.utime = MatrixUtil.parseLong(num, 0);
break;
}
case 15: { // stime
int readIdx = i, window = 0;
// seek next space
while (i < statBytes && !Character.isSpaceChar(statBuffer[i])) {
i++;
window++;
}
String num = safeBytesToString(statBuffer, readIdx, window);
if (!isNumeric(num)) {
throw new ParseException(safeBytesToString(statBuffer, 0, statBuffer.length) + "\nstime: " + num);
}
stat.stime = MatrixUtil.parseLong(num, 0);
break;
}View on GitHub (pinned to 3b8293bd65)