{"record":{"id":"42b420339e98dc79","repo":"Tencent/matrix","slug":"sbuffer-null","errorCode":null,"errorMessage":" sBuffer == null","messagePattern":" sBuffer == null","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"matrix/matrix-android/matrix-trace-canary/src/main/java/com/tencent/matrix/trace/core/AppMethodBeat.java","lineNumber":132,"sourceCode":"                }\n            } catch (Exception e) {\n                MatrixLog.e(TAG, \"\" + e.toString());\n            }\n        }\n    };\n\n    public static AppMethodBeat getInstance() {\n        return sInstance;\n    }\n\n    @Override\n    public void onStart() {\n        synchronized (statusLock) {\n            if (status < STATUS_STARTED && status >= STATUS_EXPIRED_START) {\n                sHandler.removeCallbacks(checkStartExpiredRunnable);\n                MatrixHandlerThread.getDefaultHandler().removeCallbacks(realReleaseRunnable);\n                if (sBuffer == null) {\n                    throw new RuntimeException(TAG + \" sBuffer == null\");\n                }\n                MatrixLog.i(TAG, \"[onStart] preStatus:%s\", status, Utils.getStack());\n                status = STATUS_STARTED;\n            } else {\n                MatrixLog.w(TAG, \"[onStart] current status:%s\", status);\n            }\n        }\n    }\n\n    @Override\n    public void onStop() {\n        synchronized (statusLock) {\n            if (status == STATUS_STARTED) {\n                MatrixLog.i(TAG, \"[onStop] %s\", Utils.getStack());\n                status = STATUS_STOPPED;\n            } else {\n                MatrixLog.w(TAG, \"[onStop] current status:%s\", status);\n            }","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/Tencent/matrix/blob/3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7/matrix/matrix-android/matrix-trace-canary/src/main/java/com/tencent/matrix/trace/core/AppMethodBeat.java#L114-L150","documentation":"AppMethodBeat.onStart() throws this RuntimeException when the method is called while sBuffer (the internal long[] ring buffer that records method trace timestamps) is still null. sBuffer is allocated during AppMethodBeat.init(); starting the tracer without a buffer would leave the whole method-instrumentation pipeline with nowhere to write, so the library fails fast under statusLock.","triggerScenarios":"Calling stopAppMethodBeat() (which calls onStart) or AppMethodBeat.onStart() directly before init()/onCreate() has allocated sBuffer, or after the buffer was released without re-initializing. The status check (STATUS_EXPIRED_START <= status < STATUS_STARTED) passes because the delayed realReleaseRunnable was cancelled, but the buffer was never allocated.","commonSituations":"Startup race where TracePlugin is started before AppMethodBeat.init() completes; calling start APIs manually during Application lifecycle before the plugin's onCreate; a prior release/reset leaving status inconsistent with the buffer state.","solutions":["Ensure AppMethodBeat.init(config) is called (via TracePlugin.onCreate) before any call to onStart/stopAppMethodBeat","Start the plugin through Matrix's plugin lifecycle (Matrix.Builder with TracePlugin) instead of calling core APIs directly","Check that no code path calls stopAppMethodBeat during initialization or re-entry","Verify status handling: re-init after a previous release to reallocate sBuffer"],"exampleFix":"// before\nTracePlugin trace = new TracePlugin(config);\ntrace.start(); // onStart called before init allocated sBuffer\n// after\nMatrix.with().getPlugin(TracePlugin.class); // ensure plugin initialized first\n AppMethodBeat.init(config); // allocates sBuffer\n AppMethodBeat.onStart();","handlingStrategy":"try-catch","validationCode":"if (AppMethodBeat.isAppStartTimeCalled() || statusCheck()) { /* ensure init called */ AppMethodBeat.init(config); }","typeGuard":"if (!tracePlugin.isInitialized()) { tracePlugin.init(config); }","tryCatchPattern":"try { AppMethodBeat.onStart(); } catch (RuntimeException e) { MatrixLog.e(TAG, \"start before init\", e); AppMethodBeat.init(config); AppMethodBeat.onStart(); }","preventionTips":["Always initialize Matrix/TracePlugin in Application.onCreate on the main thread","Never call low-level AppMethodBeat start/stop APIs directly; use the plugin lifecycle","Pair every release with a subsequent re-init","Add startup-order assertions in debug builds"],"tags":["android","matrix","trace","initialization-order","null-pointer"],"backgroundTag":"module-init-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"}