1/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
2/* If you are missing that file, acquire a complete release at teeworlds.com. */
3
4#include "dbg.h"
5
6#include "logger.h"
7#include "system.h" // TODO: replace with str.h after moving str_format
8
9#include <atomic>
10#include <cstdarg>
11#include <cstdlib>
12
13std::atomic_bool dbg_assert_failing = false;
14DBG_ASSERT_HANDLER dbg_assert_handler;
15
16bool dbg_assert_has_failed()
17{
18 return dbg_assert_failing.load(m: std::memory_order_acquire);
19}
20
21void dbg_assert_imp(const char *filename, int line, const char *fmt, ...)
22{
23 const bool already_failing = dbg_assert_has_failed();
24 dbg_assert_failing.store(i: true, m: std::memory_order_release);
25 char msg[512];
26 va_list args;
27 va_start(args, fmt);
28 str_format_v(buffer: msg, buffer_size: sizeof(msg), format: fmt, args);
29 char error[1024];
30 str_format(buffer: error, buffer_size: sizeof(error), format: "%s(%d): %s", filename, line, msg);
31 va_end(args);
32 log_error("assert", "%s", error);
33 if(!already_failing)
34 {
35 DBG_ASSERT_HANDLER handler = dbg_assert_handler;
36 if(handler)
37 handler(error);
38 }
39 log_global_logger_finish();
40 dbg_break();
41}
42
43void dbg_break()
44{
45#ifdef __GNUC__
46 __builtin_trap();
47#else
48 abort();
49#endif
50}
51
52void dbg_assert_set_handler(DBG_ASSERT_HANDLER handler)
53{
54 dbg_assert_handler = std::move(handler);
55}
56
57void dbg_msg(const char *sys, const char *fmt, ...)
58{
59 va_list args;
60 va_start(args, fmt);
61 log_log_v(level: LEVEL_INFO, sys, fmt, args);
62 va_end(args);
63}
64