ui: added info screen for indexer crash investigation
* in case Coati crashes while indexing this screen will inform the user of further steps to take in order to find out what happened
This commit is contained in:
+39
-1
@@ -1,4 +1,5 @@
|
||||
#include "Application.h"
|
||||
#include "ApplicationStateMonitor.h"
|
||||
#include "ProjectFactoryModuleC.h"
|
||||
#include "ProjectFactoryModuleCpp.h"
|
||||
#include "ProjectFactoryModuleJava.h"
|
||||
@@ -175,7 +176,6 @@ int main(int argc, char *argv[])
|
||||
Application::destroyInstance();
|
||||
});
|
||||
|
||||
|
||||
prefillJavaRuntimePath();
|
||||
prefillCxxHeaderPaths();
|
||||
prefillCxxFrameworkPaths();
|
||||
@@ -196,6 +196,44 @@ int main(int argc, char *argv[])
|
||||
utility::loadFontsFromDirectory(ResourcePaths::getFontsPath(), ".otf");
|
||||
utility::loadFontsFromDirectory(ResourcePaths::getFontsPath(), ".ttf");
|
||||
|
||||
const std::vector<FilePath> storedIndexingFiles = ApplicationStateMonitor::getStoredIndexingFiles();
|
||||
if (storedIndexingFiles.size() > 0)
|
||||
{
|
||||
ApplicationStateMonitor::clearStoredIndexingFiles();
|
||||
if (storedIndexingFiles.size() > 1)
|
||||
{
|
||||
std::string fileStrings = "";
|
||||
for (const FilePath& filePath: storedIndexingFiles)
|
||||
{
|
||||
fileStrings += "<li>" + filePath.str() + "</li>";
|
||||
}
|
||||
Application::getInstance()->handleDialog(
|
||||
"<p>It seems that Coati shut down unexpectedly while indexing your project. We are sorry about that. "
|
||||
"But let's go on and find out what exactly went wrong. The crash occurred while indexing one of these files:</p>"
|
||||
"<ul>" +
|
||||
fileStrings +
|
||||
"</ul>"
|
||||
"<p>First of all we need to figure out which of these files caused the crash. Please go ahead and create copy of your project. "
|
||||
"Remove everything except the files mentioned above from the Project Paths. "
|
||||
"Set your indexer thread count to 1, force-refresh the project and wait for the crash to reoccur.</p>"
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
Application::getInstance()->handleDialog(
|
||||
"<p>It seems that Coati shut down unexpectedly while indexing your project. We are really sorry about that. "
|
||||
"At least we know which of your source files caused the crash:</p>"
|
||||
"<ul>"
|
||||
"<li>" + storedIndexingFiles.front().str() + "</li>" +
|
||||
"</ul>"
|
||||
"<p>To find out which part of the file caused the crash, please make sure to remove everything except this source file from your Project Paths. "
|
||||
"Enable the option \"Enable Verbose Indexer Logging\" in your log window (this really slows down indexing performance) and force-refresh the project.</p>"
|
||||
"<p>After the expected crash reoccurred please open the respective log file which now contains the portion of the abstract syntax tree that Coati managed to index, "
|
||||
"including the node where the crash occurred. We hope that this information helps you figure out what caused the crash and tell us what we can do to reproduce it.</p>"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return qtApp.exec();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ void Application::createInstance(
|
||||
|
||||
s_instance->m_storageCache = std::make_shared<StorageCache>();
|
||||
|
||||
if (viewFactory != nullptr)
|
||||
if (hasGui)
|
||||
{
|
||||
s_instance->m_componentManager = ComponentManager::create(viewFactory, s_instance->m_storageCache.get());
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
#include "ApplicationStateMonitor.h"
|
||||
|
||||
#include "settings/ApplicationSettings.h"
|
||||
|
||||
std::shared_ptr<ApplicationStateMonitor> ApplicationStateMonitor::getInstance()
|
||||
{
|
||||
if (!s_instance)
|
||||
{
|
||||
s_instance = std::shared_ptr<ApplicationStateMonitor>(new ApplicationStateMonitor());
|
||||
}
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
std::vector<FilePath> ApplicationStateMonitor::getStoredIndexingFiles()
|
||||
{
|
||||
return ApplicationSettings::getInstance()->getIndexingFilePaths();
|
||||
}
|
||||
|
||||
void ApplicationStateMonitor::clearStoredIndexingFiles()
|
||||
{
|
||||
ApplicationSettings::getInstance()->setIndexingFilePaths(std::vector<FilePath>());
|
||||
ApplicationSettings::getInstance()->save();
|
||||
}
|
||||
|
||||
void ApplicationStateMonitor::clearIndexingFiles()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_indexingFilesMutex);
|
||||
m_indexingFiles.clear();
|
||||
storeCurrentState();
|
||||
}
|
||||
|
||||
void ApplicationStateMonitor::addIndexingFile(FilePath file)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_indexingFilesMutex);
|
||||
m_indexingFiles.insert(file);
|
||||
storeCurrentState();
|
||||
}
|
||||
|
||||
void ApplicationStateMonitor::removeIndexingFile(FilePath file)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_indexingFilesMutex);
|
||||
m_indexingFiles.erase(file);
|
||||
storeCurrentState();
|
||||
}
|
||||
|
||||
std::shared_ptr<ApplicationStateMonitor> ApplicationStateMonitor::s_instance;
|
||||
|
||||
ApplicationStateMonitor::ApplicationStateMonitor()
|
||||
{
|
||||
}
|
||||
|
||||
void ApplicationStateMonitor::storeCurrentState()
|
||||
{
|
||||
std::vector<FilePath> indexingFiles;
|
||||
indexingFiles.insert(indexingFiles.begin(), m_indexingFiles.begin(), m_indexingFiles.end());
|
||||
ApplicationSettings::getInstance()->setIndexingFilePaths(indexingFiles);
|
||||
ApplicationSettings::getInstance()->save();
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef APPLICATION_STATE_MONITOR_H
|
||||
#define APPLICATION_STATE_MONITOR_H
|
||||
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
|
||||
#include "utility/file/FilePath.h"
|
||||
|
||||
class ApplicationStateMonitor
|
||||
{
|
||||
public:
|
||||
static std::shared_ptr<ApplicationStateMonitor> getInstance();
|
||||
static std::vector<FilePath> getStoredIndexingFiles();
|
||||
static void clearStoredIndexingFiles();
|
||||
|
||||
void clearIndexingFiles();
|
||||
void addIndexingFile(FilePath file);
|
||||
void removeIndexingFile(FilePath file);
|
||||
|
||||
private:
|
||||
static std::shared_ptr<ApplicationStateMonitor> s_instance;
|
||||
ApplicationStateMonitor();
|
||||
void storeCurrentState();
|
||||
|
||||
|
||||
std::set<FilePath> m_indexingFiles;
|
||||
std::mutex m_indexingFilesMutex;
|
||||
};
|
||||
|
||||
#endif // APPLICATION_STATE_MONITOR_H
|
||||
@@ -383,6 +383,8 @@ add_files(
|
||||
|
||||
Application.cpp
|
||||
Application.h
|
||||
ApplicationStateMonitor.cpp
|
||||
ApplicationStateMonitor.h
|
||||
LicenseChecker.cpp
|
||||
LicenseChecker.h
|
||||
Project.cpp
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#include "data/parser/TaskParse.h"
|
||||
|
||||
#include "component/view/DialogView.h"
|
||||
#include "utility/file/FileRegister.h"
|
||||
#include "utility/scheduling/Blackboard.h"
|
||||
#include "ApplicationStateMonitor.h"
|
||||
|
||||
TaskParse::TaskParse(
|
||||
std::shared_ptr<StorageProvider> storageProvider,
|
||||
@@ -28,6 +31,28 @@ void TaskParse::doEnter(std::shared_ptr<Blackboard> blackboard)
|
||||
}
|
||||
}
|
||||
|
||||
Task::TaskState TaskParse::doUpdate(std::shared_ptr<Blackboard> blackboard)
|
||||
{
|
||||
FilePath sourcePath = m_fileRegister->consumeSourceFile();
|
||||
|
||||
if (sourcePath.empty())
|
||||
{
|
||||
return STATE_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ApplicationStateMonitor::getInstance()->addIndexingFile(sourcePath);
|
||||
m_dialogView->updateIndexingDialog(
|
||||
m_fileRegister->getParsedSourceFilesCount(), m_fileRegister->getSourceFilesCount(), sourcePath.str()
|
||||
);
|
||||
|
||||
indexFile(sourcePath);
|
||||
ApplicationStateMonitor::getInstance()->removeIndexingFile(sourcePath);
|
||||
}
|
||||
|
||||
return (m_interrupted ? STATE_FAILURE : STATE_SUCCESS);
|
||||
}
|
||||
|
||||
void TaskParse::doExit(std::shared_ptr<Blackboard> blackboard)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(blackboard->getMutex());
|
||||
|
||||
@@ -25,10 +25,12 @@ public:
|
||||
|
||||
protected:
|
||||
virtual void doEnter(std::shared_ptr<Blackboard> blackboard);
|
||||
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blackboard);
|
||||
virtual void doExit(std::shared_ptr<Blackboard> blackboard);
|
||||
virtual void doReset(std::shared_ptr<Blackboard> blackboard);
|
||||
|
||||
virtual void handleMessage(MessageInterruptTasks* message);
|
||||
virtual void indexFile(FilePath sourcePath) = 0;
|
||||
|
||||
std::shared_ptr<StorageProvider> m_storageProvider;
|
||||
std::shared_ptr<FileRegister> m_fileRegister;
|
||||
|
||||
@@ -175,6 +175,16 @@ void ApplicationSettings::setVerboseIndexerLoggingEnabled(bool value)
|
||||
setValue<bool>("application/verbose_indexer_logging_enabled", value);
|
||||
}
|
||||
|
||||
std::vector<FilePath> ApplicationSettings::getIndexingFilePaths() const
|
||||
{
|
||||
return getPathValues("application/state/indexing_paths/indexing_path");
|
||||
}
|
||||
|
||||
bool ApplicationSettings::setIndexingFilePaths(const std::vector<FilePath>& indexingFiles)
|
||||
{
|
||||
return setPathValues("application/state/indexing_paths/indexing_path", indexingFiles);
|
||||
}
|
||||
|
||||
int ApplicationSettings::getIndexerThreadCount() const
|
||||
{
|
||||
return getValue<int>("indexing/indexer_thread_count", 4);
|
||||
|
||||
@@ -53,6 +53,9 @@ public:
|
||||
bool getVerboseIndexerLoggingEnabled() const;
|
||||
void setVerboseIndexerLoggingEnabled(bool loggingEnabled);
|
||||
|
||||
std::vector<FilePath> getIndexingFilePaths() const;
|
||||
bool setIndexingFilePaths(const std::vector<FilePath>& indexingFiles);
|
||||
|
||||
// indexing
|
||||
int getIndexerThreadCount() const;
|
||||
void setIndexerThreadCount(const int count);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include "clang/Tooling/JSONCompilationDatabase.h"
|
||||
|
||||
#include "component/view/DialogView.h"
|
||||
#include "data/parser/cxx/CxxParser.h"
|
||||
#include "data/parser/ParserClientImpl.h"
|
||||
#include "data/StorageProvider.h"
|
||||
@@ -62,48 +61,33 @@ void TaskParseCxx::doEnter(std::shared_ptr<Blackboard> blackboard)
|
||||
}
|
||||
}
|
||||
|
||||
Task::TaskState TaskParseCxx::doUpdate(std::shared_ptr<Blackboard> blackboard)
|
||||
void TaskParseCxx::indexFile(FilePath sourcePath)
|
||||
{
|
||||
FileRegister* fileRegister = m_parser->getFileRegister();
|
||||
|
||||
FilePath sourcePath = fileRegister->consumeSourceFile();
|
||||
std::shared_ptr<IntermediateStorage> storage = m_storageProvider->popIndexerTarget();
|
||||
m_parserClient->setStorage(storage);
|
||||
m_parserClient->startParsingFile();
|
||||
|
||||
if (sourcePath.empty())
|
||||
if (m_isCDB)
|
||||
{
|
||||
return STATE_FAILURE;
|
||||
std::vector<clang::tooling::CompileCommand> commands = m_cdb->getCompileCommands(sourcePath.str());
|
||||
if (commands.size() > 0)
|
||||
{
|
||||
m_parser->runTool(commands[0], m_arguments);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dialogView->updateIndexingDialog(
|
||||
fileRegister->getParsedSourceFilesCount(), fileRegister->getSourceFilesCount(), sourcePath.str()
|
||||
);
|
||||
|
||||
std::shared_ptr<IntermediateStorage> storage = m_storageProvider->popIndexerTarget();
|
||||
m_parserClient->setStorage(storage);
|
||||
m_parserClient->startParsingFile();
|
||||
|
||||
if (m_isCDB)
|
||||
{
|
||||
std::vector<clang::tooling::CompileCommand> commands = m_cdb->getCompileCommands(sourcePath.str());
|
||||
if (commands.size() > 0)
|
||||
{
|
||||
m_parser->runTool(commands[0], m_arguments);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_parser->runTool(std::vector<std::string>(1, sourcePath.str()));
|
||||
}
|
||||
|
||||
m_parserClient->finishParsingFile();
|
||||
m_parserClient->resetStorage();
|
||||
|
||||
if (!m_interrupted)
|
||||
{
|
||||
fileRegister->markThreadFilesParsed();
|
||||
m_storageProvider->pushIndexerTarget(storage);
|
||||
}
|
||||
m_parser->runTool(std::vector<std::string>(1, sourcePath.str()));
|
||||
}
|
||||
|
||||
return (m_interrupted ? STATE_FAILURE : STATE_SUCCESS);
|
||||
m_parserClient->finishParsingFile();
|
||||
m_parserClient->resetStorage();
|
||||
|
||||
if (!m_interrupted)
|
||||
{
|
||||
fileRegister->markThreadFilesParsed();
|
||||
m_storageProvider->pushIndexerTarget(storage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@ public:
|
||||
|
||||
private:
|
||||
virtual void doEnter(std::shared_ptr<Blackboard> blackboard);
|
||||
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blackboard);
|
||||
|
||||
virtual void indexFile(FilePath sourcePath);
|
||||
|
||||
std::shared_ptr<CxxParser> m_parser;
|
||||
std::shared_ptr<ParserClientImpl> m_parserClient;
|
||||
|
||||
@@ -17,38 +17,23 @@ TaskParseJava::TaskParseJava(
|
||||
{
|
||||
}
|
||||
|
||||
Task::TaskState TaskParseJava::doUpdate(std::shared_ptr<Blackboard> blackboard)
|
||||
void TaskParseJava::indexFile(FilePath sourcePath)
|
||||
{
|
||||
std::shared_ptr<ParserClientImpl> parserClient = std::make_shared<ParserClientImpl>();
|
||||
std::shared_ptr<JavaParser> parser = std::make_shared<JavaParser>(parserClient.get());
|
||||
|
||||
FilePath sourcePath = m_fileRegister->consumeSourceFile();
|
||||
std::shared_ptr<IntermediateStorage> storage = m_storageProvider->popIndexerTarget();
|
||||
parserClient->setStorage(storage);
|
||||
parserClient->startParsingFile();
|
||||
|
||||
if (sourcePath.empty())
|
||||
parser->parseFile(sourcePath, TextAccess::createFromFile(sourcePath.str()), m_arguments);
|
||||
|
||||
parserClient->finishParsingFile();
|
||||
parserClient->resetStorage();
|
||||
|
||||
if (!m_interrupted)
|
||||
{
|
||||
return STATE_FAILURE;
|
||||
m_fileRegister->markThreadFilesParsed(); // todo: rename to markThreadFilesProcessed
|
||||
m_storageProvider->pushIndexerTarget(storage);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dialogView->updateIndexingDialog(
|
||||
m_fileRegister->getParsedSourceFilesCount(), m_fileRegister->getSourceFilesCount(), sourcePath.str()
|
||||
);
|
||||
|
||||
std::shared_ptr<IntermediateStorage> storage = m_storageProvider->popIndexerTarget();
|
||||
parserClient->setStorage(storage);
|
||||
parserClient->startParsingFile();
|
||||
|
||||
parser->parseFile(sourcePath, TextAccess::createFromFile(sourcePath.str()), m_arguments);
|
||||
|
||||
parserClient->finishParsingFile();
|
||||
parserClient->resetStorage();
|
||||
|
||||
if (!m_interrupted)
|
||||
{
|
||||
m_fileRegister->markThreadFilesParsed(); // todo: rename to markThreadFilesProcessed
|
||||
m_storageProvider->pushIndexerTarget(storage);
|
||||
}
|
||||
}
|
||||
|
||||
return (m_interrupted ? STATE_FAILURE : STATE_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ public:
|
||||
);
|
||||
|
||||
private:
|
||||
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blackboard);
|
||||
void indexFile(FilePath sourcePath);
|
||||
};
|
||||
|
||||
#endif // TASK_PARSE_JAVA_H
|
||||
|
||||
Reference in New Issue
Block a user