サブロウ丸

Sabrou-mal サブロウ丸

主にプログラミングと数学

スタックトレース; Python & C++

スタックトレースとは、実行していた関数やメソッドなどの履歴のことです。バグやエラーが発生した際にスタックトレースを表示させることでデバッグを行いやすくします。

Python

tmp.py

f = lambda: g()
g = lambda: h()
h = lambda: i()
def i():
    return 2/0

f()

について、python tmp.py実行時に表示される

Traceback (most recent call last):
  File "/hoge/debug/tmp.py", line 6, in <module>
    f()
  File "/hoge/debug/tmp.py", line 1, in <lambda>
    f = lambda: g()
  File "/hoge/debug/tmp.py", line 2, in <lambda>
    g = lambda: h()
  File "/hoge/debug/tmp.py", line 3, in <lambda>
    h = lambda: i()
  File "/hoge/debug/tmp.py", line 4, in <lambda>
    return 2/0
ZeroDivisionError: division by zero

スタックトレースPythonでこれを任意の箇所で表示するには、Python標準のtracebackモジュールを使用します。

f = lambda: g()
g = lambda: h()
h = lambda: i()

def i():
    import traceback
    traceback.print_stack()

C++

C++23からbasic_stacktraceが用意されているようですが、より古い標準システムを用いている方は多いと思います。

その場合はboostのstacktraceを用いるのが楽です。Getting Started - 1.65.0

ここの例にあるように

#include <boost/stacktrace.hpp>

// ... somewhere inside the `bar(int)` function that is called recursively:
std::cout << boost::stacktrace::stacktrace();

スタックトレースを表示したい箇所にこれを書き加えるだけ。CMakeを用いている場合は

find_package(Boost REQUIRED)

# ...

target_include_directories(
  hoge PRIVATE
  # ...
  ${Boost_INCLUDE_DIR}
  )

これを付け加えばOkです。このとき

//lib/x86_64-linux-gnu/libdl.so.2: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
src/CMakeFiles/hoge.dir/build.make:123: recipe for target 'src/hoge' failed
make[2]: *** [src/hoge] Error 1
make[2]: Leaving directory '/hogehoge/build/temp.linux-x86_64-3.10/hoge'
CMakeFiles/Makefile2:204: recipe for target 'src/CMakeFiles/hoge.dir/all' failed
make[1]: *** [src/CMakeFiles/hoge.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
make[2]: Leaving directory '/hogehoge/build/temp.linux-x86_64-3.10/hoge'
[ 92%] Built target optcast
make[1]: Leaving directory '/hogehoge/build/temp.linux-x86_64-3.10/hoge'
Makefile:93: recipe for target 'all' failed
make: *** [all] Error 2

このようなエラーが出る場合は、リンクするライブラリへCMAKE_DL_LIBSの追加を試してみてください。

target_link_libraries(
  hoge PRIVATE
  # ...
  ${CMAKE_DL_LIBS}
  )

他にもライブラリはあるみたいなので、感想を聞かせてください。