Tencent/matrix · warning · ProcStatUtil.ParseException
RAF err
Error message
RAF err: ${ioe.getMessage()} What it means
ProcStatReader.reset() lazily opens /proc/<pid>/stat as a RandomAccessFile; if the open throws IOException the reader marks itself invalid, closes, and rethrows as ParseException("RAF err: <message>"). It signals that the proc stat file could not be opened for reading at all, before any parsing starts.
Solutions
- Catch ParseException around parse calls and skip/ignore that pid (transient process-exit is expected).
- Verify the target pid is still alive (e.g. check /proc/<pid> exists or Process.isThreadRunning) before parsing.
- Retry on the next sampling tick; if it fails persistently for the app's own pid, log the device/SELinux context.
- Ensure the reader path points to the app's own process stats when lacking permission to read others.
Example fix
// before
StatModel stat = ProcStatUtil.instance.parse(pid);
// after
try {
StatModel stat = ProcStatUtil.instance.parse(pid);
} catch (ProcStatUtil.ParseException e) {
// process died or file unreadable; skip this tick
return;
} Defensive patterns
Strategy: try-catch
Validate before calling
java.io.File f = new File("/proc/" + pid + "/stat");
if (!f.exists() || !f.canRead()) { /* skip pid */ } Try / catch
try { StatModel s = ProcStatUtil.instance.parse(pid); } catch (ProcStatUtil.ParseException e) { Log.w(TAG, "stat open failed: " + e.getMessage()); } Prevention
- Check pid liveness before each sample
- Only read the app's own /proc stats unless root privileges are available
- Treat each parse as best-effort; never let one pid failure break the sampling loop
- Log device/SELinux context for persistent failures
When it happens
Trigger: Calling ProcStatUtil.parse/parseWithBufferForPath for a pid whose /proc/<pid>/stat cannot be opened: the process exited between listing and reading, the path does not exist, or the kernel/security module denies open.
Common situations: Short-lived child processes dying before the battery canary polls them; restricted SELinux policies on some Android vendors; reading stats of other users' processes on non-rooted devices.
Understand the failure class
Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.
Related errors
- Couldn't read string because file ended!
- Can only rewind one step!
- Couldn't read string!
- Couldn't read number!
- Couldn't read number because the file ended!
AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08).
Data as JSON: /api/errors/1d215e01bb1a2778.
Report an issue: GitHub.
Appendix: source
Thrown at matrix/matrix-android/matrix-battery-canary/src/main/java/com/tencent/matrix/batterycanary/utils/ProcStatReader.java:60
mIsValid = true;
// First, try to move the pointer if a file exists
if (mFile != null) {
try {
mFile.seek(0);
} catch (IOException ioe) {
close();
}
}
// Otherwise try to open/reopen the file and fail
if (mFile == null) {
try {
mFile = new RandomAccessFile(mPath, "r");
} catch (IOException ioe) {
mIsValid = false;
close();
throw new ProcStatUtil.ParseException("RAF err: " + ioe.getMessage());
}
}
if (mIsValid) {
mPosition = -1;
mBufferSize = 0;
mChar = 0;
mPrev = 0;
mRewound = false;
}
return this;
}
public boolean isValid() {
return mIsValid;View on GitHub (pinned to 3b8293bd65)