Utils/Console: Add 'sys/backtrace' command
g0dil [Thu, 22 Jan 2009 09:00:12 +0000 (09:00 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1068 270642c3-0616-0410-b53a-bc976706d245

Scheduler/FdEvent.cc
Utils/Console/ParsedCommand.hh
Utils/Console/Server.cc
Utils/Console/Server.cci
Utils/Console/Server.hh

index b6a5a4e..9cfb410 100644 (file)
@@ -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();
     }
index 67b8daa..ba0bbca 100644 (file)
@@ -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
index cbc8aca..719f527 100644 (file)
@@ -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"
index fb6e82d..62e6fad 100644 (file)
@@ -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();
index 431221b..7d0a10d 100644 (file)
@@ -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