1 year ago
#339190
Steve Lorimer
Is it possible to generate a stacktrace with valid frame symbols / function names?
I am trying to generate a stacktrace at the point in which an exception is thrown.
To do so, I have a custom exception class which stores the current stacktrace as a member, allowing me to log it when the exception is caught.
class generic_error : public std::runtime_error
{
public:
generic_error(const char* err)
: std::runtime_error{err}
, stacktrace_{utl::stacktrace()}
{}
const std::string& stacktrace() const
{
return stacktrace_;
}
private:
std::string stacktrace_;
};
I am using backtrace
and backtrace_symbols
together with abi::__cxa_demangle
, but am getting many stack frames without an address from which I can obtain a function name etc.
I have also tried to use boost::stacktrace
in case it was a mistake in my implentation, but to no evail.
In both cases I get a stacktrace with many empty frames (eg: frame 3-12 and 14-17 below)
0# utl:stacktrace[abi:cxx11]() in ./test_app
1# app::generic_error::generic_error(char const*) in ./test_app
2# app::exception_factory::create(const char*) in ./test_app
3# 0x00000000027329FA in ./test_app
4# 0x0000000002732B06 in ./test_app
5# 0x0000000002747FC7 in ./test_app
6# 0x000000000273FEAE in ./test_app
7# 0x0000000002732CF3 in ./test_app
8# 0x0000000002732D3E in ./test_app
9# 0x0000000002732D7B in ./test_app
10# 0x000000000272BEF5 in ./test_app
11# 0x0000000002732DA5 in ./test_app
12# 0x0000000002732DCD in ./test_app
13# stdext::inplace_function<void (std::ostream&), 4608ul, 16ul>::operator()(std::ostream&) const in ./test_app
14# 0x000000000275F523 in ./test_app
15# 0x0000000002759927 in ./test_app
16# 0x0000000002755BDE in ./test_app
17# 0x0000000002759AE5 in ./test_app
18# boost::asio::detail::scheduler_operation::complete(void*, boost::system::error_code const&, unsigned long) in ./test_app
19# boost::asio::detail::scheduler::do_run_one(boost::asio::detail::conditionally_enabled_mutex::scoped_lock&, boost::asio::detail::scheduler_thread_info&, boost::system::error_code const&) in ./test_app
20# boost::asio::detail::scheduler::run(boost::system::error_code&) in ./test_app
21# boost::asio::io_context::run() in ./test_app
I am building in debug mode (
-g
)I have no optimistaion flag (
-On
) presentI also have
-ggdb3
flag set.I have
-rdynamic
linker flag setI am linking
-ldl
I have ensured that I do not have
-fvisibility=hidden
etc in my compiler flags.I have
-fno-omit-frame-pointer
set
Questions:
Given I have debug symbols present in my binary, why does my stacktrace not work?
I am 99% confident I have had success with my approach before, so I'm thinking this must be due to the visibility changes in gcc?
I see there is a std::stracktrace
utility being added in C++23, and the notes make reference to boost::stacktrace::basic_stacktrace
, which suggest boost::stracktrace
is a reference implementation... however, given boost::stracktrace
is not working for me, what would std::stacktrace
do differently to make it work?
Were I to load my app in gdb
for example, gdb would have access to the full stack, so presumably it must be possible to obtain the full call stack? Is there an alternative method of obtaining stacktrace symbols?
c++
gcc
stack-trace
0 Answers
Your Answer