@@ -16,15 +16,12 @@
#include <signal.h>
#include <sys/utsname.h>
#if defined(__GLIBC__)
/* Execinfo (and thus making stacktraces) is a GNU extension */
# include <execinfo.h>
#elif defined(SUNOS)
# include <ucontext.h>
# include <dlfcn.h>
#endif
#if defined(__NetBSD__)
#include <unistd.h>
@@ -67,65 +64,24 @@ class CrashLogUnix : public CrashLog {
strsignal(this->signum),
this->signum,
message
);
}
#if defined(SUNOS)
/** Data needed while walking up the stack */
struct StackWalkerParams {
std::back_insert_iterator<std::string> *output_iterator; ///< Buffer
int counter; ///< We are at counter-th stack level
};
/**
* Callback used while walking up the stack.
* @param pc program counter
* @param sig 'active' signal (unused)
* @param params parameters
* @return always 0, continue walking up the stack
*/
static int SunOSStackWalker(uintptr_t pc, int sig, void *params)
{
StackWalkerParams *wp = (StackWalkerParams *)params;
/* Resolve program counter to file and nearest symbol (if possible) */
Dl_info dli;
if (dladdr((void *)pc, &dli) != 0) {
fmt::format_to(*wp->output_iterator, " [{:02}] {}({}+0x{:x}) [0x{:x}]\n",
wp->counter, dli.dli_fname, dli.dli_sname, (int)((byte *)pc - (byte *)dli.dli_saddr), (uint)pc);
} else {
fmt::format_to(*wp->output_iterator, " [{:02}] [0x{:x}]\n", wp->counter, (uint)pc);
wp->counter++;
return 0;
void LogStacktrace(std::back_insert_iterator<std::string> &output_iterator) const override
fmt::format_to(output_iterator, "Stacktrace:\n");
void *trace[64];
int trace_size = backtrace(trace, lengthof(trace));
char **messages = backtrace_symbols(trace, trace_size);
for (int i = 0; i < trace_size; i++) {
fmt::format_to(output_iterator, " [{:02}] {}\n", i, messages[i]);
free(messages);
ucontext_t uc;
if (getcontext(&uc) != 0) {
fmt::format_to(output_iterator, " getcontext() failed\n\n");
return buffer;
StackWalkerParams wp = { &output_iterator, 0 };
walkcontext(&uc, &CrashLogUnix::SunOSStackWalker, &wp);
#else
fmt::format_to(output_iterator, " Not supported.\n");
fmt::format_to(output_iterator, "\n");
public:
@@ -39,20 +39,14 @@
/* It seems that we need to include stdint.h before anything else
* We need INT64_MAX, which for most systems comes from stdint.h. However, MSVC
* does not have stdint.h.
* For OSX the inclusion is already done in osx_stdafx.h. */
#if !defined(__APPLE__) && (!defined(_MSC_VER) || _MSC_VER >= 1600)
# if defined(SUNOS)
/* SunOS/Solaris does not have stdint.h, but inttypes.h defines everything
* stdint.h defines and we need. */
# include <inttypes.h>
# else
# define __STDC_LIMIT_MACROS
# include <stdint.h>
# endif
#include <algorithm>
#include <array>
#include <cassert>
#include <cctype>
Status change: