mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
* Print stack trace on crash * Printing stack trace is fully functional except for WIN32 * Minor fixes * Minor fixes
This commit is contained in:
@@ -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()
|
||||
|
@@ -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());
|
||||
|
@@ -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 )
|
||||
|
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
@@ -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();
|
||||
|
@@ -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()
|
||||
@@ -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));
|
||||
|
||||
if (getPriorityInfo(priority).componentId != hyperion::COMP_COLOR)
|
||||
clear(priority);
|
||||
|
@@ -36,7 +36,7 @@ LedDevice::LedDevice(const QJsonObject& config, QObject* parent)
|
||||
|
||||
LedDevice::~LedDevice()
|
||||
{
|
||||
_refresh_timer->deleteLater();
|
||||
delete _refresh_timer;
|
||||
}
|
||||
|
||||
int LedDevice::open()
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
132
libsrc/utils/DefaultSignalHandler.cpp
Normal file
132
libsrc/utils/DefaultSignalHandler.cpp
Normal file
@@ -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
|
Reference in New Issue
Block a user