{"record":{"id":"05b7a5ab1e83e7e8","repo":"alibaba/arthas","slug":"backtracenum-must-be-1-or-greater","errorCode":null,"errorMessage":"backtraceNum must be -1 or greater","messagePattern":"backtraceNum must be -1 or greater","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"arthas-vmtool/src/main/java/arthas/VmTool.java","lineNumber":150,"sourceCode":"    }\n\n    private static synchronized native int mallocTrim0();\n\n    @Override\n    public boolean mallocStats() {\n        return mallocStats0();\n    }\n    private static synchronized native boolean mallocStats0();\n\n    @Override\n    public String heapAnalyze(int classNum, int objectNum) {\n        return heapAnalyze0(classNum, objectNum);\n    }\n\n    @Override\n    public String referenceAnalyze(Class<?> klass, int objectNum, int backtraceNum) {\n        if (backtraceNum < -1) {\n            throw new IllegalArgumentException(\"backtraceNum must be -1 or greater\");\n        }\n        return referenceAnalyze0(klass, objectNum, backtraceNum);\n    }\n}\n","sourceCodeStart":132,"sourceCodeEnd":155,"githubUrl":"https://github.com/alibaba/arthas/blob/21cf2e9ba52b305290be7223b980ff504bb9cb5b/arthas-vmtool/src/main/java/arthas/VmTool.java#L132-L155","documentation":"VmTool.referenceAnalyze(Class, int objectNum, int backtraceNum) rejects backtraceNum < -1. The value -1 is the documented sentinel meaning 'do not capture allocation backtraces'; any non-negative value requests that many backtraces per object. Values below -1 are invalid.","triggerScenarios":"Calling referenceAnalyze with a backtraceNum computed from user input or a subtraction that yields -2 or lower (e.g. depth - 1 where depth was 0).","commonSituations":"A 'disable backtraces' flag mapped to a negative sentinel via subtraction; an unset option defaulting to a negative number; off-by-one when clamping an upper bound.","solutions":["Pass -1 to disable backtrace capture, or a non-negative int to capture N backtraces.","Clamp the computed value: backtraceNum = Math.max(-1, value).","Validate user-supplied backtrace depth before calling."],"exampleFix":"// before\nString r = vmTool.referenceAnalyze(klass, objNum, depth - 1);  // depth == 0 -> -1 ok; depth negative -> throws\n\n// after\nint bt = Math.max(-1, depth - 1);\nString r = vmTool.referenceAnalyze(klass, objNum, bt);","handlingStrategy":"validation","validationCode":"int safeBt = Math.max(-1, backtraceNum);","typeGuard":"static boolean isValidBacktraceNum(int n) {\n    return n >= -1;\n}","tryCatchPattern":"try {\n    return vmTool.referenceAnalyze(klass, objNum, bt);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"backtraceNum\")) {\n        return vmTool.referenceAnalyze(klass, objNum, -1);\n    }\n    throw e;\n}","preventionTips":["Clamp backtraceNum with Math.max(-1, value) before calling.","Map 'disabled' flags to -1, never to a computed negative.","Document the -1 sentinel (no backtrace capture) in wrapper APIs."],"tags":["vmtool","validation","jvm","argument"],"backgroundTag":null,"analyzedSha":"21cf2e9ba52b305290be7223b980ff504bb9cb5b","analyzedAt":"2026-08-14T00:57:07.243Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}