Commit 24f5270e authored by Leander Schulten's avatar Leander Schulten
Browse files

Convert segfaults and div by zero to exeptions. Closes #2. If a modules...

Convert segfaults and div by zero to exeptions. Closes #2. If a modules segfaults show an error and on windows the line of the error
parent e7616f79
......@@ -45,6 +45,7 @@ SOURCES += \
modules/dmxconsumer.cpp \
modules/ledconsumer.cpp \
scanner.cpp \
system_error_handler.cpp \
test/testloopprogramm.cpp \
settings.cpp \
test/DriverDummy.cpp \
......@@ -108,6 +109,7 @@ HEADERS += \
modules/ledconsumer.h \
modules/scanner.hpp \
scanner.h \
system_error_handler.h \
updater.h \
usermanagment.h \
gui/channelprogrammeditor.h \
......@@ -249,6 +251,18 @@ win32-g++{
}
}
#segvcatch
LIBS += -L$$PWD/'lib/segvcatch/lib' -lsegvcatch
INCLUDEPATH += $$PWD/'lib/segvcatch/include'
#boost stacktrace / libbacktrace
#see https://www.boost.org/doc/libs/1_66_0/doc/html/stacktrace/configuration_and_build.html
DEFINES += BOOST_STACKTRACE_USE_BACKTRACE
LIBS += -L$$PWD/'lib/libbacktrace/lib' -lbacktrace
INCLUDEPATH += $$PWD/'lib/libbacktrace/include'
win32-msvc{
#AudioFFT
LIBS += -L$$PWD/'lib/AudioFFT/dll/AudioFFT.dll'
......
libbacktrace.git*
*/*
\ No newline at end of file
#!/bin/bash
GIT_DIR="libbacktrace.git"
# wenn es schon da ist, einfach löschen
rm -f -r $GIT_DIR
git clone https://github.com/ianlancetaylor/libbacktrace.git $GIT_DIR
cd $GIT_DIR
# build from http://boostorg.github.io/stacktrace/stacktrace/configuration_and_build.html#stacktrace.configuration_and_build.mingw_and_mingw_w64_specific_not
./configure
make
cd ..
# move important files to new folder
mkdir -p lib
mv $GIT_DIR/.libs/libbacktrace.a lib
mkdir -p include
mv $GIT_DIR/backtrace.h include
echo "Installation complete"
\ No newline at end of file
segvcatch.git*
*/*
\ No newline at end of file
#!/bin/bash
mkdir -p lib
mkdir -p include
# wenn es schon da ist, einfach löschen
rm -f -r segvcatch.git
git clone https://github.com/Plaristote/segvcatch.git segvcatch.git
cd segvcatch.git
mkdir release
cd release
# build
if [ "$(expr substr $(uname -s) 1 5)" == "MINGW" ]; then
# we are on windows
# from build_mingw_release.bat
cmake -G "MSYS Makefiles" -DCMAKE_BUILD_TYPE=Release ../lib
mingw32-make
cd ..
else
cmake ..
make
cd ..
# we are on linux and cross compile
fi
cd ..
mv segvcatch.git/release/libsegvcatch.a lib
mv segvcatch.git/lib/segvcatch.h include
echo "Installation complete"
\ No newline at end of file
......@@ -4,7 +4,6 @@
#include "dmx/HardwareInterface.h"
#include "dmx/channel.h"
#include "dmx/device.h"
#include "dmx/device.h"
#include "dmx/dmxchannelfilter.h"
#include "dmx/driver.h"
#include "dmx/programm.h"
......@@ -26,6 +25,7 @@
#include "settings.h"
#include "sortedmodelview.h"
#include "spotify/spotify.h"
#include "system_error_handler.h"
#include "test/testloopprogramm.h"
#include "test/testmodulsystem.h"
#include "test/testsampleclass.h"
......@@ -55,8 +55,8 @@
#include <QNetworkReply>
#endif
int main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
error::initErrorHandler();
#ifdef DrMinGW
ExcHndlInit();
auto path = QStandardPaths::writableLocation(QStandardPaths::QStandardPaths::AppDataLocation);
......
#include "controller.h"
#include "compiler.h"
#include "errornotifier.h"
#include "system_error_handler.h"
#include <QDebug>
#include <QProcess>
#include <mutex>
namespace Modules {
......@@ -102,13 +107,75 @@ void Controller::run() noexcept{
std::unique_lock<std::mutex> l(vectorLock);
updateSpotifyState();
for(auto pb = runningProgramms.begin() ; pb != runningProgramms.end();){
if((*pb)->doStep(1)){
deletingProgramBlock = (*pb).get();
(**pb).stop();
try {
if ((*pb)->doStep(1)) {
deletingProgramBlock = (*pb).get();
(**pb).stop();
deletingProgramBlock = nullptr;
pb = runningProgramms.erase(pb);
} else {
++pb;
}
} catch (const error::crash_error &e) {
QString msg(e.what());
for (const auto &frame : e.getStacktrace()) {
const auto asString = boost::stacktrace::to_string(frame);
if (asString.find("____") != std::string::npos) {
QString filename;
int lineNumber = -1;
QProcess p;
QString cmd = Compiler::compilerCmd;
#ifdef Q_OS_WIN
if (!cmd.endsWith(QLatin1String("g++.exe"))) {
qDebug() << "Error in " << __FILE__ << " line " << __LINE__ << ": Can not build command to translate address to line. g++.exe not found in Compiler::cmd";
} else {
cmd.replace(QLatin1String("g++.exe"), QLatin1String("addr2line.exe"));
const int length = std::strlen("0x00007FFA4E5CA299 in ");
p.start(cmd, QStringList() << QStringLiteral("-e") << QString::fromStdString(asString).mid(length) << QString::number(reinterpret_cast<std::size_t>(frame.address()), 16));
p.waitForFinished();
QByteArray output = p.readAllStandardOutput();
int seperator = output.lastIndexOf(':');
filename = output.left(seperator);
lineNumber = output.mid(seperator + 1).trimmed().toInt();
}
#else
#warning OS not supported
#endif
if (lineNumber >= 0) {
QFile file(filename);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
break;
}
msg += " in line " + QString::number(lineNumber) + " in file " + filename.mid(filename.lastIndexOf('/') + 1) + "\n";
int currentLineNumber = 0;
while (!file.atEnd() && currentLineNumber < lineNumber + 2) {
++currentLineNumber;
QByteArray line = file.readLine();
if (currentLineNumber == lineNumber) {
msg += "->" + line;
} else if (currentLineNumber == lineNumber - 1 || currentLineNumber == lineNumber + 1) {
msg += " " + line;
}
}
file.close();
}
break;
}
}
ErrorNotifier::showError(QStringLiteral("Error while executing ") + (**pb).getName() + ":\n" + msg);
// if it was in a doStep call
if (deletingProgramBlock == nullptr) {
try {
deletingProgramBlock = (*pb).get();
(**pb).stop();
} catch (...) {
// we ignore the error (the module is completly broken)
}
}
// maybe inside the stop call
deletingProgramBlock = nullptr;
// we remove the programm from the running list
pb = runningProgramms.erase(pb);
}else{
++pb;
}
}
spotifyState.newTrack = false;
......
#include "system_error_handler.h"
#include <segvcatch.h>
#include <sstream>
error::crash_error::crash_error(std::string_view errorName) : error(errorName) {}
void throw_segv_error() {
using namespace std::literals;
throw error::crash_error("Segmention fault"sv);
}
void throw_div_zero_error() {
using namespace std::literals;
throw error::crash_error("Divide by zero"sv);
}
void error::initErrorHandler() {
segvcatch::init_segv(throw_segv_error);
segvcatch::init_fpe(throw_div_zero_error);
}
#ifndef SYSTEM_ERROR_HANDLER_H
#define SYSTEM_ERROR_HANDLER_H
#include <boost/stacktrace.hpp>
#include <stdexcept>
#include <string>
#include <string_view>
namespace error {
class crash_error : public std::exception {
std::string error;
boost::stacktrace::stacktrace stacktrace;
public:
explicit crash_error(std::string_view errorName);
[[nodiscard]] const char *what() const noexcept override { return error.c_str(); }
[[nodiscard]] const boost::stacktrace::stacktrace &getStacktrace() const noexcept { return stacktrace; }
};
void initErrorHandler();
} // namespace error
#endif // SYSTEM_ERROR_HANDLER_H
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment