Skip to content

Commit

Permalink
Dump stack trace on crash (Implement #849) (#870)
Browse files Browse the repository at this point in the history
* Print stack trace on crash

* Printing stack trace is fully functional except for WIN32

* Minor fixes

* Minor fixes
  • Loading branch information
m-seker authored Jul 12, 2020
1 parent 9c5e5ca commit 3b48d8c
Show file tree
Hide file tree
Showing 22 changed files with 235 additions and 84 deletions.
1 change: 1 addition & 0 deletions include/grabber/V4L2Wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class V4L2Wrapper : public GrabberWrapper
VideoStandard videoStandard,
PixelFormat pixelFormat,
int pixelDecimation );
~V4L2Wrapper() override;

bool getSignalDetectionEnable();

Expand Down
5 changes: 5 additions & 0 deletions include/grabber/X11Wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ class X11Wrapper: public GrabberWrapper
///
X11Wrapper(int cropLeft, int cropRight, int cropTop, int cropBottom, int pixelDecimation, const unsigned updateRate_Hz);

///
/// Destructor of this framebuffer frame grabber. Releases any claimed resources.
///
~X11Wrapper() override;

public slots:
///
/// Performs a single frame grab and computes the led-colors
Expand Down
6 changes: 6 additions & 0 deletions include/utils/DefaultSignalHandler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once

namespace DefaultSignalHandler
{
void install();
}
2 changes: 1 addition & 1 deletion libsrc/grabber/dispmanx/DispmanxWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ DispmanxWrapper::DispmanxWrapper(const unsigned grabWidth, const unsigned grabHe
: GrabberWrapper("Dispmanx", &_grabber, grabWidth, grabHeight, updateRate_Hz)
, _grabber(grabWidth, grabHeight)
{

}

void DispmanxWrapper::action()
Expand Down
5 changes: 5 additions & 0 deletions libsrc/grabber/v4l2/V4L2Wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ V4L2Wrapper::V4L2Wrapper(const QString &device,
connect(&_grabber, SIGNAL(readError(const char*)), this, SLOT(readError(const char*)), Qt::DirectConnection);
}

V4L2Wrapper::~V4L2Wrapper()
{
stop();
}

bool V4L2Wrapper::start()
{
return ( _grabber.start() && GrabberWrapper::start());
Expand Down
8 changes: 8 additions & 0 deletions libsrc/grabber/x11/X11Wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ X11Wrapper::X11Wrapper(int cropLeft, int cropRight, int cropTop, int cropBottom,
, _init(false)
{}

X11Wrapper::~X11Wrapper()
{
if ( _init )
{
stop();
}
}

void X11Wrapper::action()
{
if (! _init )
Expand Down
13 changes: 8 additions & 5 deletions libsrc/hyperion/GrabberWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ GrabberWrapper::GrabberWrapper(QString grabberName, Grabber * ggrabber, unsigned

GrabberWrapper::~GrabberWrapper()
{
GrabberWrapper::stop(); // TODO Is this right????????
stop();
Debug(_log,"Close grabber: %s", QSTRING_CSTR(_grabberName));
}

Expand All @@ -53,9 +53,12 @@ bool GrabberWrapper::start()

void GrabberWrapper::stop()
{
// Stop the timer, effectivly stopping the process
Debug(_log,"Grabber stop()");
_timer->stop();
if (_timer->isActive())
{
// Stop the timer, effectivly stopping the process
Debug(_log,"Grabber stop()");
_timer->stop();
}
}

QStringList GrabberWrapper::availableGrabbers()
Expand Down Expand Up @@ -216,7 +219,7 @@ void GrabberWrapper::handleSourceRequest(const hyperion::Components& component,

void GrabberWrapper::tryStart()
{
// verify start condition
// verify start condition
if((_grabberName.startsWith("V4L") && !GRABBER_V4L_CLIENTS.empty()) || (!_grabberName.startsWith("V4L") && !GRABBER_SYS_CLIENTS.empty()))
{
start();
Expand Down
15 changes: 2 additions & 13 deletions libsrc/hyperion/Hyperion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,8 @@ void Hyperion::start()
_boblightServer = new BoblightServer(this, getSetting(settings::BOBLSERVER));
connect(this, &Hyperion::settingsChanged, _boblightServer, &BoblightServer::handleSettingsUpdate);

// instance inited
// instance inited, enter thread event loop
emit started();
// enter thread event loop
}

void Hyperion::stop()
Expand Down Expand Up @@ -380,18 +379,8 @@ void Hyperion::setColor(const int priority, const std::vector<ColorRgb> &ledColo
_effectEngine->channelCleared(priority);

// create full led vector from single/multiple colors
size_t size = _ledString.leds().size();
std::vector<ColorRgb> newLedColors;
while (true)
{
for (const auto &entry : ledColors)
{
newLedColors.emplace_back(entry);
if (newLedColors.size() == size)
goto end;
}
}
end:
std::copy_n(ledColors.begin(), _ledString.leds().size(), std::back_inserter(newLedColors));

This comment has been minimized.

Copy link
@Lord-Grey

Lord-Grey Jul 25, 2020

Collaborator

Changes causes #897


if (getPriorityInfo(priority).componentId != hyperion::COMP_COLOR)
clear(priority);
Expand Down
2 changes: 1 addition & 1 deletion libsrc/leddevice/LedDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ LedDevice::LedDevice(const QJsonObject& config, QObject* parent)

LedDevice::~LedDevice()
{
_refresh_timer->deleteLater();
delete _refresh_timer;
}

int LedDevice::open()
Expand Down
2 changes: 1 addition & 1 deletion libsrc/leddevice/dev_spi/ProviderSpi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ bool ProviderSpi::init(const QJsonObject &deviceConfig)
_baudRate_Hz = deviceConfig["rate"].toInt(_baudRate_Hz);
_spiMode = deviceConfig["spimode"].toInt(_spiMode);
_spiDataInvert = deviceConfig["invert"].toBool(_spiDataInvert);

return isInitOK;
}

Expand Down
21 changes: 9 additions & 12 deletions libsrc/ssdp/SSDPHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,20 +116,17 @@ void SSDPHandler::handleWebServerStateChange(const bool newState)
void SSDPHandler::handleNetworkConfigurationChanged(const QNetworkConfiguration &config)
{
// get localAddress from interface
if(!getLocalAddress().isEmpty())
QString localAddress = getLocalAddress();
if(!localAddress.isEmpty() && _localAddress != localAddress)
{
QString localAddress = getLocalAddress();
if(_localAddress != localAddress)
{
// revoke old ip
sendAnnounceList(false);
// revoke old ip
sendAnnounceList(false);

// update desc & notify new ip
_localAddress = localAddress;
_webserver->setSSDPDescription(buildDesc());
setDescriptionAddress(getDescAddress());
sendAnnounceList(true);
}
// update desc & notify new ip
_localAddress = localAddress;
_webserver->setSSDPDescription(buildDesc());
setDescriptionAddress(getDescAddress());
sendAnnounceList(true);
}
}

Expand Down
132 changes: 132 additions & 0 deletions libsrc/utils/DefaultSignalHandler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#ifndef _WIN32

#include <utils/DefaultSignalHandler.h>
#include <utils/Logger.h>

#include <ctype.h>
#include <cxxabi.h>
#include <execinfo.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include <QCoreApplication>

namespace DefaultSignalHandler
{

std::string decipher_trace(const std::string &trace)
{
std::string result;

if(trace.empty())
{
result += "??\n";
return result;
}

auto* begin = strchr(trace.c_str(), '(') + 1;
auto* end = strchr(begin, '+');

if(!end)
end = strchr(begin, ')');

std::string mangled_name(begin, end);

int status;
char * realname = abi::__cxa_demangle(mangled_name.c_str(), 0, 0, &status);
result.insert(result.end(), trace.c_str(), begin);

if(realname)
result += realname;
else
result.insert(result.end(), begin, end);

free(realname);
result.insert(result.size(), end);

return result;
}

void print_trace()
{
const int MAX_SIZE = 50;
void * addresses[MAX_SIZE];
int size = backtrace(addresses, MAX_SIZE);

if (!size)
return;

Logger* log = Logger::getInstance("CORE");
char ** symbols = backtrace_symbols(addresses, size);
for (int i = 0; i < size; ++i)
{
std::string line = "\t" + decipher_trace(symbols[i]);
Error(log, line.c_str());
}

free(symbols);
}

/* Note that this signal handler is not async signal safe !
* Ideally a signal handler should only flip a bit and defer
* heavy work to some kind of bottom-half processing. */
void signal_handler(int signum, siginfo_t * /*info*/, void * /*context*/)
{
Logger* log = Logger::getInstance("SIGNAL");

char *name = strsignal(signum);
if (name)
{
Info(log, "Signal received : %s", name);
}

switch(signum)
{
case SIGSEGV:
case SIGABRT:
case SIGFPE :
print_trace();
exit(1);
case SIGINT :
case SIGTERM:
case SIGPIPE:
default:
/* If the signal_handler is hit before the event loop is started,
* following call will do nothing. So we queue the call. */

// QCoreApplication::quit();
QMetaObject::invokeMethod(qApp, "quit", Qt::QueuedConnection);

// Reset signal handler to default (in case this handler is not capable of stopping)
struct sigaction action{};
action.sa_handler = SIG_DFL;
sigaction(signum, &action, nullptr);

}
}

} // namespace DefaultSignalHandler
#endif // _WIN32

namespace DefaultSignalHandler
{
void install()
{
#ifndef _WIN32
struct sigaction action{};
action.sa_sigaction = signal_handler;
action.sa_flags = SA_RESTART | SA_SIGINFO;

sigaction(SIGHUP , &action, nullptr);
sigaction(SIGFPE , &action, nullptr);
sigaction(SIGINT , &action, nullptr);
sigaction(SIGTERM, &action, nullptr);
sigaction(SIGABRT, &action, nullptr);
sigaction(SIGSEGV, &action, nullptr);
sigaction(SIGPIPE, &action, nullptr);
#endif // _WIN32
}
} // namespace DefaultSignalHandler
4 changes: 4 additions & 0 deletions src/hyperion-aml/hyperion-aml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
// ssdp discover
#include <ssdp/SSDPDiscover.h>

#include <utils/DefaultSignalHandler.h>

using namespace commandline;

// save the image as screenshot
Expand All @@ -29,6 +31,8 @@ int main(int argc, char ** argv)
<< "\tVersion : " << HYPERION_VERSION << " (" << HYPERION_BUILD_ID << ")" << std::endl
<< "\tbuild time: " << __DATE__ << " " << __TIME__ << std::endl;

DefaultSignalHandler::install();

QCoreApplication app(argc, argv);

try
Expand Down
4 changes: 4 additions & 0 deletions src/hyperion-dispmanx/hyperion-dispmanx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
// ssdp discover
#include <ssdp/SSDPDiscover.h>

#include <utils/DefaultSignalHandler.h>

using namespace commandline;

// save the image as screenshot
Expand All @@ -29,6 +31,8 @@ int main(int argc, char ** argv)
<< "\tVersion : " << HYPERION_VERSION << " (" << HYPERION_BUILD_ID << ")" << std::endl
<< "\tbuild time: " << __DATE__ << " " << __TIME__ << std::endl;

DefaultSignalHandler::install();

QCoreApplication app(argc, argv);

try
Expand Down
4 changes: 4 additions & 0 deletions src/hyperion-framebuffer/hyperion-framebuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
// ssdp discover
#include <ssdp/SSDPDiscover.h>

#include <utils/DefaultSignalHandler.h>

using namespace commandline;

// save the image as screenshot
Expand All @@ -21,6 +23,8 @@ void saveScreenshot(QString filename, const Image<ColorRgb> & image)

int main(int argc, char ** argv)
{
DefaultSignalHandler::install();

QCoreApplication app(argc, argv);

try
Expand Down
4 changes: 4 additions & 0 deletions src/hyperion-osx/hyperion-osx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
// ssdp discover
#include <ssdp/SSDPDiscover.h>

#include <utils/DefaultSignalHandler.h>

using namespace commandline;

// save the image as screenshot
Expand All @@ -23,6 +25,8 @@ void saveScreenshot(QString filename, const Image<ColorRgb> & image)

int main(int argc, char ** argv)
{
DefaultSignalHandler::install();

QCoreApplication app(argc, argv);

try
Expand Down
3 changes: 3 additions & 0 deletions src/hyperion-remote/hyperion-remote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "HyperionConfig.h"
#include <commandline/Parser.h>
#include <utils/DefaultSignalHandler.h>

using namespace commandline;

Expand Down Expand Up @@ -66,6 +67,8 @@ int main(int argc, char * argv[])
<< "\tVersion : " << HYPERION_VERSION << " (" << HYPERION_BUILD_ID << ")" << std::endl
<< "\tbuild time: " << __DATE__ << " " << __TIME__ << std::endl;

DefaultSignalHandler::install();

QCoreApplication app(argc, argv);

// force the locale
Expand Down
Loading

0 comments on commit 3b48d8c

Please sign in to comment.