Coverage Report

Created: 2026-08-24 19:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
src/util/assert.cpp
Line
Count
Source
1
#include <silk/util/assert.h>
2
3
#include <silk/util/platform.h>
4
5
#include <cstdarg>
6
#include <cstdio>
7
#include <cstdlib>
8
#include <cstring>
9
10
#if defined(SILK_USE_LIBBACKTRACE)
11
#    include <backtrace.h>
12
#    include <cxxabi.h>
13
#endif // SILK_USE_LIBBACKTRACE
14
15
0
#define COLOR_RESET "\033[0m"
16
0
#define COLOR_RED "\033[1;31m"
17
0
#define COLOR_YELLOW "\033[0;33m"
18
#define COLOR_GREEN "\033[0;32m"
19
20
namespace silk
21
{
22
23
#if defined(SILK_USE_LIBBACKTRACE)
24
25
static void btCreateErrorCallback(void * data, const char * msg, int err) noexcept
26
0
{
27
0
    SILK_UNUSED(data);
28
0
    std::fprintf(stderr, "backtrace_create_state error %d: %s\n", err, msg);
29
0
}
30
31
static backtrace_state * btState = backtrace_create_state(nullptr, 1, btCreateErrorCallback, nullptr);
32
33
struct Context
34
{
35
    int frame = 0;
36
};
37
38
static int btCallback(void * data, uintptr_t pc, const char * filename, int lineno, const char * function) noexcept
39
0
{
40
0
    Context * ctx = static_cast<Context *>(data);
41
0
    std::fprintf(stderr, "#%d  %#018lx in " COLOR_YELLOW, ctx->frame++, static_cast<unsigned long>(pc));
42
43
0
    int status = 0;
44
0
    char * demangled = function ? abi::__cxa_demangle(function, nullptr, nullptr, &status) : nullptr;
45
0
    if (demangled && status == 0)
46
0
    {
47
0
        const char * paren = std::strrchr(demangled, '(');
48
0
        if (paren)
49
0
        {
50
0
            std::fwrite(demangled, 1, static_cast<size_t>(paren - demangled), stderr);
51
0
            std::fprintf(stderr, COLOR_RESET " %s", paren);
52
0
        }
53
0
        else
54
0
        {
55
0
            std::fprintf(stderr, "%s" COLOR_RESET " ()", demangled);
56
0
        }
57
0
    }
58
0
    else
59
0
    {
60
0
        std::fprintf(stderr, "%s" COLOR_RESET " ()", function ? function : "??");
61
0
    }
62
63
0
    if (filename)
64
0
    {
65
0
        std::fprintf(stderr, " at " COLOR_GREEN "%s" COLOR_RESET ":%d", filename, lineno);
66
0
    }
67
0
    std::fputc('\n', stderr);
68
69
0
    std::free(demangled);
70
0
    return 0;
71
0
}
72
73
static void btErrorCallback(void * data, const char * msg, int err) noexcept
74
0
{
75
0
    SILK_UNUSED(data);
76
0
    std::fprintf(stderr, "  backtrace error %d: %s\n", err, msg);
77
0
}
78
79
#endif // SILK_USE_LIBBACKTRACE
80
81
void assertFail(const char * file, int line, const char * message, const char * fmt, ...) noexcept
82
0
{
83
0
    ::flockfile(stderr);
84
85
0
    std::fprintf(stderr, COLOR_RED "%s:%d ", file, line);
86
0
    if (message)
87
0
    {
88
0
        std::fputs(message, stderr);
89
0
    }
90
0
    if (fmt)
91
0
    {
92
0
        if (message)
93
0
        {
94
0
            std::fputs(" -- ", stderr);
95
0
        }
96
0
        va_list ap;
97
0
        va_start(ap, fmt);
98
0
        std::vfprintf(stderr, fmt, ap);
99
0
        va_end(ap);
100
0
    }
101
0
    std::fputs(COLOR_RESET "\n", stderr);
102
103
0
#if defined(SILK_USE_LIBBACKTRACE)
104
0
    Context ctx;
105
0
    backtrace_full(btState, 0, btCallback, btErrorCallback, &ctx);
106
0
#endif
107
108
0
    ::funlockfile(stderr);
109
110
    std::fflush(stderr);
111
0
    std::abort();
112
0
}
113
114
} // namespace silk
115
116
#undef COLOR_RESET
117
#undef COLOR_RED
118
#undef COLOR_YELLOW
119
#undef COLOR_GREEN