{"record":{"id":"19fed8befcfe336e","repo":"Tencent/matrix","slug":"procstatreader-error-e-getclass-getname","errorCode":null,"errorMessage":"ProcStatReader error: ${e.getClass().getName()}, ${e.getMessage()}","messagePattern":"ProcStatReader error: (.+?), (.+?)","errorType":"exception","errorClass":"ParseException","httpStatus":null,"severity":"error","filePath":"matrix/matrix-android/matrix-battery-canary/src/main/java/com/tencent/matrix/batterycanary/utils/ProcStatUtil.java","lineNumber":380,"sourceCode":"                int index = 0;\n                while (index < PROC_USER_TIME_FIELD - 2) {\n                    reader.skipSpaces();\n                    index++;\n                }\n\n                ProcStat stat = new ProcStat();\n                stat.comm = String.valueOf(comm);\n                stat.stat = String.valueOf(state);\n                stat.utime = readJiffy(reader);\n                stat.stime = readJiffy(reader);\n                stat.cutime = readJiffy(reader);\n                stat.cstime = readJiffy(reader);\n                return stat;\n            } catch (Exception e) {\n                if (e instanceof ParseException) {\n                    throw e;\n                } else {\n                    throw new ParseException(\"ProcStatReader error: \" + e.getClass().getName() + \", \" + e.getMessage());\n                }\n            } finally {\n                try {\n                    reader.close();\n                } catch (Exception ignored) {\n                }\n            }\n        }\n\n        private static long readJiffy(ProcStatReader reader) {\n            long jiffies = reader.readNumber();\n            reader.skipSpaces();\n            return jiffies;\n        }\n    }\n\n    @SuppressWarnings(\"SpellCheckingInspection\")\n    public static class ProcStat {","sourceCodeStart":362,"sourceCodeEnd":398,"githubUrl":"https://github.com/Tencent/matrix/blob/3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7/matrix/matrix-android/matrix-battery-canary/src/main/java/com/tencent/matrix/batterycanary/utils/ProcStatUtil.java#L362-L398","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Read the wrapped class name: IOException means the stat file vanished/unreadable — treat as a transient miss and re-sample.","If it's a NumberFormatException, inspect the stat content for kernel format differences.","Catch ParseException at the call site and continue monitoring rather than disabling the collector.","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)."],"exampleFix":"// before\nProcStat stat = ProcStatUtil.parse(reader);\n// after\nProcStat stat = null;\ntry {\n    stat = ProcStatUtil.parse(reader);\n} catch (ParseException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"ProcStatReader error\")) {\n        MatrixLog.w(TAG, \"stat read failed, will retry: \" + e.getMessage());\n    }\n}","handlingStrategy":"try-catch","validationCode":"File f = new File(\"/proc/\" + pid + \"/stat\");\nif (!f.exists() || !f.canRead()) return null;","typeGuard":"static boolean canReadStat(int pid) {\n    File f = new File(\"/proc/\" + pid + \"/stat\");\n    return f.exists() && f.canRead();\n}","tryCatchPattern":"try {\n    stat = ProcStatUtil.parse(reader);\n} catch (ParseException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"ProcStatReader error\")) {\n        Log.w(TAG, \"stat read IO failure, will re-sample: \" + e.getMessage());\n    }\n    stat = null;\n}","preventionTips":["Check /proc/<pid>/stat exists and is readable before parsing (hidepid/SELinux can block it).","Expect IOException when a process exits between open and read — retry the sample.","Don't disable monitoring on a single wrapped failure; count failures and degrade after a threshold.","On failing devices verify kernel /proc stat format."],"tags":["android","procfs","io","wrapped-exception"],"backgroundTag":"file-read-failed","analyzedSha":"3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7","analyzedAt":"2026-09-08T08:01:39.722Z","contentChangedAt":"2026-09-08T08:01:39.722Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}