Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 45 additions & 17 deletions src/flb_log.c
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,41 @@ struct flb_log_metrics *flb_log_metrics_create()
return metrics;
}

/*
* Release everything flb_log_create() has set up so far, for the failure
* paths that run after the channel manager pipe exists but before the
* collector thread is started. flb_log_destroy() cannot be used there: it
* joins log->tid and dereferences log->worker, neither of which is valid
* yet.
*/
static void log_create_cleanup(struct flb_log *log, struct flb_config *config)
{
flb_log_metrics_destroy(log->metrics);
flb_pipe_destroy(log->ch_mng);
log_close_sink(log);
pthread_mutex_destroy(&log->queue_mutex);
pthread_mutex_destroy(&log->pipeline_queue.mutex);
mk_event_loop_destroy(log->evl);
flb_free(log);
config->log = NULL;
}

Comment thread
coderabbitai[bot] marked this conversation as resolved.
/*
* Release the fake worker context flb_log_create() builds for the main
* thread. The thread-local pointer is cleared too, otherwise it would be
* left dangling for any later flb_log_create() attempt.
*/
static void log_create_worker_cleanup(struct flb_worker *worker)
{
if (worker->log_cache) {
flb_log_cache_destroy(worker->log_cache);
worker->log_cache = NULL;
}
flb_log_worker_destroy(worker);
flb_free(worker);
FLB_TLS_SET(flb_worker_ctx, NULL);
}

struct flb_log *flb_log_create(struct flb_config *config, int type,
int level, char *out)
{
Expand Down Expand Up @@ -1063,19 +1098,15 @@ struct flb_log *flb_log_create(struct flb_config *config, int type,

if (ret == -1) {
fprintf(stderr, "[log] could not register event\n");
mk_event_loop_destroy(log->evl);
flb_free(log);
config->log = NULL;
log_create_cleanup(log, config);
return NULL;
}

/* Create metrics */
log->metrics = flb_log_metrics_create();
if (log->metrics == NULL) {
fprintf(stderr, "[log] could not create log metrics\n");
mk_event_loop_destroy(log->evl);
flb_free(log);
config->log = NULL;
log_create_cleanup(log, config);
return NULL;
}

Expand All @@ -1087,9 +1118,8 @@ struct flb_log *flb_log_create(struct flb_config *config, int type,
worker = flb_worker_context_create(NULL, NULL, config);
if (!worker) {
flb_errno();
mk_event_loop_destroy(log->evl);
flb_free(log);
config->log = NULL;
log_create_cleanup(log, config);
return NULL;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Release logger resources before returning on worker failure

When flb_worker_context_create() fails after the logger pipe, metrics, mutexes, and possibly the file sink have already been initialized, this new return NULL leaves those resources behind and clears config->log, so later flb_config_exit() cannot call flb_log_destroy() to clean them up. In startup or embedded callers that retry after a transient allocation failure, each failed attempt leaks the pipe descriptors, cmetrics state, and an open log file when FLB_LOG_FILE was selected; this failure path should mirror the relevant pre-thread cleanup before returning.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^ @MsfPablo We need to release resources on exceptions.

}

/* Set the worker context global */
Expand All @@ -1099,10 +1129,8 @@ struct flb_log *flb_log_create(struct flb_config *config, int type,
ret = flb_log_worker_init(worker);
if (ret == -1) {
flb_errno();
mk_event_loop_destroy(log->evl);
flb_free(log);
config->log = NULL;
flb_free(worker);
log_create_cleanup(log, config);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
log_create_worker_cleanup(worker);
return NULL;
}
log->worker = worker;
Expand All @@ -1120,10 +1148,10 @@ struct flb_log *flb_log_create(struct flb_config *config, int type,
ret = flb_worker_create(log_worker_collector, log, &log->tid, config);
if (ret == -1) {
pthread_mutex_unlock(&log->pth_mutex);
mk_event_loop_destroy(log->evl);
flb_free(log->worker);
flb_free(log);
config->log = NULL;
pthread_mutex_destroy(&log->pth_mutex);
pthread_cond_destroy(&log->pth_cond);
log_create_worker_cleanup(log->worker);
log_create_cleanup(log, config);
return NULL;
}

Expand Down