[Neo-report] r2061 vincent - in /trunk/neo: live_debug.py master/app.py storage/app.py

nobody at svn.erp5.org nobody at svn.erp5.org
Tue May 4 17:18:50 CEST 2010


Author: vincent
Date: Tue May  4 17:18:50 2010
New Revision: 2061

Log:
Add "live" debugging facility.

Disabled by default, as it allows code injection in NEO processes to
anyone with the ability to send signals to them and either write access to
NEO product or its controlling TTY.

Added:
    trunk/neo/live_debug.py
Modified:
    trunk/neo/master/app.py
    trunk/neo/storage/app.py

Added: trunk/neo/live_debug.py
==============================================================================
--- trunk/neo/live_debug.py (added)
+++ trunk/neo/live_debug.py [iso-8859-1] Tue May  4 17:18:50 2010
@@ -1,0 +1,63 @@
+#
+# Copyright (C) 2010  Nexedi SA
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+import traceback
+import signal
+import imp
+import neo
+import pdb
+
+# WARNING: This module should only be used for live application debugging.
+# It - by purpose - allows code injection in a running neo process.
+# You don't want to enable it in a production environment. Really.
+ENABLED = False
+
+# How to include in python code:
+#   from neo.live_debug import register
+#   register()
+#
+# How to trigger it:
+#   Kill python process with:
+#     SIGUSR1:
+#       Loads (or reloads) neo.debug module.
+#       The content is up to you (it's only imported).
+#     SIGUSR2:
+#       Triggers a pdb prompt on process' controlling TTY.
+
+def debugHandler(sig, frame):
+    try:
+        file, filename, (suffix, mode, type) = imp.find_module('debug',
+            neo.__path__)
+        imp.load_module('neo.debug', file, filename, (suffix, mode, type))
+    except:
+        # Prevent exception from exiting signal handler, so mistakes in
+        # "debug" module don't kill process.
+        traceback.print_exception()
+
+def pdbHandler(sig, frame):
+    try:
+        pdb.set_trace()
+    except:
+        # Prevent exception from exiting signal handler, so mistakes in
+        # pdb don't kill process.
+        traceback.print_exception()
+
+def register():
+    if ENABLED:
+        signal.signal(signal.SIGUSR1, debugHandler)
+        signal.signal(signal.SIGUSR2, pdbHandler)
+

Modified: trunk/neo/master/app.py
==============================================================================
--- trunk/neo/master/app.py [iso-8859-1] (original)
+++ trunk/neo/master/app.py [iso-8859-1] Tue May  4 17:18:50 2010
@@ -37,6 +37,8 @@
 from neo.util import dump
 from neo.connector import getConnectorHandler
 
+from neo.live_debug import register as registerLiveDebugger
+
 class Application(object):
     """The master node application."""
 
@@ -90,6 +92,8 @@
         self.negotiating_master_node_set = set()
 
         self._current_manager = None
+
+        registerLiveDebugger()
 
     def run(self):
         """Make sure that the status is sane and start a loop."""

Modified: trunk/neo/storage/app.py
==============================================================================
--- trunk/neo/storage/app.py [iso-8859-1] (original)
+++ trunk/neo/storage/app.py [iso-8859-1] Tue May  4 17:18:50 2010
@@ -34,6 +34,8 @@
 from neo.util import dump
 from neo.bootstrap import BootstrapManager
 
+from neo.live_debug import register as registerLiveDebugger
+
 class Application(object):
     """The storage node application."""
 
@@ -82,6 +84,8 @@
         # force node uuid from command line argument, for testing purpose only
         if config.getUUID() is not None:
             self.uuid = config.getUUID()
+
+        registerLiveDebugger()
 
     def loadConfiguration(self):
         """Load persistent configuration data from the database.





More information about the Neo-report mailing list