TRACE, UNTRACE — 함수 호출을 추적하는 디버깅 매크로

TRACE, UNTRACE — 함수 호출을 추적하는 디버깅 매크로

함수가 호출될 때 어떤 인자로 불리고 어떤 값을 돌려주는지 출력해 보게 하는 매크로예요. 재귀 함수처럼 호출 흐름이 복잡할 때 실행 경로를 눈으로 확인하기 좋아요. untrace는 추적을 끊는 매크로예요.

출처: CLHS: Macro TRACE, UNTRACE

이 문서는 디버깅/개발용 매크로입니다. TRACE는 실행 추적 시점에 주로 유용해요.

시그니처

trace {function-name}* => trace-result
untrace {function-name}* => untrace-result

본문

인자와 값 (Arguments and Values)

  • function-name — 함수 이름(function name).
  • trace-resultfunction-name이 주어지지 않으면 함수 이름들의 목록이고, 그 외에는 **구현 의존적(implementation-dependent)**이에요.
  • untrace-result구현 의존적이에요.

설명 (Description)

traceuntrace는 trace 기능의 호출을 제어해요.

trace를 함수 이름 하나 이상과 함께 호출하면 그 함수들이 '추적(traced)'되게 만들어요. 추적되는 함수가 호출될 때마다 호출에 대한 정보, 전달된 인자, 결국 돌려주는 값에 대한 정보가 trace output에 출력돼요. function-name 없이 trace를 쓰면 추적 동작을 하지 않고, 현재 추적 중인 함수 목록을 돌려줘요.

untrace를 함수 이름 하나 이상과 함께 호출하면 그 함수들을 '추적 해제'(더 이상 추적되지 않게)해요. function-name 없이 untrace를 쓰면 현재 추적 중인 모든 함수가 추적 해제돼요.

추적할 함수가 open-coded(예: inline으로 선언)되어 있으면, 그 함수의 호출은 trace 출력을 만들지 않을 수 있어요.

예제 (Examples)

 (defun fact (n) (if (zerop n) 1 (* n (fact (- n 1)))))
=>  FACT
 (trace fact)
=>  (FACT)
;; Of course, the format of traced output is implementation-dependent.
 (fact 3)
>>  1 Enter FACT 3
>>  | 2 Enter FACT 2
>>  |   3 Enter FACT 1
>>  |   | 4 Enter FACT 0
>>  |   | 4 Exit FACT 1
>>  |   3 Exit FACT 1
>>  | 2 Exit FACT 2
>>  1 Exit FACT 6
=>  6

예제에서 재귀 호출이 깊어질수록 들여쓰기가 늘어나며 Enter/Exit이 찍히는 걸 볼 수 있어요. (추적 출력의 정확한 형식은 구현마다 달라요.)

부수 효과 (Side Effects)

function-name으로 이름 지어진 함수들의 정의를 바꿀 수 있어요.

영향 (Affected By)

이름 지어진 함수들이 정의되어 있는지, 이미 추적 중인지.

특이 상황 (Exceptional Situations)

이미 추적 중인 함수를 추적하거나, 추적 중이 아닌 함수를 추적 해제하는 것은 해로운 결과를 만들지 않아야 하지만, 경고를 신호할 수는 있어요.

참고 (Notes)

traceuntrace는 추가로 구현 의존적 인자 형식을 받아들일 수도 있어요. trace 출력의 형식도 구현 의존적이에요.

trace가 비표준 옵션을 허용하도록 확장될 수는 있지만, 구현들은 이 표준이 지정하지 않았거나 구현이 확장으로 추가하지 않은 문법이나 옵션이 쓰일 때 경고하도록 권장돼요(필수는 아니에요). 그런 사용은 오타나 다른 구현에서 지원되는 기능에 대한 의존을 암시할 수 있거든요.

더 알아보기

  • *trace-output* — trace 출력 스트림
  • step — 폼 평가를 단계적으로 따라가는 매크로