Skip to content

Commit d00dbe0

Browse files
authored
Fix #11750 (refactor ctu-info to generate fewer artifacts on disk) (#6778)
1 parent be04977 commit d00dbe0

File tree

10 files changed

+139
-49
lines changed

10 files changed

+139
-49
lines changed

addons/cppcheckdata.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1688,11 +1688,14 @@ def reportError(location, severity, message, addon, errorId, extra='', columnOve
16881688
EXIT_CODE = 1
16891689

16901690
def reportSummary(dumpfile, summary_type, summary_data):
1691-
# dumpfile ends with ".dump"
1692-
ctu_info_file = dumpfile[:-4] + "ctu-info"
1693-
with open(ctu_info_file, 'at') as f:
1694-
msg = {'summary': summary_type, 'data': summary_data}
1695-
f.write(json.dumps(msg) + '\n')
1691+
msg = {'summary': summary_type, 'data': summary_data}
1692+
if '--cli' in sys.argv:
1693+
sys.stdout.write(json.dumps(msg) + '\n')
1694+
else:
1695+
# dumpfile ends with ".dump"
1696+
ctu_info_file = dumpfile[:-4] + "ctu-info"
1697+
with open(ctu_info_file, 'at') as f:
1698+
f.write(json.dumps(msg) + '\n')
16961699

16971700

16981701
def get_path_premium_addon():

addons/test/util.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ def convert_json_output(raw_json_strings):
3838
"""Convert raw stdout/stderr cppcheck JSON output to python dict."""
3939
json_output = {}
4040
for line in raw_json_strings:
41+
if line.startswith('{"summary":'):
42+
continue
4143
try:
4244
json_line = json.loads(line)
4345
# json_output[json_line['errorId']] = json_line

cli/cppcheckexecutor.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ namespace {
129129
return !mCriticalErrors.empty();
130130
}
131131

132+
const std::string& getCtuInfo() const {
133+
return mCtuInfo;
134+
}
135+
132136
private:
133137
/**
134138
* Information about progress is directed here. This should be
@@ -170,9 +174,14 @@ namespace {
170174
std::set<std::string> mActiveCheckers;
171175

172176
/**
173-
* True if there are critical errors
177+
* List of critical errors
174178
*/
175179
std::string mCriticalErrors;
180+
181+
/**
182+
* CTU information
183+
*/
184+
std::string mCtuInfo;
176185
};
177186
}
178187

@@ -286,7 +295,7 @@ int CppCheckExecutor::check_internal(const Settings& settings) const
286295
#endif
287296
}
288297

289-
returnValue |= cppcheck.analyseWholeProgram(settings.buildDir, mFiles, mFileSettings);
298+
returnValue |= cppcheck.analyseWholeProgram(settings.buildDir, mFiles, mFileSettings, stdLogger.getCtuInfo());
290299

291300
if (settings.severity.isEnabled(Severity::information) || settings.checkConfiguration) {
292301
const bool err = reportSuppressions(settings, suppressions, settings.checks.isEnabled(Checks::unusedFunction), mFiles, mFileSettings, stdLogger);
@@ -424,6 +433,11 @@ void StdLogger::reportErr(const ErrorMessage &msg)
424433
return;
425434
}
426435

436+
if (msg.severity == Severity::internal && msg.id == "ctuinfo") {
437+
mCtuInfo += msg.shortMessage() + "\n";
438+
return;
439+
}
440+
427441
if (ErrorLogger::isCriticalErrorId(msg.id) && mCriticalErrors.find(msg.id) == std::string::npos) {
428442
if (!mCriticalErrors.empty())
429443
mCriticalErrors += ", ";

gui/checkthread.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,11 @@ void CheckThread::check(const Settings &settings)
117117
start();
118118
}
119119

120-
void CheckThread::analyseWholeProgram(const QStringList &files)
120+
void CheckThread::analyseWholeProgram(const QStringList &files, const std::string& ctuInfo)
121121
{
122122
mFiles = files;
123123
mAnalyseWholeProgram = true;
124+
mCtuInfo = ctuInfo;
124125
start();
125126
}
126127

@@ -131,12 +132,14 @@ void CheckThread::run()
131132

132133
if (!mFiles.isEmpty() || mAnalyseWholeProgram) {
133134
mAnalyseWholeProgram = false;
135+
std::string ctuInfo;
136+
ctuInfo.swap(mCtuInfo);
134137
qDebug() << "Whole program analysis";
135138
std::list<FileWithDetails> files2;
136139
std::transform(mFiles.cbegin(), mFiles.cend(), std::back_inserter(files2), [&](const QString& file) {
137140
return FileWithDetails{file.toStdString(), 0};
138141
});
139-
mCppcheck.analyseWholeProgram(mCppcheck.settings().buildDir, files2, {});
142+
mCppcheck.analyseWholeProgram(mCppcheck.settings().buildDir, files2, {}, ctuInfo);
140143
mFiles.clear();
141144
emit done();
142145
return;

gui/checkthread.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,9 @@ class CheckThread : public QThread {
6060
/**
6161
* @brief Run whole program analysis
6262
* @param files All files
63+
* @param ctuInfo Ctu info for addons
6364
*/
64-
void analyseWholeProgram(const QStringList &files);
65+
void analyseWholeProgram(const QStringList &files, const std::string& ctuInfo);
6566

6667
void setAddonsAndTools(const QStringList &addonsAndTools) {
6768
mAddonsAndTools = addonsAndTools;
@@ -143,6 +144,7 @@ class CheckThread : public QThread {
143144

144145
QStringList mFiles;
145146
bool mAnalyseWholeProgram{};
147+
std::string mCtuInfo;
146148
QStringList mAddonsAndTools;
147149
QStringList mClangIncludePaths;
148150
QList<SuppressionList::Suppression> mSuppressions;

gui/threadhandler.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ void ThreadHandler::clearFiles()
5252
mLastFiles.clear();
5353
mResults.clearFiles();
5454
mAnalyseWholeProgram = false;
55+
mCtuInfo.clear();
5556
mAddonsAndTools.clear();
5657
mSuppressions.clear();
5758
}
@@ -102,6 +103,8 @@ void ThreadHandler::check(const Settings &settings)
102103
addonsAndTools << s;
103104
}
104105

106+
mCtuInfo.clear();
107+
105108
for (int i = 0; i < mRunningThreadCount; i++) {
106109
mThreads[i]->setAddonsAndTools(addonsAndTools);
107110
mThreads[i]->setSuppressions(mSuppressions);
@@ -164,8 +167,9 @@ void ThreadHandler::removeThreads()
164167
void ThreadHandler::threadDone()
165168
{
166169
if (mRunningThreadCount == 1 && mAnalyseWholeProgram) {
167-
mThreads[0]->analyseWholeProgram(mLastFiles);
170+
mThreads[0]->analyseWholeProgram(mLastFiles, mCtuInfo);
168171
mAnalyseWholeProgram = false;
172+
mCtuInfo.clear();
169173
return;
170174
}
171175

@@ -187,6 +191,7 @@ void ThreadHandler::stop()
187191
{
188192
mCheckStartTime = QDateTime();
189193
mAnalyseWholeProgram = false;
194+
mCtuInfo.clear();
190195
for (CheckThread* thread : mThreads) {
191196
thread->stop();
192197
}

gui/threadhandler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ protected slots:
257257
int mRunningThreadCount{};
258258

259259
bool mAnalyseWholeProgram{};
260+
std::string mCtuInfo;
260261

261262
QStringList mAddonsAndTools;
262263
QList<SuppressionList::Suppression> mSuppressions;

lib/cppcheck.cpp

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ static std::string getDumpFileName(const Settings& settings, const std::string&
139139
return settings.dumpFile;
140140

141141
std::string extension;
142-
if (settings.dump)
142+
if (settings.dump || !settings.buildDir.empty())
143143
extension = ".dump";
144144
else
145145
extension = "." + std::to_string(settings.pid) + ".dump";
@@ -167,7 +167,7 @@ static void createDumpFile(const Settings& settings,
167167
if (!fdump.is_open())
168168
return;
169169

170-
{
170+
if (!settings.buildDir.empty()) {
171171
std::ofstream fout(getCtuInfoFileName(dumpFile));
172172
}
173173

@@ -1419,8 +1419,7 @@ void CppCheck::executeAddons(const std::vector<std::string>& files, const std::s
14191419
std::string fileList;
14201420

14211421
if (files.size() >= 2 || endsWith(files[0], ".ctu-info")) {
1422-
fileList = Path::getPathFromFilename(files[0]) + FILELIST + std::to_string(mSettings.pid);
1423-
filesDeleter.addFile(fileList);
1422+
fileList = Path::getPathFromFilename(files[0]) + FILELIST;
14241423
std::ofstream fout(fileList);
14251424
for (const std::string& f: files)
14261425
fout << f << std::endl;
@@ -1429,6 +1428,8 @@ void CppCheck::executeAddons(const std::vector<std::string>& files, const std::s
14291428
// ensure all addons have already been resolved - TODO: remove when settings are const after creation
14301429
assert(mSettings.addonInfos.size() == mSettings.addons.size());
14311430

1431+
std::string ctuInfo;
1432+
14321433
for (const AddonInfo &addonInfo : mSettings.addonInfos) {
14331434
if (addonInfo.name != "misra" && !addonInfo.ctu && endsWith(files.back(), ".ctu-info"))
14341435
continue;
@@ -1445,6 +1446,18 @@ void CppCheck::executeAddons(const std::vector<std::string>& files, const std::s
14451446

14461447
ErrorMessage errmsg;
14471448

1449+
if (obj.count("summary") > 0) {
1450+
if (!mSettings.buildDir.empty()) {
1451+
ctuInfo += res.serialize() + "\n";
1452+
} else {
1453+
errmsg.severity = Severity::internal;
1454+
errmsg.id = "ctuinfo";
1455+
errmsg.setmsg(res.serialize());
1456+
reportErr(errmsg);
1457+
}
1458+
continue;
1459+
}
1460+
14481461
if (obj.count("file") > 0) {
14491462
std::string fileName = obj["file"].get<std::string>();
14501463
const int64_t lineNumber = obj["linenr"].get<int64_t>();
@@ -1483,13 +1496,30 @@ void CppCheck::executeAddons(const std::vector<std::string>& files, const std::s
14831496
reportErr(errmsg);
14841497
}
14851498
}
1499+
1500+
if (!mSettings.buildDir.empty() && fileList.empty()) {
1501+
const std::string& ctuInfoFile = getCtuInfoFileName(files[0]);
1502+
std::ofstream fout(ctuInfoFile);
1503+
fout << ctuInfo;
1504+
}
14861505
}
14871506

1488-
void CppCheck::executeAddonsWholeProgram(const std::list<FileWithDetails> &files, const std::list<FileSettings>& fileSettings)
1507+
void CppCheck::executeAddonsWholeProgram(const std::list<FileWithDetails> &files, const std::list<FileSettings>& fileSettings, const std::string& ctuInfo)
14891508
{
14901509
if (mSettings.addons.empty())
14911510
return;
14921511

1512+
if (mSettings.buildDir.empty()) {
1513+
const std::string fileName = std::to_string(mSettings.pid) + ".ctu-info";
1514+
FilesDeleter filesDeleter;
1515+
filesDeleter.addFile(fileName);
1516+
std::ofstream fout(fileName);
1517+
fout << ctuInfo;
1518+
fout.close();
1519+
executeAddons({fileName}, "");
1520+
return;
1521+
}
1522+
14931523
std::vector<std::string> ctuInfoFiles;
14941524
for (const auto &f: files) {
14951525
const std::string &dumpFileName = getDumpFileName(mSettings, f.path());
@@ -1507,11 +1537,6 @@ void CppCheck::executeAddonsWholeProgram(const std::list<FileWithDetails> &files
15071537
const ErrorMessage errmsg = ErrorMessage::fromInternalError(e, nullptr, "", "Bailing out from analysis: Whole program analysis failed");
15081538
reportErr(errmsg);
15091539
}
1510-
1511-
if (mSettings.buildDir.empty()) {
1512-
for (const std::string &f: ctuInfoFiles)
1513-
std::remove(f.c_str());
1514-
}
15151540
}
15161541

15171542
Settings &CppCheck::settings()
@@ -1807,13 +1832,9 @@ bool CppCheck::analyseWholeProgram()
18071832
return errors && (mExitCode > 0);
18081833
}
18091834

1810-
unsigned int CppCheck::analyseWholeProgram(const std::string &buildDir, const std::list<FileWithDetails> &files, const std::list<FileSettings>& fileSettings)
1835+
unsigned int CppCheck::analyseWholeProgram(const std::string &buildDir, const std::list<FileWithDetails> &files, const std::list<FileSettings>& fileSettings, const std::string& ctuInfo)
18111836
{
1812-
executeAddonsWholeProgram(files, fileSettings);
1813-
if (buildDir.empty()) {
1814-
removeCtuInfoFiles(files, fileSettings);
1815-
return mExitCode;
1816-
}
1837+
executeAddonsWholeProgram(files, fileSettings, ctuInfo);
18171838
if (mSettings.checks.isEnabled(Checks::unusedFunction))
18181839
CheckUnusedFunctions::analyseWholeProgram(mSettings, *this, buildDir);
18191840
std::list<Check::FileInfo*> fileInfoList;
@@ -1877,22 +1898,6 @@ unsigned int CppCheck::analyseWholeProgram(const std::string &buildDir, const st
18771898
return mExitCode;
18781899
}
18791900

1880-
void CppCheck::removeCtuInfoFiles(const std::list<FileWithDetails> &files, const std::list<FileSettings>& fileSettings)
1881-
{
1882-
if (mSettings.buildDir.empty()) {
1883-
for (const auto& f: files) {
1884-
const std::string &dumpFileName = getDumpFileName(mSettings, f.path());
1885-
const std::string &ctuInfoFileName = getCtuInfoFileName(dumpFileName);
1886-
std::remove(ctuInfoFileName.c_str());
1887-
}
1888-
for (const auto& fs: fileSettings) {
1889-
const std::string &dumpFileName = getDumpFileName(mSettings, fs.filename());
1890-
const std::string &ctuInfoFileName = getCtuInfoFileName(dumpFileName);
1891-
std::remove(ctuInfoFileName.c_str());
1892-
}
1893-
}
1894-
}
1895-
18961901
// cppcheck-suppress unusedFunction - only used in tests
18971902
void CppCheck::resetTimerResults()
18981903
{

lib/cppcheck.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,8 @@ class CPPCHECKLIB CppCheck : ErrorLogger {
145145
/** Analyze all files using clang-tidy */
146146
void analyseClangTidy(const FileSettings &fileSettings);
147147

148-
/** analyse whole program use .analyzeinfo files */
149-
unsigned int analyseWholeProgram(const std::string &buildDir, const std::list<FileWithDetails> &files, const std::list<FileSettings>& fileSettings);
150-
151-
/** Remove *.ctu-info files */
152-
void removeCtuInfoFiles(const std::list<FileWithDetails>& files, const std::list<FileSettings>& fileSettings); // cppcheck-suppress functionConst // has side effects
148+
/** analyse whole program use .analyzeinfo files or ctuinfo string */
149+
unsigned int analyseWholeProgram(const std::string &buildDir, const std::list<FileWithDetails> &files, const std::list<FileSettings>& fileSettings, const std::string& ctuInfo);
153150

154151
static void resetTimerResults();
155152
static void printTimerResults(SHOWTIME_MODES mode);
@@ -196,7 +193,7 @@ class CPPCHECKLIB CppCheck : ErrorLogger {
196193
/**
197194
* Execute addons
198195
*/
199-
void executeAddonsWholeProgram(const std::list<FileWithDetails> &files, const std::list<FileSettings>& fileSettings);
196+
void executeAddonsWholeProgram(const std::list<FileWithDetails> &files, const std::list<FileSettings>& fileSettings, const std::string& ctuInfo);
200197

201198
#ifdef HAVE_RULES
202199
/**

0 commit comments

Comments
 (0)