From ea68229303c489e63e919b42ce3a63f7e3e1ad09 Mon Sep 17 00:00:00 2001 From: mlangkabel Date: Fri, 31 Aug 2018 13:19:52 +0200 Subject: [PATCH] logic: fixed crash that occurred in some cases when logging the clang invocation --- src/lib/utility/logging/LogManager.cpp | 7 ++++- src/lib/utility/logging/LogManager.h | 1 + src/lib_cxx/data/parser/cxx/CxxParser.cpp | 36 ++++++++++++++++++----- 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/lib/utility/logging/LogManager.cpp b/src/lib/utility/logging/LogManager.cpp index 0f47476b..6d9e81f6 100644 --- a/src/lib/utility/logging/LogManager.cpp +++ b/src/lib/utility/logging/LogManager.cpp @@ -35,7 +35,7 @@ void LogManager::setLoggingEnabled(bool enabled) if (enabled) { LOG_INFO( - std::string("Enabled logging for Sourcetrail ") + + std::string("Enabled logging for Sourcetrail ") + (utility::getApplicationArchitectureType() == APPLICATION_ARCHITECTURE_X86_32 ? "32" : "64") + " bit, " + "version " + Version::getApplicationVersion().toDisplayString() ); @@ -49,6 +49,11 @@ void LogManager::setLoggingEnabled(bool enabled) } } +bool LogManager::getLoggingEnabled() const +{ + return m_loggingEnabled; +} + void LogManager::addLogger(std::shared_ptr logger) { m_logManagerImplementation.addLogger(logger); diff --git a/src/lib/utility/logging/LogManager.h b/src/lib/utility/logging/LogManager.h index 75f8a18e..e19cd581 100644 --- a/src/lib/utility/logging/LogManager.h +++ b/src/lib/utility/logging/LogManager.h @@ -15,6 +15,7 @@ public: ~LogManager(); void setLoggingEnabled(bool enabled); + bool getLoggingEnabled() const; void addLogger(std::shared_ptr logger); void removeLogger(std::shared_ptr logger); diff --git a/src/lib_cxx/data/parser/cxx/CxxParser.cpp b/src/lib_cxx/data/parser/cxx/CxxParser.cpp index d3b0b239..d95e9402 100644 --- a/src/lib_cxx/data/parser/cxx/CxxParser.cpp +++ b/src/lib_cxx/data/parser/cxx/CxxParser.cpp @@ -24,6 +24,12 @@ namespace { + struct ClangInvocationInfo + { + std::string invocation; + std::string errors; + }; + // copied from clang codebase clang::driver::Driver *newDriver( clang::DiagnosticsEngine *Diagnostics, const char *BinaryName, @@ -36,8 +42,10 @@ namespace } // copied and stitched together from clang codebase - std::string getClangInvocationString(const clang::tooling::CompilationDatabase* compilationDatabase) + ClangInvocationInfo getClangInvocationString(const clang::tooling::CompilationDatabase* compilationDatabase) { + ClangInvocationInfo invocationInfo; + if (!compilationDatabase->getAllCompileCommands().empty()) { std::vector CommandLine = compilationDatabase->getAllCompileCommands().front().CommandLine; @@ -52,8 +60,13 @@ namespace llvm::opt::InputArgList ParsedArgs = Opts->ParseArgs( clang::ArrayRef(Argv).slice(1), MissingArgIndex, MissingArgCount); clang::ParseDiagnosticArgs(*DiagOpts, ParsedArgs); + + llvm::raw_string_ostream diagnosticsStream(invocationInfo.errors); + clang::TextDiagnosticPrinter DiagnosticPrinter( + diagnosticsStream, &*DiagOpts); clang::DiagnosticsEngine Diagnostics( - clang::IntrusiveRefCntPtr(new clang::DiagnosticIDs()), &*DiagOpts); + clang::IntrusiveRefCntPtr(new clang::DiagnosticIDs()), &*DiagOpts, + &DiagnosticPrinter, false); llvm::IntrusiveRefCntPtr Files(new clang::FileManager(clang::FileSystemOptions())); @@ -63,16 +76,20 @@ namespace Driver->setCheckInputsExist(false); const std::unique_ptr Compilation( Driver->BuildCompilation(llvm::makeArrayRef(Argv))); + if (Compilation) { - std::string s; - llvm::raw_string_ostream ss(s); + llvm::raw_string_ostream ss(invocationInfo.invocation); Compilation->getJobs().Print(ss, "", true); ss.flush(); - return utility::trim(s); } + + diagnosticsStream.flush(); + + invocationInfo.invocation = utility::trim(invocationInfo.invocation); + invocationInfo.errors = utility::trim(invocationInfo.errors); } - return ""; + return invocationInfo; } std::vector prependSyntaxOnlyToolArgs(const std::vector& args) @@ -184,7 +201,12 @@ void CxxParser::runTool(clang::tooling::CompilationDatabase* compilationDatabase tool.setDiagnosticConsumer(diagnostics.get()); - LOG_INFO("Clang Invocation: " + getClangInvocationString(compilationDatabase)); + if (LogManager::getInstance()->getLoggingEnabled()) + { + const ClangInvocationInfo info = getClangInvocationString(compilationDatabase); + LOG_INFO("Clang Invocation: " + info.invocation); + LOG_INFO("Clang Invocation errors: " + info.errors); + } ASTActionFactory actionFactory(m_client, canonicalFilePathCache); tool.run(&actionFactory);