def demo_setup(): Mmock = import_relative('mock', '..') Mshow = import_relative('show', '..') Mdebugger = import_relative('debugger', '....') d, cp = Mmock.dbg_setup() mgr = Mshow.ShowCommand(cp) return mgr
def demo_setup(): Mmock = import_relative('mock', '..') Mset = import_relative('set', '..') Mdebugger = import_relative('debugger', '....') d, cp = Mmock.dbg_setup() mgr = Mset.SetCommand(cp) return mgr
def __init__(self, inp=None, out=None, opts={}): get_option = lambda key: Mmisc.option_set(opts, key, DEFAULT_USER_SETTINGS) Minput = import_relative('input', '..inout', 'trepan') Moutput = import_relative('output', '..inout', 'trepan') atexit.register(self.finalize) self.interactive = True # Or at least so we think initially self.input = inp or Minput.DebuggerUserInput() self.output = out or Moutput.DebuggerUserOutput() if self.input.use_history(): complete = get_option('complete') if complete: parse_and_bind("tab: complete") set_completer(complete) pass self.histfile = get_option('histfile') if self.histfile: try: read_history_file(histfile) except IOError: pass set_history_length(50) atexit.register(write_history_file, self.histfile) pass return
def demo_setup(): Mmock = import_relative("mock", "..") Mshow = import_relative("show", "..") Mdebugger = import_relative("debugger", "....") d, cp = Mmock.dbg_setup() mgr = Mshow.ShowCommand(cp) return mgr
def test_list_command(self): import inspect cmdproc = import_relative('processor.cmdproc', '...trepan', 'trepan') debugger = import_relative('debugger', '...trepan', 'trepan') d = debugger.Trepan() cp = d.core.processor cp.curframe = inspect.currentframe() self.cmd = Mlist.ListCommand(cp) self.cmd.msg = self.msg self.cmd.errmsg = self.errmsg d.settings['listsize'] = self.listsize d.settings['highlight'] = 'plain' # Simple list command. self.clear_run_check(['list'], list(range(1, self.listsize+1))) # Check 2nd set of consecutive lines self.clear_run_check(['list'], list(range(self.listsize+1, (2*self.listsize)+1))) # Try going backwards. self.clear_run_check(['list', '-'], list(range(1, self.listsize+1))) # And again. Since we hit the beginning it's the same as before self.clear_run_check(['list', '-'], list(range(1, self.listsize+1))) # BUG Simple arithmetic expression # self.clear_run_check(['list', '4+1'], range(4+1, 4+1+listsize)) # List first last self.clear_run_check(['list', '10', '20'], list(range(10, 21))) # List first count self.clear_run_check(['list', '10', '5'], list(range(10, 15))) # Module # BUG? without '1' below the default starts with self.listsize+1 self.clear_run_check(['os.path', '1'], list(range(1, self.listsize+1))) # Function self.clear_run_checksize(['list', 'os.path.join']) ## FIXME: reinstate ## self.clear_run_checksize(['list', 'self.setUp']) def foo(): pass self.clear_run_checksize(['list', 'foo']) # BUG # self.clear_run_check(['os.path:1'], range(1, self.listsize+1)) self.clear_run_check(['os.path', '10', '5'], list(range(10, 15))) # Use a file name self.clear_run_check(['list', __file__+':3', '4'], list(range(3, 5))) # BUGS - but possibly the windowing thing is happening? # self.clear_run_check(['list', __file__, '3'], list(range(3, 5))) # self.clear_run_check(['list', __file__, '20', '4'], list(range(20, 24))) # self.clear_run_check(['list', __file__, '3', '4'], list(range(3, 5))) return
def setUp(self): self.errors = [] self.msgs = [] import_relative('processor.cmdproc', '...trepan', 'trepan') Mdebugger = import_relative('debugger', '...trepan', 'trepan') d = Mdebugger.Trepan() self.cmdproc = d.core.processor self.cmdproc.curframe = inspect.currentframe() cmd = self.cmdproc.commands['alias'] cmd.msg = self.msg cmd.errmsg = self.errmsg cmd = self.cmdproc.commands['unalias'] cmd.msg = self.msg cmd.errmsg = self.errmsg return
def test_parse_break_cmd(self): import inspect, types debugger = import_relative('debugger', '...trepan') d = debugger.Trepan() cp = d.core.processor cp.curframe = inspect.currentframe() self.cmd = Mbreak.BreakCommand(cp) self.cmd.msg = self.msg self.cmd.errmsg = self.errmsg fn, fi, li, cond = Mcmdbreak.parse_break_cmd(self.cmd, []) self.assertEqual((None, True, True), (fn, fi.endswith('test-break.py'), li > 1)) fn, fi, li, cond = Mcmdbreak.parse_break_cmd(self.cmd, ['11-1']) self.assertEqual((None, True, 10), (fn, fi.endswith('test-break.py'), li)) fn, fi, li, cond = Mcmdbreak.parse_break_cmd(self.cmd, [__file__ + ':10']) self.assertEqual((None, 10), (fn, li)) def foo(): return 'bar' fn, fi, li, cond = Mcmdbreak.parse_break_cmd(self.cmd, ['foo']) self.assertEqual((foo, True, True), (fn, fi.endswith('test-break.py'), li > 1)) fn, fi, li, cond = Mcmdbreak.parse_break_cmd(self.cmd, ['food']) self.assertEqual((None, None, None, None), (fn, fi, li, cond)) fn, fi, li, cond = Mcmdbreak.parse_break_cmd(self.cmd, ['os.path']) self.assertEqual((None, None), (fn, li)) fn, fi, li, cond = Mcmdbreak.parse_break_cmd(self.cmd, ['os.path', '5+1']) self.assertEqual((None, 6), (fn, li)) fn, fi, li, cond = Mcmdbreak.parse_break_cmd(self.cmd, ['os.path.join']) self.assertEqual((os.path.join, True), (fn, li > 1)) fn, fi, li, cond = Mcmdbreak.parse_break_cmd(self.cmd, ['if', 'True']) self.assertEqual((None, True, True), (fn, fi.endswith('test-break.py'), li > 1)) fn, fi, li, cond = Mcmdbreak.parse_break_cmd(self.cmd, ['foo', 'if', 'True']) self.assertEqual((foo, True, True), (fn, fi.endswith('test-break.py'), li > 1)) fn, fi, li, cond = Mcmdbreak.parse_break_cmd(self.cmd, ['os.path:10', 'if', 'True']) self.assertEqual(10, li) # FIXME: # Try a breakpoint with a symlink in the filename. # Also, add a unit test for canonic. return
def _populate_commands(self): """ Create an instance of each of the debugger commands. Commands are found by importing files in the directory 'command'. Some files are excluded via an array set in __init__. For each of the remaining files, we import them and scan for class names inside those files and for each class name, we will create an instance of that class. The set of DebuggerCommand class instances form set of possible debugger commands.""" cmd_instances = [] Mcommand = import_relative('command') eval_cmd_template = 'command_mod.%s(self)' srcdir = get_srcdir() sys.path.insert(0, srcdir) for mod_name in Mcommand.__modules__: if mod_name in ( 'info_sub', 'set_sub', 'show_sub', ): pass import_name = "command." + mod_name if False: # Sometimes we want this command_mod = getattr(__import__(import_name), mod_name) else: # FIXME give more info like the above when desired # For debugging: # command_mod = getattr(__import__(import_name), mod_name) try: command_mod = getattr(__import__(import_name), mod_name) except: print('Error importing %s: %s' % (mod_name, sys.exc_info()[0])) continue pass classnames = [ tup[0] for tup in inspect.getmembers(command_mod, inspect.isclass) if ('DebuggerCommand' != tup[0] and tup[0].endswith('Command')) ] for classname in classnames: eval_cmd = eval_cmd_template % classname if False: instance = eval(eval_cmd) cmd_instances.append(instance) else: try: instance = eval(eval_cmd) cmd_instances.append(instance) except: print('Error loading %s from %s: %s' % (classname, mod_name, sys.exc_info()[0])) pass pass pass pass sys.path.remove(srcdir) return cmd_instances
def _load_debugger_subcommands(self, name): """ Create an instance of each of the debugger subcommands. Commands are found by importing files in the directory 'name' + 'sub'. Some files are excluded via an array set in __init__. For each of the remaining files, we import them and scan for class names inside those files and for each class name, we will create an instance of that class. The set of DebuggerCommand class instances form set of possible debugger commands.""" # Initialization cmd_instances = [] module_dir = name + '_subcmd' class_prefix = string.capitalize(name) # e.g. Info, Set, or Show mod = import_relative(module_dir) eval_cmd_template = 'command_mod.%s(self)' srcdir = get_srcdir() sys.path.insert(0, srcdir) sub_srcdir = os.path.join(srcdir, module_dir) sys.path.insert(0, sub_srcdir) # Import, instantiate, and add classes for each of the # modules found in module_dir imported above. for module_name in mod.__modules__: import_name = module_dir + '.' + module_name command_mod = getattr(__import__(import_name), module_name) try: command_mod = getattr(__import__(import_name), module_name) except ImportError: print("Error importing name %s module %s: %s" % (import_name, module_name, sys.exc_info()[0])) continue # Even though we tend not to do this, it is possible to # put more than one class into a module/file. So look for # all of them. classnames = [ classname for classname, classvalue in inspect.getmembers( command_mod, inspect.isclass) if ('DebuggerCommand' != classname and classname.startswith(class_prefix)) ] for classname in classnames: eval_cmd = eval_cmd_template % classname try: instance = eval(eval_cmd) self.cmds.add(instance) except: print "Error eval'ing class %s" % classname pass pass pass sys.path.remove(srcdir) sys.path.remove(sub_srcdir) return cmd_instances
def _load_debugger_subcommands(self, name): """ Create an instance of each of the debugger subcommands. Commands are found by importing files in the directory 'name' + 'sub'. Some files are excluded via an array set in __init__. For each of the remaining files, we import them and scan for class names inside those files and for each class name, we will create an instance of that class. The set of DebuggerCommand class instances form set of possible debugger commands.""" # Initialization cmd_instances = [] module_dir = name + '_subcmd' class_prefix = string.capitalize(name) # e.g. Info, Set, or Show mod = import_relative(module_dir) eval_cmd_template = 'command_mod.%s(self)' srcdir = get_srcdir() sys.path.insert(0, srcdir) sub_srcdir = os.path.join(srcdir, module_dir) sys.path.insert(0, sub_srcdir) # Import, instantiate, and add classes for each of the # modules found in module_dir imported above. for module_name in mod.__modules__: import_name = module_dir + '.' + module_name command_mod = getattr(__import__(import_name), module_name) try: command_mod = getattr(__import__(import_name), module_name) except ImportError: print("Error importing name %s module %s: %s" % (import_name, module_name, sys.exc_info()[0])) continue # Even though we tend not to do this, it is possible to # put more than one class into a module/file. So look for # all of them. classnames = [ classname for classname, classvalue in inspect.getmembers(command_mod, inspect.isclass) if ('DebuggerCommand' != classname and classname.startswith(class_prefix)) ] for classname in classnames: eval_cmd = eval_cmd_template % classname try: instance = eval(eval_cmd) self.cmds.add(instance) except: print "Error eval'ing class %s" % classname pass pass pass sys.path.remove(srcdir) sys.path.remove(sub_srcdir) return cmd_instances
def test_pdef(self): import inspect import_relative('processor.cmdproc', '...trepan', 'trepan') debugger = import_relative('debugger', '...trepan', 'trepan') d = debugger.Trepan() cp = d.core.processor cp.curframe = inspect.currentframe() cmd = Mp.PrintDefCommand(cp) cmd.msg = self.msg cmd.errmsg = cp.errmsg = self.errmsg cmd.run(['pdef', 'self.test_pdef']) self.assertEqual('self.test_pdef(self)', self.msgs[-1]) cmd.run(['pdef', 'TestPDef']) self.assertEqual("TestPDef(self, methodName='runTest')", self.msgs[-1]) self.assertEqual(0, len(self.errors)) cmd.run(['pdef', 'FOO']) self.assertEqual(1, len(self.errors)) return
def _populate_commands(self): """ Create an instance of each of the debugger commands. Commands are found by importing files in the directory 'command'. Some files are excluded via an array set in __init__. For each of the remaining files, we import them and scan for class names inside those files and for each class name, we will create an instance of that class. The set of DebuggerCommand class instances form set of possible debugger commands.""" cmd_instances = [] Mcommand = import_relative('command') eval_cmd_template = 'command_mod.%s(self)' srcdir = get_srcdir() sys.path.insert(0, srcdir) for mod_name in Mcommand.__modules__: if mod_name in ('info_sub', 'set_sub', 'show_sub',): pass import_name = "command." + mod_name if False: # Sometimes we want this command_mod = getattr(__import__(import_name), mod_name) else: # FIXME give more info like the above when desired # For debugging: command_mod = getattr(__import__(import_name), mod_name) try: command_mod = getattr(__import__(import_name), mod_name) except: print('Error importing %s: %s' % (mod_name, sys.exc_info()[0])) continue pass classnames = [ tup[0] for tup in inspect.getmembers(command_mod, inspect.isclass) if ('DebuggerCommand' != tup[0] and tup[0].endswith('Command')) ] for classname in classnames: eval_cmd = eval_cmd_template % classname if False: instance = eval(eval_cmd) cmd_instances.append(instance) else: try: instance = eval(eval_cmd) cmd_instances.append(instance) except: print('Error loading %s from %s: %s' % (classname, mod_name, sys.exc_info()[0])) pass pass pass pass sys.path.remove(srcdir) return cmd_instances
def test_pr(self): import inspect debugger = import_relative('debugger', '...trepan', 'trepan') d = debugger.Debugger() cp = d.core.processor cp.curframe = inspect.currentframe() cmd = Mp.PrCommand(cp) cmd.msg = self.msg cmd.errmsg = self.errmsg me = 10 cmd.run([cmd.name, 'me']) self.assertEqual('10', self.msgs[-1]) cmd.run([cmd.name, '/x', 'me']) self.assertEqual("'0xa'", self.msgs[-1]) cmd.run([cmd.name, '/o', 'me']) self.assertEqual("'012'", self.msgs[-1]) return
def test_pr(self): import inspect debugger = import_relative('debugger', '...trepan', 'trepan') d = debugger.Debugger() cp = d.core.processor cp.curframe = inspect.currentframe() cmd = Mp.PrCommand(cp) cmd.msg = self.msg cmd.errmsg = self.errmsg me = 10 # NOQA cmd.run([cmd.name, 'me']) self.assertEqual('10', self.msgs[-1]) cmd.run([cmd.name, '/x', 'me']) self.assertEqual("'0xa'", self.msgs[-1]) cmd.run([cmd.name, '/o', 'me']) self.assertEqual("'012'", self.msgs[-1]) return
# it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>. """ Functions for working with Python frames""" import re, types from import_relative import import_relative Mbytecode = import_relative('bytecode', top_name='trepan') Mprint = import_relative('print', top_name='trepan') Mformat = import_relative('format', top_name='trepan') format_token = Mformat.format_token def count_frames(frame, count_start=0): "Return a count of the number of frames" count = -count_start while frame: count += 1 frame = frame.f_back return count import reprlib as Mrepr import inspect
def dbg_setup(d=None): if d is None: d = MockDebugger() bwproc = import_relative('main', os.path.pardir) cp = bwproc.BWProcessor(d.core) return d, cp
# the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>. import os # Our local modules from import_relative import import_relative Mbase_cmd = import_relative('base_cmd', top_name='trepan') Mcmdfns = import_relative('cmdfns', '..', 'trepan') Mfile = import_relative('file', '...lib', 'trepan') Mcmdbreak = import_relative('cmdbreak', '..', 'trepan') class BreakCommand(Mbase_cmd.DebuggerCommand): """**break** [*location*] [if *condition*]] With a line number argument, set a break there in the current file. With a function name, set a break at first executable line of that function. Without argument, set a breakpoint at current location. If a second argument is `if`, subsequent arguments given an expression which must evaluate to true before the breakpoint is honored. The location line number may be prefixed with a filename or module name and a colon. Files is searched for using *sys.path*, and the `.py`
#!/usr/bin/env python3 'Unit test for trepan.processor.command.help' import inspect, os, sys, unittest, types from import_relative import import_relative # FIXME: until import_relative is fixed import_relative('trepan', '...', 'trepan') Mhelp = import_relative('processor.command.help', '...trepan', 'trepan') Mcmdproc = import_relative('processor.cmdproc', '...trepan', 'trepan') from cmdhelper import dbg_setup import signal Mmock = import_relative('processor.command.mock', '...trepan') class TestHelp(unittest.TestCase): """Tests HelpCommand class""" def setUp(self): self.errors = [] self.msgs = [] self.d = Mmock.MockDebugger() self.cp = Mcmdproc.CommandProcessor(self.d.core) self.cp.intf[-1].msg = self.msg self.cp.intf[-1].errmsg = self.errmsg self.cmd = Mhelp.HelpCommand(self.cp) self.cmd.msg = self.msg self.cmd.errmsg = self.errmsg return
# (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 inspect, os, sys, types from import_relative import import_relative # Our local modules Mbase_cmd = import_relative('base_cmd', top_name='pydbgr') Mstack = import_relative('stack', '...lib', 'pydbgr') Mcmdfns = import_relative('cmdfns', '..', 'pydbgr') class WhatisCommand(Mbase_cmd.DebuggerCommand): '''**whatis** *arg* Prints the type of the argument which can be a Python expression.''' aliases = () category = 'data' min_args = 0 max_args = None name = os.path.basename(__file__).split('.')[0] need_stack = True short_help = 'Print data type of expression EXP'
# the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>. import os from import_relative import import_relative # Our local modules base_cmd = import_relative('base_cmd', top_name='trepan') Mcmdfns = import_relative('cmdfns', '..', 'trepan') Mstack = import_relative('stack', '...lib', 'trepan') class NextCommand(base_cmd.DebuggerCommand): aliases = ('next+', 'next-', 'n', 'n-', 'n+') category = 'running' execution_set = ['Running'] min_args = 0 max_args = 1 name = os.path.basename(__file__).split('.')[0] need_stack = True short_help = 'Step program without entering called functions'
#!/usr/bin/env python3 'Unit test for trepan.processor.command.kill' import unittest from import_relative import import_relative Mkill = import_relative('processor.command.kill', '...trepan') from cmdhelper import dbg_setup import signal class TestKill(unittest.TestCase): """Tests KillCommand class""" def setUp(self): self.signal_caught = False return def handle(self, *args): self.signal_caught = True return def test_kill(self): """Test processor.command.kill.KillCommand.run()""" signal.signal(28, self.handle) d, cp = dbg_setup() command = Mkill.KillCommand(cp) result = command.run(['kill', 'wrong', 'number', 'of', 'args']) self.assertFalse(result) self.assertFalse(self.signal_caught) result = command.run(['kill', '28'])
# # 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 os, re # Our local modules from import_relative import import_relative import_relative('processor', '....trepan') Mbase_cmd = import_relative('base_cmd', top_name='trepan') Mcmdproc = import_relative('cmdproc', '..', 'trepan') Mcomplete = import_relative('complete', '...lib') Mmisc = import_relative('misc', '...', 'trepan') categories = { 'breakpoints': 'Making the program stop at certain points', 'data': 'Examining data', 'files': 'Specifying and examining files', 'running': 'Running the program', 'status': 'Status inquiries', 'support': 'Support facilities', 'stack': 'Examining the call stack' }
# the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>. """Debugger input possibly attached to a user or interactive. """ import sys, types, StringIO from import_relative import import_relative Mmisc = import_relative('misc', '..') Mbase = import_relative('base', top_name='trepan') def readline_importable(): try: import readline return True except ImportError: return False return # Not reached class DebuggerUserInput(Mbase.DebuggerInputBase): """Debugger input connected to what we think of as a end-user input as opposed to a relay mechanism to another process. Input could be
#!/usr/bin/env python3 "General integration tests" import unittest from import_relative import import_relative Mhelper = import_relative('helper', '.') class GeneralTests(unittest.TestCase): def test_step(self): """Test stepping, set skip, set trace""" result = Mhelper.run_debugger(testname='step', dbgr_opts='--basename --highlight=plain', python_file='gcd.py') self.assertEqual(True, result, "debugger 'step' command comparision") return pass if __name__ == "__main__": unittest.main()
# it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>. from import_relative import import_relative # Our local modules Mbase_subcmd = import_relative('base_subcmd', '..', 'trepan') Mcmdfns = import_relative('cmdfns', '...', 'trepan') class SetListSize(Mbase_subcmd.DebuggerSubcommand): "Set the number lines printed in a *list* command by default" in_list = True min_abbrev = len('lis') # Need at least "set lis" def run(self, args): Mcmdfns.run_set_int(self, ' '.join(args), "The 'listsize' command requires a line count.", 0, None) return pass
# it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>. import sys, threading from import_relative import import_relative # Our local modules Mbase_subcmd = import_relative('base_subcmd', '..', 'trepan') Mstack = import_relative('stack', '....lib', 'trepan') Mthread = import_relative('thread', '....lib', 'trepan') # FIXME turn into yet another subcommand thingy. class InfoThread(Mbase_subcmd.DebuggerSubcommand): """info threads [thread-name|thread-number] [terse|verbose] List all currently-known thread name(s). If no thread name is given, we list info for all threads. Unless a terse listing, for each thread we give: - the class, thread name, and status as <Class(Thread-n, status)> - the top-most call-stack information for that thread. Generally the top-most calls into the debugger and dispatcher are omitted unless set dbg_trepan is True.
# (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, see <http://www.gnu.org/licenses/>. """Interface when communicating with the user in the same process as the debugged program.""" import atexit, pprint # Our local modules from import_relative import import_relative import_relative('inout', '..', 'trepan') import_relative('interfaces', '..', 'trepan') Minterface = import_relative('interface', '..', 'trepan') Minput = import_relative('input', '..inout', 'trepan') Moutput = import_relative('output', '..inout', 'trepan') class BWInterface(Minterface.DebuggerInterface): """Interface when communicating with the user in the same process as the debugged program.""" def __init__(self, inp=None, out=None, opts=None): atexit.register(self.finalize) self.input = inp or Minput.DebuggerUserInput() self.output = out or Moutput.DebuggerUserOutput() self.pp = pprint.PrettyPrinter()
# # 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, see <http://www.gnu.org/licenses/>. # Credit: code inspired from code of the same name in ipython. import inspect, os, types # Our local modules from import_relative import import_relative Mbase_cmd = import_relative('base_cmd', top_name='trepan') Mprint = import_relative('print', '...lib', 'trepan') class PrintDefCommand(Mbase_cmd.DebuggerCommand): """**pdef** *obj* Print the definition header for a callable object *obj*. If the object is a class, print the constructor information. See also `pydocX`.""" category = 'data' min_args = 1 max_args = 1 name = os.path.basename(__file__).split('.')[0]
# 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 3 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, see <http://www.gnu.org/licenses/>. from import_relative import import_relative # Our local modules Mbase_cmd = import_relative('base_cmd', top_name='trepan') class AliasCommand(Mbase_cmd.DebuggerCommand): """**alias** *alias-name* *debugger-command* Add alias *alias-name* for a debugger command *debugger-comand*. Add an alias when you want to use a command abbreviation for a command that would otherwise be ambigous. For example, by default we make `s` be an alias of `step` to force it to be used. Without the alias, `s` might be `step`, `show`, or `set` among others **Example:** alias cat list # "cat prog.py" is the same as "list prog.py" alias s step # "s" is now an alias for "step".
pass for i in (15, -15, 300): print('lookup_signame(%d): %s' % (i, lookup_signame(i))) pass for i in ('term', 'TERM', 'NotThere'): print('lookup_signum(%s): %s' % (i, repr(lookup_signum(i)))) pass for i in ('15', '-15', 'term', 'sigterm', 'TERM', '300', 'bogus'): print('canonic_signame(%s): %s' % (i, canonic_signame(i))) pass from import_relative import import_relative Mdebugger = import_relative('debugger', '..', 'trepan') dbgr = Mdebugger.Debugger() h = SignalManager(dbgr) h.info_signal(["TRAP"]) # Set to known value h.action('SIGUSR1') h.action('usr1 print pass stop') h.info_signal(['USR1']) # noprint implies no stop h.action('SIGUSR1 noprint') h.info_signal(['USR1']) h.action('foo nostop') # stop keyword implies print h.action('SIGUSR1 stop') h.info_signal(['SIGUSR1']) h.action('SIGUSR1 noprint')
# 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 3 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, see <http://www.gnu.org/licenses/>. import os from import_relative import import_relative Mbase_submgr = import_relative('base_submgr', top_name='trepan') class InfoCommand(Mbase_submgr.SubcommandMgr): """Generic command for showing things about the program being debugged. You can give unique prefix of the name of a subcommand to get information about just that subcommand. Type `info` for a list of *info* subcommands and what they do. Type `help info *` for just a list of *info* subcommands. """ aliases = ('i',) category = 'status' min_args = 0 max_args = None
# (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, see <http://www.gnu.org/licenses/>. import inspect, linecache, os, sys, tempfile, traceback, types import pyficache from repr import Repr from import_relative import import_relative, get_srcdir import_relative('lib', '...trepan') import_relative('bwprocessor', '...trepan') Mprocessor = import_relative('vprocessor', '..') Mbytecode = import_relative('bytecode', '..lib', 'trepan') Mexcept = import_relative('exception', '..', 'trepan') Mdisplay = import_relative('display', '..lib', 'trepan') Mmisc = import_relative('misc', '..', 'trepan') Mfile = import_relative('file', '..lib', 'trepan') Mlocation = import_relative('location', '.', 'trepan') Mmsg = import_relative('msg', '.', 'trepan') Mstack = import_relative('stack', '..lib', 'trepan') Mthread = import_relative('thred', '..lib', 'trepan') def get_stack(f, t, botframe, proc_obj=None):
#!/usr/bin/env python 'Unit test for trepan.processor.command.cmdfns' import unittest import trepan from import_relative import import_relative Mcmdfns = import_relative('processor.cmdfns', '...trepan') class TestCommandHelper(unittest.TestCase): def setUp(self): self.errors = [] return def errmsg(self, msg): self.errors.append(msg) return def test_get_an_int(self): self.assertEqual(0, Mcmdfns.get_an_int(self.errmsg, '0', 'foo', 0)) self.assertEqual(0, len(self.errors)) self.assertEqual(6, Mcmdfns.get_an_int(self.errmsg, '6*1', 'foo', 5)) self.assertEqual(0, len(self.errors)) self.assertEqual(None, Mcmdfns.get_an_int(self.errmsg, '0', '0 is too small', 5)) self.assertEqual(1, len(self.errors)) self.assertEqual(None, Mcmdfns.get_an_int(self.errmsg, '4+a', '4+a is invalid', 5)) self.assertEqual('4+a is invalid', self.errors[-1]) return
#!/usr/bin/env python 'Unit test for trepan.processor.command.cmdfns' import unittest from import_relative import import_relative Mcmdfns = import_relative('processor.cmdfns', '...trepan') class TestCommandHelper(unittest.TestCase): def setUp(self): self.errors = [] return def errmsg(self, msg): self.errors.append(msg) return def test_get_an_int(self): self.assertEqual(0, Mcmdfns.get_an_int(self.errmsg, '0', 'foo', 0)) self.assertEqual(0, len(self.errors)) self.assertEqual(6, Mcmdfns.get_an_int(self.errmsg, '6*1', 'foo', 5)) self.assertEqual(0, len(self.errors)) self.assertEqual( None, Mcmdfns.get_an_int(self.errmsg, '0', '0 is too small', 5)) self.assertEqual(1, len(self.errors)) self.assertEqual( None, Mcmdfns.get_an_int(self.errmsg, '4+a', '4+a is invalid', 5)) self.assertEqual('4+a is invalid', self.errors[-1]) return def test_get_int(self):
#!/usr/bin/env python3 'Unit test for trepan.exception' import unittest from import_relative import import_relative Mexcept = import_relative('exception', '...trepan') class TestDeguggerExcept(unittest.TestCase): def test_debugger_restart(self): try: raise Mexcept.DebuggerRestart(['a', 'b']) except Mexcept.DebuggerRestart: import sys self.assertEqual(['a', 'b'], sys.exc_info()[1].sys_argv) else: self.assertFalse(True) pass return if __name__ == '__main__': unittest.main()
# # 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 3 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, see <http://www.gnu.org/licenses/>. import inspect, os, re, string, sys from import_relative import get_srcdir, import_relative Mbase_cmd = import_relative('base_cmd') Msubcmd = import_relative('subcmd', os.path.pardir) Mcomplete = import_relative('complete', '...lib', 'trepan') def capitalize(s): # "abcd" -> "Abcd" if s: return s[0].upper() + s[1:] else: # empty string return s pass class SubcommandMgr(Mbase_cmd.DebuggerCommand):
# it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>. import os from import_relative import import_relative Mbase_cmd = import_relative('base_cmd', top_name='trepan') class DisplayCommand(Mbase_cmd.DebuggerCommand): """**display** [*format*] *expression* Print value of expression *expression* each time the program stops. *format* may be used before *expression* and may be one of `c` for char, `x` for hex, `o` for octal, `f` for float or `s` for string. For now, display expressions are only evaluated when in the same code as the frame that was in effect when the display expression was set. This is a departure from gdb and we may allow for more flexibility in the future to specify whether this should be the case or not. With no argument, evaluate and display all currently requested
def dbg_setup(d = None): if d is None: d = MockDebugger() cmdproc = import_relative('cmdproc', os.path.pardir) cp = cmdproc.CommandProcessor(d.core) return d, cp
# (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, see <http://www.gnu.org/licenses/>. import inspect from import_relative import import_relative # Our local modules Mbase_subcmd = import_relative('base_subcmd', '..', 'trepan') class InfoArgs(Mbase_subcmd.DebuggerSubcommand): """Argument variables of the current stack frame.""" min_abbrev = 1 need_stack = True short_help = "Argument variables of the current stack frame" def run(self, args): if not self.proc.curframe: self.errmsg("No stack.") return False f = self.proc.curframe co = f.f_code # Break out display into args, varargs, keywords, and locals ?
# 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 3 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, see <http://www.gnu.org/licenses/>. import os from import_relative import import_relative Mbase_cmd = import_relative('base_cmd', '.', 'trepan') Mdebugger = import_relative('debugger', '...', 'trepan') Mpp = import_relative('pp', '...lib', 'trepan') class PrettyPrintCommand(Mbase_cmd.DebuggerCommand): """**pp** *expression* Pretty-print the value of the expression. Simple arrays are shown columnized horizontally. Other values are printed via *pprint.pformat()*. See also `pr` and `examine` for commands which do more in the way of formatting. """
# 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 3 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, see <http://www.gnu.org/licenses/>. import os, sys, threading from import_relative import import_relative Mbase_cmd = import_relative('base_cmd', top_name='trepan') Mdebugger = import_relative('debugger', '...', top_name='trepan') class DebugCommand(Mbase_cmd.DebuggerCommand): """**debug** *python-expression* Enter a nested debugger that steps through the *python-expression* argument which is an arbitrary expression to be executed the current environment.""" category = 'support' min_args = 1 max_args = None name = os.path.basename(__file__).split('.')[0] need_stack = True short_help = 'Debug PYTHON-EXPR'
#!/usr/bin/env python3 'Unit test for trepan.processor.cmdproc' import unittest from import_relative import import_relative Mcmdproc = import_relative('processor.cmdproc', '...trepan') from cmdhelper import dbg_setup class TestProcesor(unittest.TestCase): def setUp(self): self.d, self.cp = dbg_setup() def test_populate_commands(self): """ Test that we are creating instances for all of classes of files in the command directory .""" for i in self.cp.cmd_instances: if hasattr(i, 'aliases'): self.assertEqual(tuple, type(i.aliases), "not tuple %s." % repr(i.aliases)) self.assertEqual([], [item for item in i.aliases if str != type(item)], "elements of tuple should be strings %s" % repr(i.aliases)) pass pass return
# # 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. ''' Not a command. A stub class used by a command in its 'main' for demonstrating how the command works.''' import os, sys from import_relative import import_relative import_relative('lib', '...', 'trepan') breakpoint = import_relative('breakpoint', '...lib', 'trepan') default = import_relative('default', '...lib', 'trepan') # Default settings class MockIO: def readline(self, prompt='', add_to_history=False): print prompt return 'quit' pass class MockUserInterface: def __init__(self): self.io = MockIO()
#!/usr/bin/env python 'Unit test for trepan.clifns' import inspect, os, sys, unittest from import_relative import import_relative Mclifns = import_relative('clifns', '...trepan') class TestCLIFns(unittest.TestCase): def test_clifns(self): """Test clifns.expanduser_abs()""" file1 = os.path.join(os.path.curdir, "test_clifns") file1 = Mclifns.path_expanduser_abs(file1) file2 = Mclifns.path_expanduser_abs("test_clifns") self.assertEqual(file1, file2, "path_expanduser_abs") self.assertTrue(Mclifns.path_expanduser_abs("~/foo")) return def test_is_ok_line_for_breakpoint(self): filename = __file__ if len(filename) > 4 and filename[-4:] == '.pyc': filename = filename[:-1] pass # Pick up a Python code line for testing. # Note that this comment line relative to the line # we pick up is also used. frame = inspect.currentframe() lineno = frame.f_lineno self.assertTrue(Mclifns
# -*- coding: utf-8 -*- """ trepan ~~~~~~ Trepan Debugger :copyright: Copyright 2013 :license: GPL3, see LICENSE for details. """ __docformat__ = 'restructuredtext' __import__('pkg_resources').declare_namespace(__name__) from import_relative import import_relative Mmisc = import_relative('misc', '.', 'trepan') __all__ = [ Mmisc.pyfiles() ]
#!/usr/bin/env python 'Unit test for trepan.lib.thred' import sys, thread, threading, unittest from import_relative import import_relative Mthread = import_relative('lib.thred', '...trepan') class BgThread(threading.Thread): def __init__(self, id_name_checker): threading.Thread.__init__(self) self.id_name_checker = id_name_checker return def run(self): self.id_name_checker() return pass class TestLibThread(unittest.TestCase): def id_name_checker(self): '''Helper for testing map_thread_names and id2thread''' if sys.version_info[0] == 2 and sys.version_info[1] <= 4: # Don't have sys._current_frames return name2id = Mthread.map_thread_names() for thread_id, f in list(sys._current_frames().items()): self.assertEqual(thread_id, name2id[Mthread.id2thread_name(thread_id)]) # FIXME: use a better test self.assertNotEqual(f, Mthread.find_debugged_frame(f))
#!/usr/bin/env python3 'Unit test for trepan.processor.command.list' import os, sys, unittest from import_relative import import_relative Mlist = import_relative('processor.command.list', '...trepan') import signal class TestListCommand(unittest.TestCase): def setUp(self): self.listsize = 8 self.errors = [] self.msgs = [] return def errmsg(self, msg): self.errors.append(msg) return def msg(self, msg): self.msgs.append(msg) return def print_lines(self): for msg in self.msgs: print(msg) for msg in self.errors: print(msg) def check_lines(self, nums):
#!/usr/bin/env python3 'Unit test for trepan.lib.sighandler' import signal, unittest from import_relative import import_relative Msig = import_relative('lib.sighandler', '...trepan', 'trepan') class TestLibSigHandle(unittest.TestCase): def test_YN(self): for expect, b in (('Yes', True), ('No', False)): self.assertEqual(expect, Msig.YN(b)) pass return def test_canonic_signame(self): for expect, name_num in (('SIGTERM', '15'), ('SIGTERM', '-15'), ('SIGTERM', 'term'), ('SIGTERM', 'sigterm'), ('SIGTERM', 'TERM'), (None, '300'), (False, 'bogus')): self.assertEqual(expect, Msig.canonic_signame(name_num), 'name_num: %s' % name_num) pass pass def test_lookup_signame(self): for expect, num in (('SIGTERM', 15), ('SIGTERM', -15), (None, 300)):
#!/usr/bin/env python3 'Unit test for trepan.lib.file' import os, stat, tempfile, unittest from import_relative import import_relative import_relative('lib', '...trepan') Mfile = import_relative('lib.file', '...trepan') class TestLibFile(unittest.TestCase): def test_lookupmodule(self): m, f = Mfile.lookupmodule('os.path') self.assertTrue(f) self.assertTrue(m) m, f = Mfile.lookupmodule(__file__) self.assertTrue(f) self.assertEqual(None, m) self.assertEqual((None, None), Mfile.lookupmodule('fafdsafdsa')) return def test_pyc2py(self): """Test clifns.pyc2py()""" self.assertEqual('foo.py', Mfile.file_pyc2py("foo.pyc")) fn = 'stays-the-same.py' self.assertEqual(fn , Mfile.file_pyc2py(fn)) fn = 'stays-the-same-without-suffix' self.assertEqual(fn , Mfile.file_pyc2py(fn)) return def test_readable(self): self.assertFalse(Mfile.readable('fdafdsa'))
# (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 os from import_relative import import_relative Mbase_cmd = import_relative('base_cmd', top_name='trepan') Mcmdfns = import_relative('cmdfns', '..', 'trepan') Mfile = import_relative('file', '...lib', 'trepan') Mmisc = import_relative('misc', '...', 'trepan') Mbreak = import_relative('break', '.', 'trepan') class EnableCommand(Mbase_cmd.DebuggerCommand): """**enable** *bpnumber* [*bpnumber* ...] Enables the breakpoints given as a space separated list of breakpoint numbers. See also `info break` to get a list. """ aliases = ('en', ) category = 'breakpoints'
# the Free Software Foundation, either version 3 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, see <http://www.gnu.org/licenses/>. """Debugger input possibly attached to a user or interactive. """ import io, sys, types from import_relative import import_relative Mbase = import_relative('base', top_name='trepan') Mmisc = import_relative('misc', '...trepan') def readline_importable(): try: import readline return True except ImportError: return False return # Not reached class TrepanUserInput(Mbase.TrepanInputBase): """Trepan input connected to what we think of as a end-user input as opposed to a relay mechanism to another process. Input could be interative terminal, but it might be file input."""
# (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, see <http://www.gnu.org/licenses/>. """Interface when communicating with the user in the same process as the debugged program.""" import atexit, os # Our local modules from import_relative import import_relative Minterface = import_relative('interface', '...trepan') Mmisc = import_relative('misc', '...trepan') histfile = os.path.expanduser('~/.trepan_hist') DEFAULT_USER_SETTINGS = { 'histfile' : histfile, # Where do we save the history? } try: from readline import read_history_file, set_completer, set_history_length from readline import write_history_file, parse_and_bind except ImportError: pass