From 6ba9dce5c8dbc40532658b5b6b0e9143539da3e3 Mon Sep 17 00:00:00 2001 From: quzard <1191890118@qq.com> Date: Sat, 30 Dec 2023 00:39:52 +0800 Subject: [PATCH] fix: Prevent crash due to concurrent map access in Go plugin log processing (#1284) This commit resolves a critical concurrency issue in the Go plugin log processing that could lead to a crash. The problem was identified as a "concurrent map read and map write" error stemming from shared context map usage without proper isolation. During high log volume situations, the concurrent modification of the context map in the ReceiveLogGroup function and simultaneous access in the Add function caused the crash. The fix introduces a shallow copy of the context map for each log instance, ensuring that each processor works with an independent map and preventing the concurrent access conflicts that could lead to runtime crashes. --- pluginmanager/plugin_runner_v1.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pluginmanager/plugin_runner_v1.go b/pluginmanager/plugin_runner_v1.go index 147109e947..a51921d94f 100644 --- a/pluginmanager/plugin_runner_v1.go +++ b/pluginmanager/plugin_runner_v1.go @@ -432,18 +432,26 @@ func (p *pluginv1Runner) ReceiveRawLog(log *pipeline.LogWithContext) { } func (p *pluginv1Runner) ReceiveLogGroup(logGroup pipeline.LogGroupWithContext) { - context := logGroup.Context topic := logGroup.LogGroup.GetTopic() - context[ctxKeyTopic] = topic for _, log := range logGroup.LogGroup.Logs { if len(topic) > 0 { log.Contents = append(log.Contents, &protocol.Log_Content{Key: tagKeyLogTopic, Value: topic}) } // When UsingOldContentTag is set to false, the tag is now put into the context during cgo. if !p.LogstoreConfig.GlobalConfig.UsingOldContentTag { + context := map[string]interface{}{} + for key, value := range logGroup.Context { + context[key] = value + } + context[ctxKeyTopic] = topic context[ctxKeyTags] = logGroup.LogGroup.LogTags p.ReceiveRawLog(&pipeline.LogWithContext{Log: log, Context: context}) } else { + context := map[string]interface{}{} + for key, value := range logGroup.Context { + context[key] = value + } + context[ctxKeyTopic] = topic for _, tag := range logGroup.LogGroup.LogTags { log.Contents = append(log.Contents, &protocol.Log_Content{ Key: tagPrefix + tag.GetKey(),