diff --git a/src/daemon/daemon-shutdown.c b/src/daemon/daemon-shutdown.c index 0a2c7697d0..29fa7f1a81 100644 --- a/src/daemon/daemon-shutdown.c +++ b/src/daemon/daemon-shutdown.c @@ -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 } diff --git a/src/daemon/main.c b/src/daemon/main.c index c874064b91..96bde5ab73 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -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]; diff --git a/src/daemon/signal-handler.c b/src/daemon/signal-handler.c index ee9cd03499..67b57571e9 100644 --- a/src/daemon/signal-handler.c +++ b/src/daemon/signal-handler.c @@ -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); diff --git a/src/database/contexts/api_v2_contexts_alerts.c b/src/database/contexts/api_v2_contexts_alerts.c index fcfe56b6d4..efe4bb38dc 100644 --- a/src/database/contexts/api_v2_contexts_alerts.c +++ b/src/database/contexts/api_v2_contexts_alerts.c @@ -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, diff --git a/src/database/rrd.c b/src/database/rrd.c index f5c12fb06a..e1eaa8bc80 100644 --- a/src/database/rrd.c +++ b/src/database/rrd.c @@ -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; diff --git a/src/database/rrdhost-system-info.c b/src/database/rrdhost-system-info.c index beb4e7349a..8b6fda90cd 100644 --- a/src/database/rrdhost-system-info.c +++ b/src/database/rrdhost-system-info.c @@ -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 diff --git a/src/database/rrdhost-system-info.h b/src/database/rrdhost-system-info.h index f2062be1ab..dd4bcf7abd 100644 --- a/src/database/rrdhost-system-info.h +++ b/src/database/rrdhost-system-info.h @@ -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 diff --git a/src/database/rrdhost.c b/src/database/rrdhost.c index 31cb55fd32..01342b94ad 100644 --- a/src/database/rrdhost.c +++ b/src/database/rrdhost.c @@ -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; } diff --git a/src/database/sqlite/sqlite_aclk.c b/src/database/sqlite/sqlite_aclk.c index ae30b30b36..1eae4b1a62 100644 --- a/src/database/sqlite/sqlite_aclk.c +++ b/src/database/sqlite/sqlite_aclk.c @@ -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); diff --git a/src/plugins.d/pluginsd_parser.c b/src/plugins.d/pluginsd_parser.c index 9effb42790..643d5dcf2e 100644 --- a/src/plugins.d/pluginsd_parser.c +++ b/src/plugins.d/pluginsd_parser.c @@ -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); diff --git a/src/streaming/stream-receiver-connection.c b/src/streaming/stream-receiver-connection.c index 675453cec6..7d85a26ca0 100644 --- a/src/streaming/stream-receiver-connection.c +++ b/src/streaming/stream-receiver-connection.c @@ -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) {