Visual Studio 2022 의 최신 C++ 도입내용을 살펴보다 반가운 내용이 있어 오랜만에 블로그를 열었다.
드디어 콜스택을 확인할 수 있는 헤더를 VS에서 사용할 수 있게 되었다.
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p0881r7.html
C++에서 콜스택을 로깅하려면 각 운영체제 별로 제공하는 API를 통해 StackWalker 를 별도로 구현해야했다.
이제 새로 C++를 배우시는 학생분들은 이러한 어려움에서 한발 벗어날 수 있을 것으로 보이고,
가르치는 사람 입장에서도 콜스택을 보다 빠른 시점에 직관적으로 가르칠 수 있을 것으로 보인다.
stacktrace 사용법
사용법은 간단하다.
먼저 VS2022 C++프로젝트에서, 프로젝트 속성의 C++ 언어 표준을 /std:c++latest 로 설정한다.
그리고 stacktrace 헤더를 포함시킨 뒤 다음과 같이 함수 하나만 호출해주면 된다.
std::stacktrace::current()
#include <iostream>
#include <stacktrace>
int main()
{
std::stacktrace callstack = std::stacktrace::current();
std::cout << callstack << std::endl;
}
그러면 다음과 같이 콜스택 정보를 바로 확인할 수 있다.
std::to_string() 등으로 문자열로 변환하여 로깅하면
문제되는 상황의 콜스택을 쉽게 로깅할 수 있을 것이다.
결과 :
0> C:\source\repos\CppPractice\CppPractice\stacktrace.cpp(6): CppPractice!main+0x63
1> D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(79): CppPractice!invoke_main+0x39
2> D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(288): CppPractice!__scrt_common_main_seh+0x12E
3> D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(331): CppPractice!__scrt_common_main+0xE
4> D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp(17): CppPractice!mainCRTStartup+0xE
5> KERNEL32!BaseThreadInitThunk+0x10
6> ntdll!RtlUserThreadStart+0x2B
응용
std::stacktrace 는 다음과 같이 stacktrace_entry 의 스트림이다.
using stacktrace = basic_stacktrace<allocator<stacktrace_entry>>;
따라서 다음과 같이 콜스택을 순회하며, 필요한 정보만을 기입할 수도 있다.
#include <iostream>
#include <stacktrace>
int main()
{
std::stacktrace callstack = std::stacktrace::current();
for (auto& entry : callstack)
{
std::cout << "source_file : " << entry.source_file() << std::endl;
std::cout << "source_line : " << entry.source_line() << std::endl;
std::cout << "description : " << entry.description() << std::endl;
std::cout << "-----------" << std::endl;
}
}
결과 :
source_file : C:\source\repos\CppPractice\CppPractice\stacktrace.cpp
source_line : 6
description : CppPractice!main+0x63
-----------
source_file : D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl
source_line : 79
description : CppPractice!invoke_main+0x39
-----------
source_file : D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl
source_line : 288
description : CppPractice!__scrt_common_main_seh+0x12E
-----------
source_file : D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl
source_line : 331
description : CppPractice!__scrt_common_main+0xE
-----------
source_file : D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp
source_line : 17
description : CppPractice!mainCRTStartup+0xE
-----------
source_file :
source_line : 0
description : KERNEL32!BaseThreadInitThunk+0x10
-----------
source_file :
source_line : 0
description : ntdll!RtlUserThreadStart+0x2B
-----------
보다 자세한 내용은 다음의 문서에서 확인할 수 있다.
https://en.cppreference.com/w/cpp/header/stacktrace
'C++' 카테고리의 다른 글
C++20 : std::ranges #3 - range 를 컨테이너로 변환하기 (0) | 2021.03.24 |
---|---|
C++20 : std::ranges #2 - iota_view 만들기 (0) | 2021.03.22 |
C++20 : std::ranges #1 - views (0) | 2021.03.17 |
C++ : shrink_to_fit() (1) | 2020.12.13 |
L1 캐시는 왜 Data와 Inst로 나뉘어 있나요? (번역) (0) | 2020.12.13 |