From 043f3ff3cf7af541f9ba64691462bc8b210d3e78 Mon Sep 17 00:00:00 2001 From: g0dil <g0dil@wiback.org> Date: Thu, 22 Jan 2009 09:00:12 +0000 Subject: [PATCH] Utils/Console: Add 'sys/backtrace' command --- Scheduler/FdEvent.cc | 2 +- Utils/Console/ParsedCommand.hh | 3 ++- Utils/Console/Server.cc | 36 +++++++++++++++++++++++++++++----- Utils/Console/Server.cci | 6 ++++++ Utils/Console/Server.hh | 12 +++++++++++- 5 files changed, 51 insertions(+), 8 deletions(-) diff --git a/Scheduler/FdEvent.cc b/Scheduler/FdEvent.cc index b6a5a4e8..9cfb4108 100644 --- a/Scheduler/FdEvent.cc +++ b/Scheduler/FdEvent.cc @@ -163,7 +163,7 @@ prefix_ void senf::scheduler::FdEvent::signal(int events) 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))); 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) i->setRunnable(); } diff --git a/Utils/Console/ParsedCommand.hh b/Utils/Console/ParsedCommand.hh index 67b8daa4..ba0bbca5 100644 --- a/Utils/Console/ParsedCommand.hh +++ b/Utils/Console/ParsedCommand.hh @@ -571,7 +571,8 @@ namespace console { template <class Signature> 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> typename detail::ParsedCommandTraits<Function>::Attributor diff --git a/Utils/Console/Server.cc b/Utils/Console/Server.cc index cbc8acab..719f527b 100644 --- a/Utils/Console/Server.cc +++ b/Utils/Console/Server.cc @@ -37,6 +37,9 @@ #include "../../Utils/membind.hh" #include "../../Utils/Logger/SenfLog.hh" #include "LineEditor.hh" +#include "ScopedDirectory.hh" +#include "Sysdir.hh" +#include "ParsedCommand.hh" //#include "Server.mpp" #define prefix_ @@ -286,17 +289,20 @@ prefix_ std::string::size_type senf::console::Client::handleInput(std::string da _1 )); } catch (Executor::ExitException &) { - // This generates an EOF condition on the Handle. This EOF condition is expected - // to be handled gracefully by the ClientReader. We cannot call stop() here, since we - // are called from the client reader callback and that will continue executing even if we - // call stop here ... + // This generates an EOF condition on the Handle. This EOF condition is expected to be + // handled gracefully by the ClientReader. We cannot call stop() here, since we are called + // from the client reader callback and that will continue executing after stop() has been + // called. stop() however will delete *this instance ... BANG ... handle_.facet<senf::TCPSocketProtocol>().shutdown(senf::TCPSocketProtocol::ShutRD); } catch (std::exception & ex) { std::string msg (ex.what()); 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); + } else + backtrace_.clear(); stream() << msg << std::endl; } catch (...) { @@ -343,6 +349,26 @@ prefix_ std::ostream & senf::console::operator<<(std::ostream & os, Client * cli 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//////////////////////////////////////// #undef prefix_ //#include "Server.mpp" diff --git a/Utils/Console/Server.cci b/Utils/Console/Server.cci index fb6e82da..62e6fade 100644 --- a/Utils/Console/Server.cci +++ b/Utils/Console/Server.cci @@ -157,6 +157,12 @@ prefix_ void senf::console::Client::write(std::string const & 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) { return dynamic_cast<detail::NonblockingSocketOStream&>(os)->client(); diff --git a/Utils/Console/Server.hh b/Utils/Console/Server.hh index 431221be..7d0a10de 100644 --- a/Utils/Console/Server.hh +++ b/Utils/Console/Server.hh @@ -176,6 +176,7 @@ namespace console { DirectoryNode & cwd() const; Server::Mode mode() const; void write(std::string const & data) const; + std::string const & backtrace() const; static Client & get(std::ostream & os); @@ -186,7 +187,7 @@ namespace console { void setInteractive(); void setNoninteractive(); - + size_t handleInput(std::string input, bool incremental = false); virtual void v_write(senf::log::time_type timestamp, std::string const & stream, std::string const & area, unsigned level, @@ -202,10 +203,19 @@ namespace console { std::string lastCommand_; boost::scoped_ptr<detail::ClientReader> reader_; Server::Mode mode_; + std::string backtrace_; friend class Server; friend class detail::ClientReader; 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 -- GitLab