[Python-checkins] r47111 - in sandbox/trunk/pdb: mconnection.py mpdb.py mthread.py test/test_mconnection.py test/test_mpdb.py test/thread_script.py

matt.fleming python-checkins at python.org
Tue Jun 27 00:08:11 CEST 2006


Author: matt.fleming
Date: Tue Jun 27 00:08:11 2006
New Revision: 47111
Added:
 sandbox/trunk/pdb/test/thread_script.py
Modified:
 sandbox/trunk/pdb/mconnection.py
 sandbox/trunk/pdb/mpdb.py
 sandbox/trunk/pdb/mthread.py
 sandbox/trunk/pdb/test/test_mconnection.py
 sandbox/trunk/pdb/test/test_mpdb.py
Log:
start implementing the thread command and of course, unit tests ;-)
Modified: sandbox/trunk/pdb/mconnection.py
==============================================================================
--- sandbox/trunk/pdb/mconnection.py	(original)
+++ sandbox/trunk/pdb/mconnection.py	Tue Jun 27 00:08:11 2006
@@ -57,8 +57,8 @@
 """
 self._dev = device
 try:
- self.output = open(self._dev, 'w')
 self.input = open(self._dev, 'r')
+ self.output = open(self._dev, 'w')
 except IOError,e:
 # Use e[1] for more detail about why the connection failed
 raise ConnectionFailed, e[1]
Modified: sandbox/trunk/pdb/mpdb.py
==============================================================================
--- sandbox/trunk/pdb/mpdb.py	(original)
+++ sandbox/trunk/pdb/mpdb.py	Tue Jun 27 00:08:11 2006
@@ -53,6 +53,7 @@
 self.waiter = threading.Event()
 self.tracers = []
 self.threads = []
+ self.current_thread = threading.currentThread()
 self._info_cmds.append('target')
 
 def _rebind_input(self, new_input):
@@ -151,12 +152,10 @@
 return # Thread not being traced
 
 self.threads.append(threading.currentThread())
- self.msg('New thread: %s' % self.threads[-1].getName())
- m = MTracer(self.stdout)
+ self.msg('New thread: %s' % self.threads[-1])
+ m = MTracer(self.breaks, self.stdout)
 self.tracers.append(m)
 sys.settrace(m.trace_dispatch)
- 
- 
 
 # Debugger commands
 def do_attach(self, addr):
@@ -232,7 +231,7 @@
 self.errmsg('Unknown target type')
 return 
 self.connection = eval(target+'()')
- try: 
+ try:
 self.connection.connect(addr)
 except ConnectionFailed, err:
 self.errmsg("Failed to connect to %s: (%s)" % (addr, err))
@@ -324,6 +323,39 @@
 self._rebind_input(self.connection)
 self._rebind_output(self.connection)
 
+ def do_thread(self, arg):
+ """Use this command to switch between threads.
+The new thread ID must be currently known.
+
+List of thread subcommands:
+
+thread apply -- Apply a command to a thread
+
+Type "help thread" followed by thread subcommand name for full documentation.
+Command name abbreviations are allowed if unambiguous.
+"""
+ args = arg.split()
+ if len(args) == 0:
+ self.msg('Current thread is %s' % self.current_thread)
+ return
+ if 'apply'.startswith(args[0]):
+ if len(args) < 2:
+ self.errmsg('Please specify a thread ID')
+ return
+ if len(args) < 3:
+ self.errmsg('Please specify a command following the thread' \
+ + ' ID')
+ return
+ # These should always be in sync
+ if len(self.threads) == 0:
+ self.errmsg('No threads')
+ return
+ t = self.threads[int(args[1])-1]
+ t_tracer = self.tracers[int(args[1])-1]
+ func = args[2]
+ cmd = eval('t.' + func)
+ result = cmd(args[3:])
+
 def pdbserver(addr):
 """ This method sets up a pdbserver debugger that allows debuggers
 to connect to 'address' using 'protocol'. The argument 'filename'
Modified: sandbox/trunk/pdb/mthread.py
==============================================================================
--- sandbox/trunk/pdb/mthread.py	(original)
+++ sandbox/trunk/pdb/mthread.py	Tue Jun 27 00:08:11 2006
@@ -1,18 +1,60 @@
 """ This file contains all code for allowing the debugging of threads. """
 
+from bdb import Breakpoint
+import os
 import sys
 import threading
 
 class MTracer(object):
- """ A class to trace a thread. """
- def __init__(self, stdout=None):
+ """ A class to trace a thread. Breakpoints can be passed from
+ a main debugger to this debugger through the constructor
+ which is useful, for instance, if a breakpoint occurs inside
+ a thread's run() method.
+ """
+ def __init__(self, breaks=None, stdout=None):
 self.thread = threading.currentThread()
- # No other thread can be debugged whilst this is set
- # (including the MainThread)
 if stdout is None:
 stdout = sys.stdout
 self.out = stdout
+ # Each tracer instance must keep track of its own breakpoints
+ if breaks is None:
+ breaks = {}
+ self.breaks = breaks
+ self.fncache = {}
+
+ def canonic(self, filename):
+ if filename == "<" + filename[1:-1] + ">":
+ return filename
+ canonic = self.fncache.get(filename)
+ if not canonic:
+ canonic = os.path.abspath(filename)
+ canonic = os.path.normcase(canonic)
+ self.fncache[filename] = canonic
+ return canonic
+
+ def info(self, arg):
+ args = arg.split()
+ if 'break'.startswith(args[0]):
+ return self.breaks
+ 
+ def _get_break(self, filename, lineno):
+ """ Return the breakpoint at [filename:]lineno. """
+ filename = self.canonic(filename)
+ return filename in self.breaks and \
+ lineno in self.breaks[filename]
+
+ def _get_breaks(self, filename, lineno):
+ """ Return all the breakpoints set in this thread. """
+ filename = self.canonic(filename)
+ return filename in self.breaks and \
+ lineno in self.breaks[filename] and \
+ Breakpoint.bplist[filename, lineno] or []
 
+ def _set_break(self, filename, lineno, temporary=0, cond = None,
+ funcname=None):
+ """ Set a breakpoint in this thread. """
+ pass
+ 
 def trace_dispatch(self, frame, event, arg):
 if event == 'line':
 print >> self.out, self.thread.getName(),'*** line'
Modified: sandbox/trunk/pdb/test/test_mconnection.py
==============================================================================
--- sandbox/trunk/pdb/test/test_mconnection.py	(original)
+++ sandbox/trunk/pdb/test/test_mconnection.py	Tue Jun 27 00:08:11 2006
@@ -57,6 +57,7 @@
 def testDisconnectDisconnected(self):
 """(tcp) Disconnect a disconnected session. """
 s = MConnectionServerTCP()
+
 s.disconnect()
 s.disconnect()
 
@@ -142,6 +143,12 @@
 line = self.server.readline()
 self.assertEquals('', line, 'Could not read third line.')
 
+ def testInvalidFilename(self):
+ """(serial) Connect to an invalid server. """
+ client = MConnectionSerial()
+ self.assertRaises(ConnectionFailed, client.connect,
+ '/dev/pleasepleasepleasedontexit')
+
 def tearDown(self):
 self.server.disconnect()
 self.client.disconnect()
Modified: sandbox/trunk/pdb/test/test_mpdb.py
==============================================================================
--- sandbox/trunk/pdb/test/test_mpdb.py	(original)
+++ sandbox/trunk/pdb/test/test_mpdb.py	Tue Jun 27 00:08:11 2006
@@ -40,6 +40,7 @@
 def __init__(self):
 MPdb.__init__(self)
 self.lines = []
+ self.botframe = None
 
 def msg_nocr(self, msg):
 self.lines.append(msg)
@@ -70,7 +71,6 @@
 line = self.server2.lines[0]
 self.assertEquals('*** Unknown protocol\n', line)
 
- 
 def testTarget(self):
 """ Test the target command. """
 server = MConnectionServerTCP()
@@ -80,13 +80,25 @@
 connect_to_target(self.client1)
 
 self.client2 = MPdbTest()
-
 self.client2.do_target('dlkdlksldkslkd')
 line = self.client2.lines[0]
 self.assertEquals('*** Invalid arguments\n', line)
 
+ # Hope there's nothing running on this port
+ self.client2.do_target('tcp localhost:9000')
+ line = self.client2.lines[1]
+ errmsg = '*** Failed to connect to localhost:9000: (Connection' \
+ + ' refused)\n'
+ self.assertEquals(errmsg, line)
+
+ addr = 'serial /dev/hopefullythisdevicenamedoesntexist'
+ self.client2.do_target(addr)
+ line = self.client2.lines[2]
+ errmsg = '*** Failed to connect to ' \
+ + '/dev/hopefullythisdevicenamedoesntexist:' \
+ + ' (No such file or directory)\n'
 
- self.client3 = MPdbTest()
+ self.assertEquals(errmsg, line)
 
 server.disconnect()
 
@@ -102,7 +114,6 @@
 line = f.readline()
 f.close()
 self.assertEquals('some text\n', line, 'Could not rebind output')
-
 
 def testRebindInput(self):
 """ Test rebinding input. """
@@ -116,13 +127,39 @@
 self.server._rebind_input(f)
 line = self.server.stdin.readline()
 
+ f.close()
 self.assertEquals(line, 'help', 'Could not rebind input.')
 
- def testTargetRoutine(self):
- """ Test that the top-level target routine works properly. """
- #invalid_address = 'tcp ::::::'
- pass
+ def testThread(self):
+ """ Test the thread command. """
+ server = MConnectionServerTCP()
 
+ thread.start_new_thread(server.connect, (__addr__,))
+
+ self.client1 = MPdbTest()
+ connect_to_target(self.client1)
+ # Thread with no commands should return current thread
+ self.client1.onecmd('thread')
+ assert 'MainThread' in self.client1.lines[0]
+
+ # 'thread apply' without thread ID should return an error message
+ self.client1.onecmd('thread apply')
+ line = self.client1.lines[1]
+ self.assertEquals('*** Please specify a thread ID\n', line)
+
+ # Need a command to actually apply to a thread
+ self.client1.onecmd('thread apply 49843')
+ line = self.client1.lines[2]
+ errmsg = '*** Please specify a command following the thread ID\n'
+ self.assertEquals(errmsg, line)
+
+ # We've still not started any threads
+ self.client1.onecmd('thread apply 2 info break')
+ line = self.client1.lines[3]
+ errmsg = '*** No threads\n'
+ self.assertEquals(errmsg, line)
+ 
+ server.disconnect()
 
 def test_main():
 test_support.run_unittest(TestRemoteDebugging)
Added: sandbox/trunk/pdb/test/thread_script.py
==============================================================================
--- (empty file)
+++ sandbox/trunk/pdb/test/thread_script.py	Tue Jun 27 00:08:11 2006
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+""" This is a script that is being used to debug whilst trying to get
+the thread debugging features working.
+"""
+
+import threading
+
+class MyThread(threading.Thread):
+ def run(self):
+ for i in range(10):
+ print i
+
+def func():
+ t = MyThread()
+ t.start()
+ t.join()
+
+if __name__ == '__main__':
+ func()
+
+ 


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /