Tencent/matrix · error · ParseException

ProcStatReader error

Error message

ProcStatReader error: ${e.getClass().getName()}, ${e.getMessage()}

What it means

ProcStatUtil.parse wraps its BufferedReader-based /proc stat parsing; any unexpected Exception (IO error, NumberFormatException, index problems) is converted to a ParseException prefixed 'ProcStatReader error:' with the exception class and message, while genuine ParseExceptions are rethrown untouched. It tells you the stat file read itself failed, not that a field was malformed.

Solutions

  1. Read the wrapped class name: IOException means the stat file vanished/unreadable — treat as a transient miss and re-sample.
  2. If it's a NumberFormatException, inspect the stat content for kernel format differences.
  3. Catch ParseException at the call site and continue monitoring rather than disabling the collector.
  4. Verify the target process still exists (check /proc/<pid> before reading) and that the app has /proc read permission (not blocked by hidepid or SELinux).

Example fix

// before
ProcStat stat = ProcStatUtil.parse(reader);
// after
ProcStat stat = null;
try {
    stat = ProcStatUtil.parse(reader);
} catch (ParseException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("ProcStatReader error")) {
        MatrixLog.w(TAG, "stat read failed, will retry: " + e.getMessage());
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

File f = new File("/proc/" + pid + "/stat");
if (!f.exists() || !f.canRead()) return null;

Type guard

static boolean canReadStat(int pid) {
    File f = new File("/proc/" + pid + "/stat");
    return f.exists() && f.canRead();
}

Try / catch

try {
    stat = ProcStatUtil.parse(reader);
} catch (ParseException e) {
    if (e.getMessage() != null && e.getMessage().contains("ProcStatReader error")) {
        Log.w(TAG, "stat read IO failure, will re-sample: " + e.getMessage());
    }
    stat = null;
}

Prevention

When it happens

Trigger: Calling ProcStatUtil.parse when the underlying reader throws — /proc/<pid>/stat disappeared mid-read (IOException, process exited), stream closed, or a runtime exception (e.g. NumberFormatException) occurs inside readJiffy/readInt helpers.

Common situations: Device under heavy process churn (parent reaped the process between open and read); restricted /proc access on some OEMs; low-level IO errors from /proc filesystem.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08). Data as JSON: /api/errors/19fed8befcfe336e. Report an issue: GitHub.

Appendix: source

Thrown at matrix/matrix-android/matrix-battery-canary/src/main/java/com/tencent/matrix/batterycanary/utils/ProcStatUtil.java:380

                int index = 0;
                while (index < PROC_USER_TIME_FIELD - 2) {
                    reader.skipSpaces();
                    index++;
                }

                ProcStat stat = new ProcStat();
                stat.comm = String.valueOf(comm);
                stat.stat = String.valueOf(state);
                stat.utime = readJiffy(reader);
                stat.stime = readJiffy(reader);
                stat.cutime = readJiffy(reader);
                stat.cstime = readJiffy(reader);
                return stat;
            } catch (Exception e) {
                if (e instanceof ParseException) {
                    throw e;
                } else {
                    throw new ParseException("ProcStatReader error: " + e.getClass().getName() + ", " + e.getMessage());
                }
            } finally {
                try {
                    reader.close();
                } catch (Exception ignored) {
                }
            }
        }

        private static long readJiffy(ProcStatReader reader) {
            long jiffies = reader.readNumber();
            reader.skipSpaces();
            return jiffies;
        }
    }

    @SuppressWarnings("SpellCheckingInspection")
    public static class ProcStat {

View on GitHub (pinned to 3b8293bd65)