0
0
Fork 0
mirror of https://github.com/netdata/netdata.git synced 2025-04-23 13:00:23 +00:00

Fix LSAN and memory leaks ()

* add SIGUSR1 for exiting immediately, so that LSAN can check for leaks

* fix system info leak

* adapt to changed semantics of rrdhost system_info

* fix memory leak in rrdcontexts when matching alerts

* do not system info after it was freed

* allow sentry to send its reports
This commit is contained in:
Costa Tsaousis 2025-03-10 13:44:57 +00:00 committed by GitHub
parent e3484260d3
commit ec48ad55ef
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 46 additions and 27 deletions

View file

@ -318,12 +318,12 @@ void netdata_cleanup_and_exit(EXIT_REASON reason, const char *action, const char
watcher_shutdown_end();
watcher_thread_stop();
curl_global_cleanup();
daemon_status_file_shutdown_step(NULL);
daemon_status_file_update_status(DAEMON_STATUS_EXITED);
#ifdef OS_WINDOWS
curl_global_cleanup();
return;
#endif
@ -335,12 +335,15 @@ void netdata_cleanup_and_exit(EXIT_REASON reason, const char *action, const char
abort();
} else {
nd_sentry_fini();
curl_global_cleanup();
exit(ret);
}
#else
if(ret)
_exit(ret);
else
else {
curl_global_cleanup();
exit(ret);
}
#endif
}

View file

@ -1026,20 +1026,19 @@ int netdata_main(int argc, char **argv) {
struct rrdhost_system_info *system_info = rrdhost_system_info_create();
rrdhost_system_info_detect(system_info);
// ----------------------------------------------------------------------------------------------------------------
delta_startup_time("install type");
get_install_type(system_info);
set_late_analytics_variables(system_info);
// ----------------------------------------------------------------------------------------------------------------
delta_startup_time("RRD structures");
abort_on_fatal_disable();
if(rrd_init(netdata_configured_hostname, system_info, false)) {
set_late_analytics_variables(system_info);
if (rrd_init(netdata_configured_hostname, system_info, false))
fatal("Cannot initialize localhost instance with name '%s'.", netdata_configured_hostname);
}
abort_on_fatal_enable();
system_info = NULL; // system_info is now freed by rrd_init
// ----------------------------------------------------------------------------------------------------------------
delta_startup_time("localhost labels");
@ -1064,7 +1063,6 @@ int netdata_main(int argc, char **argv) {
netdata_conf_section_web();
set_late_analytics_variables(system_info);
for (i = 0; static_threads[i].name != NULL ; i++) {
struct netdata_static_thread *st = &static_threads[i];

View file

@ -6,6 +6,9 @@
typedef enum signal_action {
NETDATA_SIGNAL_IGNORE,
NETDATA_SIGNAL_EXIT_CLEANLY,
#if defined(FSANITIZE_ADDRESS)
NETDATA_SIGNAL_EXIT_NOW,
#endif
NETDATA_SIGNAL_REOPEN_LOGS,
NETDATA_SIGNAL_RELOAD_HEALTH,
NETDATA_SIGNAL_DEADLY,
@ -23,6 +26,9 @@ static struct {
{ SIGQUIT, "SIGQUIT", 0, NETDATA_SIGNAL_EXIT_CLEANLY, EXIT_REASON_SIGQUIT },
{ SIGTERM, "SIGTERM", 0, NETDATA_SIGNAL_EXIT_CLEANLY, EXIT_REASON_SIGTERM },
{ SIGHUP, "SIGHUP", 0, NETDATA_SIGNAL_REOPEN_LOGS, EXIT_REASON_NONE },
#if defined(FSANITIZE_ADDRESS)
{ SIGUSR1, "SIGUSR1", 0, NETDATA_SIGNAL_EXIT_NOW, EXIT_REASON_NONE },
#endif
{ SIGUSR2, "SIGUSR2", 0, NETDATA_SIGNAL_RELOAD_HEALTH, EXIT_REASON_NONE },
{ SIGBUS, "SIGBUS", 0, NETDATA_SIGNAL_DEADLY, EXIT_REASON_SIGBUS },
{ SIGSEGV, "SIGSEGV", 0, NETDATA_SIGNAL_DEADLY, EXIT_REASON_SIGSEGV },
@ -38,6 +44,11 @@ static void signal_handler(int signo) {
signals_waiting[i].count++;
#if defined(FSANITIZE_ADDRESS)
if(signals_waiting[i].action == NETDATA_SIGNAL_EXIT_NOW)
exit(1);
#endif
if(signals_waiting[i].action == NETDATA_SIGNAL_DEADLY) {
// Update the status file
daemon_status_file_deadly_signal_received(signals_waiting[i].reason);

View file

@ -123,9 +123,10 @@ bool rrdcontext_matches_alert(struct rrdcontext_to_json_v2_data *ctl, RRDCONTEXT
sizeof(struct alert_by_x_entry),
rcl);
char *module = NULL;
rrdlabels_get_value_strdup_or_null(st->rrdlabels, &module, "_collect_module");
if(!module || !*module) module = "[unset]";
char module[128];
rrdlabels_get_value_strcpyz(st->rrdlabels, module, sizeof(module), "_collect_module");
if(!*module)
strncpyz(module, "[unset]", sizeof(module) - 1);
dictionary_set_advanced(ctl->alerts.by_module,
module,

View file

@ -142,6 +142,7 @@ int rrd_init(const char *hostname, struct rrdhost_system_info *system_info, bool
, 1
, 0
);
rrdhost_system_info_free(system_info);
if (unlikely(!localhost))
return 1;

View file

@ -8,6 +8,11 @@
// coverity[ +tainted_string_sanitize_content : arg-0 ]
static inline void coverity_remove_taint(char *s __maybe_unused) { }
void rrdhost_system_info_swap(struct rrdhost_system_info *a, struct rrdhost_system_info *b) {
if(a && b)
SWAP(*a, *b);
}
// ----------------------------------------------------------------------------
// RRDHOST - set system info from environment variables
// system_info fields must be heap allocated or NULL

View file

@ -100,5 +100,6 @@ void rrdhost_system_info_to_node_info(struct rrdhost_system_info *system_info, s
void rrdhost_system_info_to_streaming_function_array(BUFFER *wb, struct rrdhost_system_info *system_info);
void get_daemon_status_fields_from_system_info(DAEMON_STATUS_FILE *ds);
void rrdhost_system_info_swap(struct rrdhost_system_info *a, struct rrdhost_system_info *b);
#endif //NETDATA_RRDHOST_SYSTEM_INFO_H

View file

@ -368,7 +368,8 @@ RRDHOST *rrdhost_create(
rrdhost_set_replication_parameters(host, memory_mode, replication_period, replication_step);
host->system_info = system_info;
host->system_info = rrdhost_system_info_create();
rrdhost_system_info_swap(host->system_info, system_info);
rrdset_index_init(host);
@ -543,12 +544,8 @@ static void rrdhost_update(RRDHOST *host
host->health.enabled = (mode == RRD_DB_MODE_NONE) ? 0 : health;
{
struct rrdhost_system_info *old = host->system_info;
host->system_info = system_info;
rrdhost_flag_set(host, RRDHOST_FLAG_METADATA_INFO | RRDHOST_FLAG_METADATA_CLAIMID | RRDHOST_FLAG_METADATA_UPDATE);
rrdhost_system_info_free(old);
}
rrdhost_system_info_swap(host->system_info, system_info);
rrdhost_flag_set(host, RRDHOST_FLAG_METADATA_INFO | RRDHOST_FLAG_METADATA_CLAIMID | RRDHOST_FLAG_METADATA_UPDATE);
rrdhost_init_os(host, os);
rrdhost_init_timezone(host, timezone, abbrev_timezone, utc_offset);
@ -676,10 +673,8 @@ RRDHOST *rrdhost_find_or_create(
RRDHOST *host = rrdhost_find_by_guid(guid);
if (unlikely(host && host->rrd_memory_mode != mode && rrdhost_flag_check(host, RRDHOST_FLAG_ARCHIVED))) {
if (likely(!archived && rrdhost_flag_check(host, RRDHOST_FLAG_PENDING_CONTEXT_LOAD))) {
rrdhost_system_info_free(system_info);
if (likely(!archived && rrdhost_flag_check(host, RRDHOST_FLAG_PENDING_CONTEXT_LOAD)))
return host;
}
/* If a legacy memory mode instantiates all dbengine state must be discarded to avoid inconsistencies */
nd_log(NDLS_DAEMON, NDLP_INFO,
@ -748,9 +743,6 @@ RRDHOST *rrdhost_find_or_create(
, system_info);
}
if(!host)
rrdhost_system_info_free(system_info);
return host;
}

View file

@ -174,6 +174,8 @@ static int create_host_callback(void *data, int argc, char **argv, char **column
system_info,
1);
rrdhost_system_info_free(system_info);
if (likely(host)) {
if (is_ephemeral)
rrdhost_option_set(host, RRDHOST_OPTION_EPHEMERAL_HOST);

View file

@ -194,6 +194,8 @@ static inline PARSER_RC pluginsd_host_define_end(char **words __maybe_unused, si
if(!parser->user.host_define.parsing_host)
return PLUGINSD_DISABLE_PLUGIN(parser, PLUGINSD_KEYWORD_HOST_DEFINE_END, "missing initialization, send " PLUGINSD_KEYWORD_HOST_DEFINE " before this");
struct rrdhost_system_info *system_info = rrdhost_system_info_from_host_labels(parser->user.host_define.rrdlabels);
RRDHOST *host = rrdhost_find_or_create(
string2str(parser->user.host_define.hostname),
string2str(parser->user.host_define.hostname),
@ -215,9 +217,11 @@ static inline PARSER_RC pluginsd_host_define_end(char **words __maybe_unused, si
stream_receive.replication.enabled,
stream_receive.replication.period,
stream_receive.replication.step,
rrdhost_system_info_from_host_labels(parser->user.host_define.rrdlabels),
system_info,
false);
rrdhost_system_info_free(system_info);
rrdhost_option_set(host, RRDHOST_OPTION_VIRTUAL_HOST);
rrdhost_flag_set(host, RRDHOST_FLAG_COLLECTOR_ONLINE);
object_state_activate_if_not_activated(&host->state_id);

View file

@ -173,7 +173,8 @@ static bool stream_receiver_send_first_response(struct receiver_state *rpt) {
rpt->config.replication.step,
rpt->system_info,
0);
// IMPORTANT: system_info is now consumed!
rrdhost_system_info_free(rpt->system_info);
rpt->system_info = NULL;
if(!host) {