• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

realm / realm-core / thomas.goyne_113

27 Oct 2023 10:49AM UTC coverage: 91.596% (+0.03%) from 91.571%
thomas.goyne_113

push

Evergreen

web-flow
Merge pull request #7085 from realm/release/13.23.2

Release/13.23.2

91788 of 168244 branches covered (0.0%)

230165 of 251282 relevant lines covered (91.6%)

6444552.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/realm/util/terminate.cpp
1
/*************************************************************************
2
 *
3
 * Copyright 2016 Realm Inc.
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 * http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 **************************************************************************/
18

19
#include <realm/util/terminate.hpp>
20

21
#include <iostream>
22
#include <sstream>
23
#include <realm/util/features.h>
24
#include <realm/util/thread.hpp>
25
#include <realm/util/backtrace.hpp>
26
#include <realm/version.hpp>
27

28
#if REALM_PLATFORM_APPLE
29

30
#include <os/log.h>
31
#include <asl.h>
32

33
#include <dlfcn.h>
34
#include <execinfo.h>
35
#include <CoreFoundation/CoreFoundation.h>
36
#endif
37

38
#if REALM_ANDROID
39
#include <android/log.h>
40
#endif
41

42
// extern "C" and noinline so that a readable message shows up in the stack trace
43
// of the crash
44
// prototype here to silence warning
45
// The macro indirection here puts the core version number in the actual stack trace
46

47
// LCOV_EXCL_START
48
#define REALM_DEFINE_TERMINATE_VERSIONED_(x)                                                                         \
49
    extern "C" REALM_NORETURN REALM_NOINLINE void please_report_this_issue_in_github_realm_realm_core_v##x();        \
50
                                                                                                                     \
51
    extern "C" REALM_NORETURN REALM_NOINLINE void please_report_this_issue_in_github_realm_realm_core_v##x()         \
×
52
    {                                                                                                                \
×
53
        std::abort();                                                                                                \
×
54
    }
55

56
#define REALM_DEFINE_TERMINATE_VERSIONED(x) REALM_DEFINE_TERMINATE_VERSIONED_(x)
57
#define REALM_EVALUATE_(x) _##x
58
#define REALM_EVALUATE(x) REALM_EVALUATE_(x)
59
#define REALM_MACRO_CONCAT(A, B) REALM_MACRO_CONCAT_(A, B)
60
#define REALM_MACRO_CONCAT_(A, B) A##B
61
#define REALM_VERSION_SUFFIX_CONCAT                                                                                  \
62
    REALM_MACRO_CONCAT(REALM_EVALUATE(REALM_VERSION_MAJOR),                                                          \
63
                       REALM_MACRO_CONCAT(REALM_EVALUATE(REALM_VERSION_MINOR), REALM_EVALUATE(REALM_VERSION_PATCH)))
64

65
REALM_DEFINE_TERMINATE_VERSIONED(REALM_VERSION_SUFFIX_CONCAT)
66

×
67
#define REALM_TERMINATE_VERSIONED_(x) please_report_this_issue_in_github_realm_realm_core_v##x()
×
68
#define REALM_TERMINATE_VERSIONED(x) REALM_TERMINATE_VERSIONED_(x)
×
69
#define REALM_TERMINATE_AUTO_VERSIONED() REALM_TERMINATE_VERSIONED(REALM_VERSION_SUFFIX_CONCAT)
70

71
// LCOV_EXCL_STOP
72

73
namespace {
74

75
#if REALM_PLATFORM_APPLE
76
void nslog(const char* message) noexcept
77
{
78
    // Standard error goes nowhere for applications managed by launchd,
79
    // so log to ASL/unified logging system logs as well.
80
    fputs(message, stderr);
81
    if (__builtin_available(iOS 10.0, macOS 10.12, tvOS 10.0, watchOS 3.0, *)) {
82
        // The unified logging system considers dynamic strings to be private in
83
        // order to protect users. This means we must specify "%{public}s" to get
84
        // the message here. See `man os_log` for more details.
85
        os_log_error(OS_LOG_DEFAULT, "%{public}s", message);
86
    }
87
    else {
88
        REALM_DIAG_PUSH();
×
89
        REALM_DIAG(ignored "-Wdeprecated");
90
        asl_log(nullptr, nullptr, ASL_LEVEL_ERR, "%s", message);
91
        REALM_DIAG_POP();
92
    }
93
    // Log the message to Crashlytics if it's loaded into the process
94
    void* addr = dlsym(RTLD_DEFAULT, "CLSLog");
95
    if (addr) {
96
        CFStringRef str =
97
            CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, message, kCFStringEncodingUTF8, kCFAllocatorNull);
98
        auto fn = reinterpret_cast<void (*)(CFStringRef, ...)>(reinterpret_cast<size_t>(addr));
99
        fn(CFSTR("%@"), str);
100
        CFRelease(str);
101
    }
102
}
103

104
void (*termination_notification_callback)(const char*) noexcept = nslog;
105

106
#elif REALM_ANDROID
107

108
void android_log(const char* message) noexcept
109
{
110
    __android_log_write(ANDROID_LOG_ERROR, "REALM", message);
111
}
112

113
void (*termination_notification_callback)(const char*) noexcept = android_log;
114

115
#else
116

117
void (*termination_notification_callback)(const char*) noexcept = nullptr;
118

119
#endif
120

121
} // unnamed namespace
×
122

×
123
namespace realm {
124
namespace util {
×
125

126
// LCOV_EXCL_START
×
127
REALM_NORETURN static void terminate_internal(std::stringstream& ss) noexcept
×
128
{
×
129
    util::Backtrace::capture().print(ss);
×
130

×
131
    ss << "\n!!! IMPORTANT: Please report this at https://github.com/realm/realm-core/issues/new/choose";
×
132

×
133
    if (termination_notification_callback) {
×
134
        termination_notification_callback(ss.str().c_str());
×
135
    }
136
    else {
×
137
        std::cerr << ss.rdbuf();
×
138
        std::string thread_name;
139
        if (Thread::get_name(thread_name))
140
            std::cerr << "\nThread name: " << thread_name;
141
    }
×
142

×
143
    REALM_TERMINATE_AUTO_VERSIONED();
×
144
}
145

146
REALM_NORETURN void terminate(const char* message, const char* file, long line,
×
147
                              std::initializer_list<Printable>&& values) noexcept
×
148
{
×
149
    terminate_with_info(message, file, line, nullptr, std::move(values));
150
}
151

152
REALM_NORETURN void terminate_with_info(const char* message, const char* file, long line,
153
                                        const char* interesting_names,
×
154
                                        std::initializer_list<Printable>&& values) noexcept
×
155
{
×
156
    std::stringstream ss;
×
157
    ss << file << ':' << line << ": " REALM_VER_CHUNK " " << message;
×
158
    if (interesting_names)
×
159
        ss << " with " << interesting_names << " = ";
×
160
    Printable::print_all(ss, values, bool(interesting_names));
×
161
    ss << '\n';
×
162
    terminate_internal(ss);
163
}
164
// LCOV_EXCL_STOP
165

166
} // namespace util
167
} // namespace realm
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc