-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcrash_reporting.cpp
More file actions
132 lines (111 loc) · 4.48 KB
/
Copy pathcrash_reporting.cpp
File metadata and controls
132 lines (111 loc) · 4.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
//
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2025-Present Datadog, Inc.
#include "datadog/crash_reporting.h"
#include <cstdio>
#include <memory>
#include <string_view>
#include "datadog/core.h"
#include "datadog/c/core_glue.hpp"
#include "datadog/c/crash_reporting_glue.hpp"
#include "datadog/impl/core/core.hpp"
#include "datadog/impl/core/util/diagnostics.hpp"
#include "datadog/impl/crash_reporting/crash_handler.hpp"
#include "datadog/impl/crash_reporting/crash_handler_init.hpp"
#include "datadog/impl/crash_reporting/crash_reporting.hpp"
static const uint32_t CRASH_REPORTING_CONFIG_VERSION = 1;
static const dd_crash_reporting_config_t DEFAULT_CRASH_REPORTING_CONFIG = {
CRASH_REPORTING_CONFIG_VERSION, // version
"" // handler_exe_path (empty = auto-detect)
};
// This C API necessarily uses C-style idioms for memory management and strings.
// NOLINTBEGIN(cppcoreguidelines-owning-memory)
// NOLINTBEGIN(cppcoreguidelines-pro-type-vararg)
// NOLINTBEGIN(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
extern "C" {
void dd_crash_reporting_config_init(dd_crash_reporting_config_t* config) {
// Require an input value
if (!config) {
return;
}
*config = DEFAULT_CRASH_REPORTING_CONFIG;
}
void dd_crash_reporting_config_set_handler_exe_path(
dd_crash_reporting_config_t* config, const char* value
) {
if (config) {
if (value) {
std::snprintf(
config->handler_exe_path, sizeof(config->handler_exe_path), "%s", value
);
} else {
config->handler_exe_path[0] = '\0';
}
}
}
dd_crash_reporting_t* dd_crash_reporting_init(
dd_core_t* core, const dd_crash_reporting_config_t* config
) {
// Require a valid core: note that in the C API, where we tolerate null arguments to
// all API functions, returning NULL is effectively returning a no-op implementation
if (!core || !core->impl) {
return nullptr;
}
// If no config was given, use the default config
if (!config) {
config = &DEFAULT_CRASH_REPORTING_CONFIG;
}
// If we were given a config struct with an invalid version number, assume it was not
// properly initialized and fall back to the default config
if (config->version <= 0 || config->version > CRASH_REPORTING_CONFIG_VERSION) {
core->diagnostic_logger.Warning(
"dd_crash_reporting_init falling back to default config: application must "
"initialize dd_crash_reporting_config_t value via "
"dd_crash_reporting_config_init"
);
config = &DEFAULT_CRASH_REPORTING_CONFIG;
}
// Prepare a directory at <application-storage>/.datadog/.crashes/ to contain
// crash-related artifacts
auto storage = core->impl->InitializeArtifactStorage(".crashes");
if (!storage) {
return nullptr;
}
// Initialize an ICrashHandler implementation and get a pointer to the global handler
// instance, which persists throughout the lifetime of the process: this will only
// return a valid pointer the first time it's called, ensuring that only a single
// instance of the CrashReporting feature is empowered to handle and upload crashes
datadog::impl::ICrashHandler* handler = datadog::impl::CrashHandler::InitializeOnce(
core->diagnostic_logger,
core->impl->GetFilesystem(),
storage->GetPath(),
config->handler_exe_path
);
// If handler initialization failed, or if crash reporting is being enabled for an SDK
// instance after the first, return a no-op CrashReporting interface
if (!handler) {
return nullptr;
}
// Initialize our CrashReporting feature implementation
auto crash_reporting_impl = std::make_shared<datadog::impl::CrashReporting>(
*handler, core->impl->GetFilesystem(), storage->GetPath()
);
// Register the feature with the core, returning a no-op interface on failure
if (!core->impl->RegisterFeature(crash_reporting_impl)) {
return nullptr;
}
// Initialize and return the API object that represents our user-facing interface
// for the crash reporting feature
return new dd_crash_reporting(
std::move(crash_reporting_impl), core->diagnostic_logger
);
}
void dd_crash_reporting_destroy(dd_crash_reporting_t* crash_reporting) {
delete crash_reporting;
}
}
// NOLINTEND(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
// NOLINTEND(cppcoreguidelines-pro-type-vararg)
// NOLINTEND(cppcoreguidelines-owning-memory)