@Override
    public void traceBlockEnd(int stackId) {
        if (closed) {
            if (logger.isWarnEnabled()) {
                stackDump("already closed trace");
            }
            return;
        }

        final SpanEvent spanEvent = callStack.pop();
        if (spanEvent == null) {
            if (logger.isWarnEnabled()) {
                stackDump("call stack is empty.");
            }
            return;
        }

        if (isDummySpanEvent(spanEvent)) {
            if (isDebug) {
                logger.debug("[{}] Skip dummy spanEvent", this);
            }
            return;
        }

        if (spanEvent.getStackId() != stackId) {
            // stack dump will make debugging easy.
            if (logger.isWarnEnabled()) {
                stackDump("not matched stack id. expected=" + stackId + ", current=" + spanEvent.getStackId());
            }
        }

        if (spanEvent.isTimeRecording()) {
            spanEvent.markAfterTime();
        }
        logSpan(spanEvent);
        // state restore
        final SpanEvent previous = callStack.peek();
        wrappedSpanEventRecorder(wrappedSpanEventRecorder, previous);
    }
@author netspider
@author emeroad
@author jaehong.kim
agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultTrace.java