스택 추적
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
스택 추적(stack trace)은 프로그램 실행 중 특정 시점까지 호출된 함수들의 정보를 역추적하여 보여주는 기능이다. 스택, 즉 호출 스택의 정보를 바탕으로 하며, 디버깅 및 오류 분석에 유용하게 활용된다. 스택 트레이스를 통해 중첩된 함수 호출 순서와 오류 발생 지점을 파악할 수 있다. 많은 프로그래밍 언어에서 스택 추적 기능을 지원하며, 자바, C#, C++, 자바스크립트, 파이썬, 러스트 등 다양한 언어에서 스택 추적을 얻는 방법을 제공한다.
더 읽어볼만한 페이지
- 소프트웨어 개발 - 유스 케이스
유스 케이스는 시스템과 액터 간 상호작용을 통해 시스템 목표 달성에 기여하는 동작들을 나타내는 요구 사항 캡처, 모델링, 명세 기법으로, 객체 지향 소프트웨어 공학에서 기능 요구 사항을 캡처하는 데 중요한 역할을 하며 다양한 분야에서 활용된다. - 소프트웨어 개발 - 사용자 경험 디자인
사용자 경험 디자인은 인간 공학에 기반하여 제품 또는 서비스와 사용자 간의 상호작용을 설계하는 분야이며, 사용자 조사, 인터랙션 디자인, 사용성 테스트 등을 통해 효율적이고 만족스러운 경험을 제공하는 것을 목표로 한다. - 디버깅 - 메모리 디버거
메모리 디버거는 메모리 접근, 할당, 해제를 모니터링하여 메모리 오류를 찾아내고 소프트웨어의 신뢰성을 높이는 도구이다. - 디버깅 - 브레이크포인트
브레이크포인트는 프로그램 디버깅 시 특정 지점에서 실행을 중단시키는 기술 또는 지점으로, 케이블 제거에서 유래하여 대화형 디버깅 환경으로 발전했으며, 명령, 데이터, 조건부 브레이크포인트 등 다양한 종류가 있고 프로그램 상태 조사 및 변경 도구와 함께 사용되며, 하드웨어나 소프트웨어 방식으로 구현될 수 있다.
스택 추적 | |
---|---|
개요 | |
유형 | 소프트웨어 개발 도구 |
목적 | 프로그램 실행 중 스택 프레임 보고 |
관련 용어 | 디버깅 오류 추적 |
상세 정보 | |
정의 | 프로그램 실행 중 호출 스택의 기록 |
구성 요소 | 함수 호출 순서 각 함수 호출의 위치 (파일명 및 라인 번호) 변수 값 (디버깅 정보 포함 시) |
사용 목적 | 프로그램 오류 원인 분석 코드 실행 흐름 파악 디버깅 효율성 향상 |
생성 시점 | 오류 발생 시 자동 생성 디버거 명령으로 수동 생성 |
표현 방식 | 텍스트 기반 그래픽 기반 (IDE 디버거) |
포함 정보 | 호출 스택의 각 프레임 정보 함수 이름, 소스 파일명, 라인 번호 변수 값, 인수 정보 (디버깅 정보) |
활용 분야 | 소프트웨어 개발 시스템 관리 보안 분석 |
장점 | 오류 발생 지점 및 원인 파악 용이 코드 분석 시간 단축 프로그램 안정성 향상 |
단점 | 정보 과다로 분석 어려움 발생 가능 디버깅 정보 미포함 시 제한적인 정보 제공 |
주의 사항 | 개인 정보 및 보안 정보 노출 가능성 스택 트레이스 분석 도구 활용 필요 |
2. 상세
많은 프로그래밍 언어 (자바, C# 등)는 시스템 호출을 통해 현재 스택 추적을 검색하는 기능을 기본적으로 제공한다. C++는 이 기능이 기본적으로 제공되지는 않지만, [http://stacktrace.sourceforge.net/ stacktrace] 라이브러리를 통해 스택 추적을 검색할 수 있다. 자바스크립트에서는 예외 처리 시 `stack` 속성을 통해 스택 정보를 얻을 수 있다.
프로그램이 실행될 때 메모리는 크게 스택과 힙 두 영역으로 나뉜다. 여기서 스택은 호출 스택(call stack)이라고도 불리며, 함수 호출 정보를 순차적으로 저장한다. 힙은 프로세스 내의 모든 스레드에서 공유되지만, 호출 스택은 각 스레드마다 할당된다. 호출 스택은 LIFO(Last In, First Out) 구조로, 함수가 호출될 때마다 해당 함수의 정보(매개변수, 지역 변수, 반환 주소 등)를 담은 스택 프레임(Stack Frame)이 스택에 쌓이고, 함수 실행이 끝나면 제거된다.
2. 1. 스택 트레이스의 활용
프로그래머는 주로 디버깅 과정에서 스택 트레이스를 사용한다. 일반적인 통합 개발 환경에서는 디버거를 중단(일시 중지)했을 때 "호출 이력"으로 스택 트레이스를 시각적으로 보여주고 추적할 수 있게 해준다.[14] 최종 사용자에게는 오류 메시지의 일부로 스택 트레이스가 표시될 수 있으며, 이를 통해 장애를 보고할 때 활용할 수 있다.스택 트레이스를 사용하면, 스택 트레이스가 생성되기까지 호출된 중첩 함수의 순서를 추적할 수 있다. 오류 발생 후 분석에서는, 문제가 발생한 함수까지 추적할 수 있다 (항상 가능한 것은 아니다). 꼬리 재귀는 스택 트레이스에 나타나지 않는다.
다음은 오류가 있는 Python 프로그램 예시이다.
```python
def a():
i = 0
j = b(i)
return j
def b(z):
k = 5
if z == 0:
c()
return k/z
def c():
error() #존재하지 않는 함수를 호출하려고 함
a()
```
이 프로그램을 표준 Python 인터프리터로 실행하면 다음과 같은 오류 메시지가 나타난다.
```
Traceback (most recent call last):
File "tb.py", line 15, in
a()
File "tb.py", line 3, in a
j = b(i)
File "tb.py", line 9, in b
c()
File "tb.py", line 13, in c
error()
NameError: name 'error' is not defined
```
스택 트레이스는 오류가 발생한 위치, 즉 함수 `c`를 보여준다. 또한, 함수 `c`는 함수 `b`에서, 함수 `b`는 함수 `a`에서, 함수 `a`는 프로그램의 15행(마지막 행)에서 호출되었음을 알려준다.
이 세 함수 각각의 활성화 레코드는 함수 `a`가 스택의 맨 아래를 차지하고, 함수 `c`가 스택의 맨 위를 차지하도록 스택에 배치된다.
2. 2. 꼬리 재귀와 스택 트레이스
꼬리 재귀는 함수 호출이 함수의 마지막 부분에서 발생하는 재귀 호출 형태이다. 꼬리 재귀 최적화를 지원하는 컴파일러는 꼬리 재귀 호출 시 새로운 스택 프레임을 생성하지 않고 기존 스택 프레임을 재사용하므로, 스택 트레이스에 꼬리 재귀 호출 정보가 나타나지 않을 수 있다.[13]프로그래머는 일반적으로 디버깅에서 스택 트레이스를 사용한다. 일반적인 통합 개발 환경에서는 디버거를 중단(일시 중지)했을 때 "호출 이력"으로서 스택 트레이스를 직관적으로 표시·추적할 수 있다.[14] 최종 사용자에게는 오류 메시지의 일부로 스택 트레이스가 표시될 수 있으며, 장애 보고 시에 활용할 수 있다.
꼬리 재귀는 스택 트레이스에 표시되지 않는다.
3. 프로그래밍 언어별 지원
많은 프로그래밍 언어가 시스템 호출을 통해 현재 스택 추적을 검색하는 기능을 내장하고 있다. 예를 들어, 자바[3]와 C#[4]이 이에 해당한다. C++는 내장된 지원은 없지만, 외부 라이브러리를 통해 스택 추적을 얻을 수 있다. 자바스크립트에서는 예외가 발생하면 스택 정보가 포함된 `stack` 속성이 제공된다.
각 언어별 스택 추적 기능은 다음과 같이 요약할 수 있다.
언어 | 스택 추적 기능 |
---|---|
자바 | `Thread.dumpStack()` 메서드, 예외 객체를 통한 스택 추적 정보 제공 (자세한 내용은 해당 섹션 참조) |
C# (.NET) | 예외 객체를 통한 스택 추적 정보 제공 (자세한 내용은 해당 섹션 참조) |
C++ | C++23 이전에는 외부 라이브러리 필요, C++23부터 `std::stacktrace` 표준 라이브러리 제공 (자세한 내용은 해당 섹션 참조) |
자바스크립트 | 예외 객체의 `stack` 프로퍼티, `console.trace()` 메서드 (자세한 내용은 해당 섹션 참조) |
파이썬 | 오류 발생 시 인터프리터에서 자동 출력 (자세한 내용은 해당 섹션 참조) |
Rust | 실험적으로 복구 불가능한 오류에 대한 스택 추적 지원 (`RUST_BACKTRACE` 환경 변수 설정 필요) (자세한 내용은 해당 섹션 참조) |
3. 1. 자바 (Java)
자바에서 스택 추적은 `Thread.dumpStack()`method영어를 사용하여 수동으로 덤프할 수 있다.[5] 다음은 코드 예시이다.public class Main {
public static void main(String args[]) {
demo();
}
static void demo() {
demo1();
}
static void demo1() {
demo2();
}
static void demo2() {
demo3();
}
static void demo3() {
Thread.dumpStack();
}
}
위 코드를 실행하면 함수 호출 순서대로 스택 추적이 출력되는데, 가장 안쪽 호출이 먼저 표시된다. 출력 결과는 다음과 같다.
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:1336)
at Main.demo3(Main.java:15)
at Main.demo2(Main.java:12)
at Main.demo1(Main.java:9)
at Main.demo(Main.java:6)
at Main.main(Main.java:3)
자바는 시스템 호출을 통해 현재 스택 추적을 얻기 위한 기능을 표준 클래스 라이브러리 및 실행 환경에 내장하고 있다.[15][16][17]
3. 2. C# (.NET)
C# (.NET)을 비롯한 많은 프로그래밍 언어는 시스템 호출을 통해 현재 스택 추적을 얻는 기능을 표준 클래스 라이브러리 및 실행 환경에 내장하고 있다.[15][16][17]。자바[3]와 C#[4]은 예외 객체를 통해 스택 추적 정보를 제공한다.3. 3. C++
C++23 이전에는 스택 추적을 위한 표준 기능이 없었지만, Boost.Stacktrace 라이브러리[18]나 [http://stacktrace.sourceforge.net/ stacktrace] 라이브러리 (2013년 이후 업데이트 중단) 등을 통해 스택 추적을 얻을 수 있었다.[19] C++23부터는 `std::stacktrace`가 표준 라이브러리에 추가되어, `std::stacktrace::current()` 함수를 통해 현재 스택 추적을 얻을 수 있다.[8]glibc의 `backtrace()` 함수를 사용할 수도 있다.[6] C/C++에서는 인라인 확장, 꼬리 호출 최적화, 프레임 포인터 제거와 같은 컴파일러 최적화가 런타임에 복구할 수 있는 호출 스택 정보에 영향을 줄 수 있다는 점에 유의해야 한다.[6]
3. 4. 자바스크립트 (JavaScript)
자바스크립트에서는 예외 객체가 던져진 위치에서부터의 스택을 포함하는stack
프로퍼티를 가지고 있다. 그 외에도 `console.trace()` 메서드를 이용하는 방법도 있다.[20]3. 5. 파이썬 (Python)
파이썬 인터프리터에서는 오류 발생 시 자동으로 스택 추적 정보를 출력한다. 다음은 파이썬 코드 예시와 그에 따른 스택 추적 출력 예시이다.```python
def a():
i = 0
j = b(i)
return j
def b(z):
k = 5
if z == 0:
c()
return k + z
def c():
error()
a()
```
```pytb
Traceback (most recent call last):
File "file.py", line 15, in
a()
File "file.py", line 3, in a
j = b(i)
File "file.py", line 9, in b
c()
File "file.py", line 13, in c
error()
NameError: name 'error' is not defined
```
스택 추적은 오류가 발생한 위치(`c` 함수)를 보여준다. 또한 `c` 함수가 `b`에 의해 호출되었고, `b`가 `a`에 의해 호출되었으며, `a`는 프로그램의 15번째 줄(마지막 줄)에 있는 코드에 의해 호출되었음을 보여준다. 이 세 함수 각각에 대한 활성 레코드는 `a` 함수가 스택의 맨 아래를 차지하고 `c` 함수가 스택의 맨 위를 차지하도록 스택에 정렬된다.[1]
3. 6. Rust
Rust에는 두 가지 유형의 오류가 있다. panic 매크로를 사용하는 함수는 "복구 불가능"하며 현재 스레드는 스택 풀림을 경험하면서 손상된다. `std::result::Result`를 반환하는 함수는 "복구 가능"하며 적절하게 처리할 수 있다.[9] 그러나 복구 가능한 오류는 런타임 오류의 결과가 아닌 수동으로 추가되기 때문에 스택 추적을 생성할 수 없다.2021년 6월 현재, Rust는 복구 불가능한 오류에 대한 스택 추적을 실험적으로 지원한다. 러스트는 스레드가 패닉할 때 stderr에 출력을 지원하지만, `RUST_BACKTRACE` 환경 변수를 설정하여 활성화해야 한다.[10]
활성화되면 이러한 백트레이스는 가장 최근 호출이 먼저 표시되어 아래와 유사하게 표시된다.
```text
thread 'main' panicked at 'execute_to_panic', main.rs:3
stack backtrace:
0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
1: std::panicking::default_hook::
2: std::panicking::default_hook
3: std::panicking::rust_panic_with_hook
4: std::panicking::begin_panic
5: futures::task_impl::with
6: futures::task_impl::park
...
참조
[1]
웹사이트
libc manual: backtraces
https://www.gnu.org/[...]
gnu.org
2014-07-08
[2]
웹사이트
traceback — Print or retrieve a stack traceback
https://docs.python.[...]
python.org
2014-07-08
[3]
웹사이트
Thread (Java SE 16 & JDK 16)
https://docs.oracle.[...]
2021-03-04
[4]
웹사이트
Environment.StackTrace Property (System)
https://docs.microso[...]
2021-05-07
[5]
웹사이트
Thread (Java Platform SE 8 )
https://docs.oracle.[...]
2021-06-15
[6]
웹사이트
Backtraces (The GNU C Library)
https://www.gnu.org/[...]
2021-06-15
[7]
웹사이트
Getting Started - 1.76.0
https://www.boost.or[...]
2021-06-15
[8]
웹사이트
Working Draft, Standard for Programming Language C++
http://open-std.org/[...]
ISO/IEC
2021-10-23
[9]
웹사이트
rustonomicon unwinding - Rust
https://doc.rust-lan[...]
[10]
웹사이트
std::backtrace - Rust
https://doc.rust-lan[...]
2021-06-15
[11]
웹사이트
libc manual: backtraces
https://www.gnu.org/[...]
gnu.org
2014-07-08
[12]
웹사이트
traceback — Print or retrieve a stack traceback
https://docs.python.[...]
python.org
2014-07-08
[13]
웹사이트
Examining the Stack Trace - Windows drivers
https://learn.micros[...]
[14]
웹사이트
デバッガーで呼び出し履歴を表示する - Visual Studio (Windows)
https://learn.micros[...]
[15]
웹사이트
Throwable (Java Platform SE 8 )
https://docs.oracle.[...]
[16]
웹사이트
Environment.StackTrace Property (System)
https://learn.micros[...]
[17]
웹사이트
Exception.StackTrace Property (System)
https://learn.micros[...]
[18]
웹사이트
Chapter 35. Boost.Stacktrace 1.0 - 1.82.0
https://www.boost.or[...]
[19]
웹사이트
basic_stacktrace - cpprefjp C++日本語リファレンス
https://cpprefjp.git[...]
[20]
웹사이트
console.trace() - Web API | MDN
https://developer.mo[...]
[21]
웹인용
libc manual: backtraces
http://www.gnu.org/s[...]
gnu.org
2014-07-08
[22]
웹인용
traceback — Print or retrieve a stack traceback
https://docs.python.[...]
python.org
2014-07-08
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
문의하기 : help@durumis.com