Skip to content
Snippets Groups Projects
Commit 043f3ff3 authored by g0dil's avatar g0dil
Browse files

Utils/Console: Add 'sys/backtrace' command

parent 7e4d08b7
No related branches found
No related tags found
No related merge requests found
...@@ -163,7 +163,7 @@ prefix_ void senf::scheduler::FdEvent::signal(int events) ...@@ -163,7 +163,7 @@ prefix_ void senf::scheduler::FdEvent::signal(int events)
detail::FdDispatcher::FdSet::iterator const i_end (detail::FdDispatcher::instance().fds_.end()); detail::FdDispatcher::FdSet::iterator const i_end (detail::FdDispatcher::instance().fds_.end());
bool all ((events & (EV_ERR | EV_HUP)) && ! (events & (EV_READ | EV_PRIO | EV_WRITE))); bool all ((events & (EV_ERR | EV_HUP)) && ! (events & (EV_READ | EV_PRIO | EV_WRITE)));
for (; i != i_end && fd_ == i->fd_; ++i) { for (; i != i_end && fd_ == i->fd_; ++i) {
i->signaledEvents_ = events; i->signaledEvents_ = events & (EV_ERR | EV_HUP | i->events_);
if (i->events_ & events || all) if (i->events_ & events || all)
i->setRunnable(); i->setRunnable();
} }
......
...@@ -571,7 +571,8 @@ namespace console { ...@@ -571,7 +571,8 @@ namespace console {
template <class Signature> template <class Signature>
typename detail::ParsedCommandTraits<Signature>::Attributor typename detail::ParsedCommandTraits<Signature>::Attributor
senf_console_add_node(DirectoryNode & node, std::string const & name, boost::function<Signature> fn, int); senf_console_add_node(DirectoryNode & node, std::string const & name,
boost::function<Signature> fn, int);
template <class Owner, class Function> template <class Owner, class Function>
typename detail::ParsedCommandTraits<Function>::Attributor typename detail::ParsedCommandTraits<Function>::Attributor
......
...@@ -37,6 +37,9 @@ ...@@ -37,6 +37,9 @@
#include "../../Utils/membind.hh" #include "../../Utils/membind.hh"
#include "../../Utils/Logger/SenfLog.hh" #include "../../Utils/Logger/SenfLog.hh"
#include "LineEditor.hh" #include "LineEditor.hh"
#include "ScopedDirectory.hh"
#include "Sysdir.hh"
#include "ParsedCommand.hh"
//#include "Server.mpp" //#include "Server.mpp"
#define prefix_ #define prefix_
...@@ -286,17 +289,20 @@ prefix_ std::string::size_type senf::console::Client::handleInput(std::string da ...@@ -286,17 +289,20 @@ prefix_ std::string::size_type senf::console::Client::handleInput(std::string da
_1 )); _1 ));
} }
catch (Executor::ExitException &) { catch (Executor::ExitException &) {
// This generates an EOF condition on the Handle. This EOF condition is expected // This generates an EOF condition on the Handle. This EOF condition is expected to be
// to be handled gracefully by the ClientReader. We cannot call stop() here, since we // handled gracefully by the ClientReader. We cannot call stop() here, since we are called
// are called from the client reader callback and that will continue executing even if we // from the client reader callback and that will continue executing after stop() has been
// call stop here ... // called. stop() however will delete *this instance ... BANG ...
handle_.facet<senf::TCPSocketProtocol>().shutdown(senf::TCPSocketProtocol::ShutRD); handle_.facet<senf::TCPSocketProtocol>().shutdown(senf::TCPSocketProtocol::ShutRD);
} }
catch (std::exception & ex) { catch (std::exception & ex) {
std::string msg (ex.what()); std::string msg (ex.what());
std::string::size_type i (msg.find("-- \n")); std::string::size_type i (msg.find("-- \n"));
if (i != std::string::npos) if (i != std::string::npos) {
backtrace_ = msg.substr(0,i);
msg = msg.substr(i+4); msg = msg.substr(i+4);
} else
backtrace_.clear();
stream() << msg << std::endl; stream() << msg << std::endl;
} }
catch (...) { catch (...) {
...@@ -343,6 +349,26 @@ prefix_ std::ostream & senf::console::operator<<(std::ostream & os, Client * cli ...@@ -343,6 +349,26 @@ prefix_ std::ostream & senf::console::operator<<(std::ostream & os, Client * cli
return os << *client; return os << *client;
} }
///////////////////////////////////////////////////////////////////////////
// senf::console::Client::SysBacktrace
prefix_ senf::console::Client::SysBacktrace::SysBacktrace()
{
sysdir().node().add("backtrace", &SysBacktrace::backtrace)
.doc("Display the backtrace of the last error / exception in this console");
}
prefix_ void senf::console::Client::SysBacktrace::backtrace(std::ostream & os)
{
Client & client (Client::get(os));
if (client.backtrace().empty())
os << "(no backtrace)";
else
os << client.backtrace();
}
senf::console::Client::SysBacktrace senf::console::Client::SysBacktrace::instance_;
///////////////////////////////cc.e//////////////////////////////////////// ///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_ #undef prefix_
//#include "Server.mpp" //#include "Server.mpp"
......
...@@ -157,6 +157,12 @@ prefix_ void senf::console::Client::write(std::string const & data) ...@@ -157,6 +157,12 @@ prefix_ void senf::console::Client::write(std::string const & data)
reader_->write(data); reader_->write(data);
} }
prefix_ std::string const & senf::console::Client::backtrace()
const
{
return backtrace_;
}
prefix_ senf::console::Client & senf::console::Client::get(std::ostream & os) prefix_ senf::console::Client & senf::console::Client::get(std::ostream & os)
{ {
return dynamic_cast<detail::NonblockingSocketOStream&>(os)->client(); return dynamic_cast<detail::NonblockingSocketOStream&>(os)->client();
......
...@@ -176,6 +176,7 @@ namespace console { ...@@ -176,6 +176,7 @@ namespace console {
DirectoryNode & cwd() const; DirectoryNode & cwd() const;
Server::Mode mode() const; Server::Mode mode() const;
void write(std::string const & data) const; void write(std::string const & data) const;
std::string const & backtrace() const;
static Client & get(std::ostream & os); static Client & get(std::ostream & os);
...@@ -186,7 +187,7 @@ namespace console { ...@@ -186,7 +187,7 @@ namespace console {
void setInteractive(); void setInteractive();
void setNoninteractive(); void setNoninteractive();
size_t handleInput(std::string input, bool incremental = false); size_t handleInput(std::string input, bool incremental = false);
virtual void v_write(senf::log::time_type timestamp, std::string const & stream, virtual void v_write(senf::log::time_type timestamp, std::string const & stream,
std::string const & area, unsigned level, std::string const & area, unsigned level,
...@@ -202,10 +203,19 @@ namespace console { ...@@ -202,10 +203,19 @@ namespace console {
std::string lastCommand_; std::string lastCommand_;
boost::scoped_ptr<detail::ClientReader> reader_; boost::scoped_ptr<detail::ClientReader> reader_;
Server::Mode mode_; Server::Mode mode_;
std::string backtrace_;
friend class Server; friend class Server;
friend class detail::ClientReader; friend class detail::ClientReader;
friend class detail::NonblockingSocketSink; friend class detail::NonblockingSocketSink;
class SysBacktrace
{
SysBacktrace();
static void backtrace(std::ostream & os);
static SysBacktrace instance_;
};
}; };
/** \brief Output Console Client instance as it's string representation /** \brief Output Console Client instance as it's string representation
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment