{"record":{"id":"776777b40b82bfb6","repo":"Tencent/matrix","slug":"statbuffer-stime-num","errorCode":null,"errorMessage":"${statBuffer}\nstime: ${num}","messagePattern":"(.+?)\nstime: (.+?)","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":249,"sourceCode":"                        window++;\n                    }\n                    String num = safeBytesToString(statBuffer, readIdx, window);\n                    if (!isNumeric(num)) {\n                        throw new ParseException(safeBytesToString(statBuffer, 0, statBuffer.length) + \"\\nutime: \" + num);\n                    }\n                    stat.utime = MatrixUtil.parseLong(num, 0);\n                    break;\n                }\n                case 15: { // stime\n                    int readIdx = i, window = 0;\n                    // seek next space\n                    while (i < statBytes && !Character.isSpaceChar(statBuffer[i])) {\n                        i++;\n                        window++;\n                    }\n                    String num = safeBytesToString(statBuffer, readIdx, window);\n                    if (!isNumeric(num)) {\n                        throw new ParseException(safeBytesToString(statBuffer, 0, statBuffer.length) + \"\\nstime: \" + num);\n                    }\n                    stat.stime = MatrixUtil.parseLong(num, 0);\n                    break;\n                }\n                case 16: { // cutime\n                    int readIdx = i, window = 0;\n                    // seek next space\n                    while (i < statBytes && !Character.isSpaceChar(statBuffer[i])) {\n                        i++;\n                        window++;\n                    }\n                    String num = safeBytesToString(statBuffer, readIdx, window);\n                    if (!isNumeric(num)) {\n                        throw new ParseException(safeBytesToString(statBuffer, 0, statBuffer.length) + \"\\ncutime: \" + num);\n                    }\n                    stat.cutime = MatrixUtil.parseLong(num, 0);\n                    break;\n                }","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/Tencent/matrix/blob/3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7/matrix/matrix-android/matrix-battery-canary/src/main/java/com/tencent/matrix/batterycanary/utils/ProcStatUtil.java#L231-L267","documentation":"Same validation as utime but for field 15 (stime) in ProcStatUtil.parseWithBuffer: the extracted token must pass isNumeric() or a ParseException with the full stat line and \"stime: <token>\" is thrown. It protects kernel-time (stime) accounting from garbage tokens.","triggerScenarios":"Field 15 of the stat buffer is not numeric - token misalignment from a comm field containing spaces/digits, or a truncated/partial read of the stat file.","commonSituations":"Vendor kernel stat format differences; process names shifting field positions; the utime parse succeeded but the next token is misplaced text rather than a number.","solutions":["Catch ParseException and skip the sample; the message includes the raw stat line for diagnosis.","Fix comm-field consumption (parse fields relative to the final ')') so utime/stime land on the correct tokens.","Compare the embedded stat line in the exception with the expected 52-field layout to find the offset.","Update Matrix to a version with hardened stat parsing if available."],"exampleFix":"// before\nstat.stime = MatrixUtil.parseLong(num, 0);\n// after\nif (!isNumeric(num)) {\n    Log.w(TAG, \"skip stat, bad stime token: \" + num);\n    return null; // or throw as library does; callers should catch ParseException\n}\nstat.stime = MatrixUtil.parseLong(num, 0);","handlingStrategy":"try-catch","validationCode":"String line = readStatLine(pid);\nint close = line.lastIndexOf(')');\nString[] fields = line.substring(close + 2).trim().split(\"\\\\s+\");\nboolean stimeOk = fields.length > 12 && fields[12].matches(\"\\\\d+\");","typeGuard":null,"tryCatchPattern":"try { StatModel s = ProcStatUtil.instance.parseWithBufferForPath(path); } catch (ProcStatUtil.ParseException e) { if (e.getMessage().contains(\"stime:\")) { /* log raw line, skip */ } }","preventionTips":["Validate both utime and stime tokens before consuming the stat","Anchor field indices to the closing parenthesis of comm","Keep the exception message (contains full stat line) in logs for diagnosis","Pin a Matrix version with hardened stat parsing on affected kernels"],"tags":["android","proc-stat","stime","parser"],"backgroundTag":"invalid-argument-format","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"}