Skip to content

Commit d651b6b

Browse files
authored
dump: Fix concurrency problem with dump files (#4757)
* dump: Fix concurrency problem with dump files This adds the process ID for the cppcheck process to the filenames of the .dump and .ctu-info files that the process generates. So lib/cppcheck.cpp.dump becomes lib/cppcheck.cpp.<PID>.dump For example: lib/cppcheck.cpp.2637871.dump The reason for this change is that if there is a buildsystem which supports concurrency, multiple instances of cppcheck may be run for the same file. For example, if the same file is compiled in multiple build variants, or for multiple targets. If running the MISRA plugin over such a project with concurrency enabled in the buildsystem, the plugin ends up crashing as multiple jobs attempt to create/trample/delete the same files while other jobs are using them. For more information see: https://sourceforge.net/p/cppcheck/discussion/general/thread/02c757b4af/ * dump: Include pid in filename if dump not explicit Only change the dump and ctu-info filenames to include the PID if they are being generated due to an addon. This means that existing scripts that use `--dump` will still work if they depend on the previous naming behaviour. The more robust filenames containing the pid will be used when the dump files are used as an internal implementation detail for passing data to addons. However this means that anything that does explicitly use `--dump` will be susceptible to concurrency problems. * test: Update addon dump file test to account for pid This test causes a dump file to be created by enabling the misra addon. Since the dump files now include the cppcheck process pid this test had to be updated to account for the change.
1 parent 26bb551 commit d651b6b

2 files changed

Lines changed: 31 additions & 3 deletions

File tree

lib/cppcheck.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@
5656
#include <utility>
5757
#include <vector>
5858

59+
#ifndef _WIN32
60+
#include <unistd.h>
61+
#else
62+
#include <process.h>
63+
#endif
64+
5965
#define PICOJSON_USE_INT64
6066
#include <picojson.h>
6167

@@ -229,13 +235,29 @@ static std::vector<std::string> split(const std::string &str, const std::string
229235
return ret;
230236
}
231237

238+
static int getPid()
239+
{
240+
#ifndef _WIN32
241+
return getpid();
242+
#else
243+
return _getpid();
244+
#endif
245+
}
246+
232247
static std::string getDumpFileName(const Settings& settings, const std::string& filename)
233248
{
234249
if (!settings.dumpFile.empty())
235250
return settings.dumpFile;
251+
252+
std::string extension;
253+
if (settings.dump)
254+
extension = ".dump";
255+
else
256+
extension = "." + std::to_string(getPid()) + ".dump";
257+
236258
if (!settings.dump && !settings.buildDir.empty())
237-
return AnalyzerInformation::getAnalyzerInfoFile(settings.buildDir, filename, emptyString) + ".dump";
238-
return filename + ".dump";
259+
return AnalyzerInformation::getAnalyzerInfoFile(settings.buildDir, filename, emptyString) + extension;
260+
return filename + extension;
239261
}
240262

241263
static std::string getCtuInfoFileName(const std::string &dumpFile)

test/cli/test-helloworld.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import re
66
import tempfile
77
import pytest
8+
import glob
89

910
from testutils import create_gui_project_file, cppcheck
1011

@@ -187,7 +188,12 @@ def test_build_dir_dump_output():
187188

188189
cppcheck(args.split())
189190
cppcheck(args.split())
190-
with open(f'{tempdir}/main.a1.dump', 'rt') as f:
191+
192+
filename = f'{tempdir}/main.a1.*.dump'
193+
filelist = glob.glob(filename)
194+
assert(len(filelist) == 1)
195+
196+
with open(filelist[0], 'rt') as f:
191197
dump = f.read()
192198
assert '</dump>' in dump, 'invalid dump data: ...' + dump[-100:]
193199

0 commit comments

Comments
 (0)