{"record":{"id":"01f167978b3507ca","repo":"pinpoint-apm/pinpoint","slug":"corrupted-call-stack-found-traceroot-callstack-01f167","errorCode":null,"errorMessage":"Corrupted call stack found TraceRoot:{}, CallStack:{}","messagePattern":"Corrupted call stack found TraceRoot:(.+?), CallStack:(.+?)","errorType":"console","errorClass":"PinpointException","httpStatus":null,"severity":"error","filePath":"agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultTrace.java","lineNumber":125,"sourceCode":"        return wrappedSpanEventRecorder(wrappedSpanEventRecorder, spanEvent);\n    }\n\n    private SpanEvent traceBlockBegin0(final int stackId) {\n        if (closed) {\n            if (logger.isWarnEnabled()) {\n                stackDump(\"already closed trace\");\n            }\n            return dummySpanEvent();\n        }\n        // Set properties for the case when stackFrame is not used as part of Span.\n        final SpanEvent spanEvent = newSpanEvent(stackId);\n        this.callStack.push(spanEvent);\n        return spanEvent;\n    }\n\n    private void stackDump(String caused) {\n        PinpointException exception = new PinpointException(caused);\n        logger.warn(\"Corrupted call stack found TraceRoot:{}, CallStack:{}\", getTraceRoot(), callStack, exception);\n    }\n\n    @Override\n    public void traceBlockEnd() {\n        traceBlockEnd(DEFAULT_STACKID);\n    }\n\n    @Override\n    public void traceBlockEnd(int stackId) {\n        if (closed) {\n            if (logger.isWarnEnabled()) {\n                stackDump(\"already closed trace\");\n            }\n            return;\n        }\n\n        final SpanEvent spanEvent = callStack.pop();\n        if (spanEvent == null) {","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultTrace.java#L107-L143","documentation":"DefaultTrace.stackDump(String) logs 'Corrupted call stack found TraceRoot:{}, CallStack:{}' and attaches a PinpointException when the internal CallStack is inconsistent — typically a traceBlockEnd() with no matching traceBlockBegin(), or leftover unended span events. It dumps the trace root and full call stack for diagnosis; the exception is only for logging, not always rethrown.","triggerScenarios":"Calling traceBlockEnd() without a prior traceBlockBegin(); calling traceBlockBegin/traceBlockEnd from different threads on the same Trace; a begin/end pair skipped because an exception short-circuited the ending interceptor; trace close while span events remain unbalanced.","commonSituations":"Buggy interceptor/plugin code where the end interceptor is not invoked (early return, swallowed exception); asynchronous work continuing after the synchronous trace ended; agent bugs in async trace continuation.","solutions":["Verify every traceBlockBegin() has a matching traceBlockEnd() in the same thread, including on exception paths (use try/finally)","Check interceptor/plugin implementations for early returns that skip the end-side interceptor","Enable the logged dump: inspect TraceRoot and CallStack contents to find the unbalanced block","Upgrade the pinpoint agent if async trace handling versions have known stack-corruption fixes"],"exampleFix":"// before\ntrace.traceBlockBegin();\nif (bad) return; // skips traceBlockEnd -> corrupted stack\ntrace.traceBlockEnd();\n// after\ntrace.traceBlockBegin();\ntry {\n    if (bad) return;\n} finally {\n    trace.traceBlockEnd();\n}","handlingStrategy":"validation","validationCode":"// ensure begin/end are balanced before ending\nif (spanBeginDepth <= 0) { throw new IllegalStateException(\"traceBlockEnd without begin\"); }","typeGuard":null,"tryCatchPattern":"try { trace.traceBlockEnd(); } catch (PinpointException e) { logger.warn(\"unbalanced trace block\", e); }","preventionTips":["Always pair traceBlockBegin/traceBlockEnd in try/finally","Never call trace methods across threads on the same Trace","Test instrumented code with exceptions and early returns","Keep begin/end instrumentation in matched interceptor pairs"],"tags":["java","call-stack","span-lifecycle","pinpoint-profiler"],"backgroundTag":"internal-invariant-violation","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}