dncurrency/nano/lib/assert.cpp
2024-11-12 00:46:28 +01:00

49 lines
No EOL
1.6 KiB
C++

#include <nano/lib/assert.hpp>
#include <nano/lib/files.hpp>
#include <nano/lib/stacktrace.hpp>
#include <boost/dll/runtime_symbol_info.hpp>
#include <fstream>
#include <iostream>
/*
* Backing code for "release_assert" & "debug_assert", which are macros
*/
void assert_internal (char const * check_expr, char const * func, char const * file, unsigned int line, bool is_release_assert, std::string_view error_msg)
{
std::cerr << "Assertion (" << check_expr << ") failed\n"
<< func << "\n"
<< file << ":" << line << "\n";
if (!error_msg.empty ())
{
std::cerr << "Error: " << error_msg << "\n";
}
std::cerr << "\n";
// Output stack trace to cerr
auto backtrace_str = nano::generate_stacktrace ();
std::cerr << backtrace_str << std::endl;
// "abort" at the end of this function will go into any signal handlers (the daemon ones will generate a stack trace and load memory address files on non-Windows systems).
// As there is no async-signal-safe way to generate stacktraces on Windows it must be done before aborting
#ifdef _WIN32
{
// Try construct the stacktrace dump in the same folder as the running executable, otherwise use the current directory.
boost::system::error_code err;
auto running_executable_filepath = boost::dll::program_location (err);
std::string filename = is_release_assert ? "nano_node_backtrace_release_assert.txt" : "nano_node_backtrace_assert.txt";
std::string filepath = filename;
if (!err)
{
filepath = (running_executable_filepath.parent_path () / filename).string ();
}
std::ofstream file (filepath);
nano::set_secure_perm_file (filepath);
file << backtrace_str;
}
#endif
abort ();
}