Skip to content

Commit 0a4627a

Browse files
committed
Merge branch 'master' of github.com:rocky/python2-trepan
2 parents f26ebcb + 49d9b50 commit 0a4627a

3 files changed

Lines changed: 253 additions & 3 deletions

File tree

NEWS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
trepan 1.2.4 2021-11-28
2+
=======================
3+
4+
* Revise to use xdis 6.0.3
5+
16
trepan 1.2.3 2021-01-24
27
=======================
38

admin-tools/setup-python-2.4.sh

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ PYTHON_VERSION=2.4.6
33

44
function checkout_version {
55
local repo=$1
6-
echo Checking out python-2.4 on $repo ...
7-
(cd ../$repo && git checkout python-2.4 && pyenv local $PYTHON_VERSION) && \
6+
version=${2:-python-2.4}
7+
echo Checking out $version.4 on $repo ...
8+
(cd ../$repo && git checkout $version && pyenv local $PYTHON_VERSION) && \
89
git pull
910
return $?
1011
}
@@ -19,6 +20,6 @@ fi
1920
mydir=$(dirname $bs)
2021
fulldir=$(readlink -f $mydir)
2122
(cd $fulldir/.. && checkout_version python-spark && checkout_version python-filecache &&
22-
checkout_version python-xdis && checkout_version python-uncompyle6)
23+
checkout_version python-xdis python-2.4-to-2.7 && checkout_version python-uncompyle6)
2324
cd $owd
2425
git checkout python-2.4 && pyenv local $PYTHON_VERSION && git pull

trepan/__main__.py

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
#!/usr/bin/env python
2+
# -*- coding: iso-8859-1 -*-
3+
# Copyright (C) 2008-2010, 2013-2014, 2016-2017, 2021
4+
# Rocky Bernstein <rocky@gnu.org>
5+
#
6+
# This program is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU General Public License as published by
8+
# the Free Software Foundation, either version 3 of the License, or
9+
# (at your option) any later version.
10+
#
11+
# This program is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU General Public License
17+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
"""The command-line interface to the debugger.
19+
"""
20+
import pyficache, os, sys, tempfile
21+
import os.path as osp
22+
23+
import trepan.client as Mclient
24+
import trepan.clifns as Mclifns
25+
import trepan.debugger as Mdebugger
26+
import trepan.exception as Mexcept
27+
import trepan.options as Moptions
28+
import trepan.interfaces.server as Mserver
29+
import trepan.lib.file as Mfile
30+
import trepan.misc as Mmisc
31+
32+
# The name of the debugger we are currently going by.
33+
__title__ = "trepan2"
34+
35+
from trepan.version import __version__
36+
37+
38+
def main(dbg=None, sys_argv=list(sys.argv)):
39+
"""Routine which gets run if we were invoked directly"""
40+
41+
# Save the original just for use in the restart that works via exec.
42+
orig_sys_argv = list(sys_argv)
43+
opts, dbg_opts, sys_argv = Moptions.process_options(
44+
__title__, __version__, sys_argv
45+
)
46+
if opts.server:
47+
connection_opts = {"IO": "TCP", "PORT": opts.port}
48+
intf = Mserver.ServerInterface(connection_opts=connection_opts)
49+
dbg_opts["interface"] = intf
50+
if "FIFO" == intf.server_type:
51+
print("Starting FIFO server for process %s." % os.getpid())
52+
elif "TCP" == intf.server_type:
53+
print("Starting TCP server listening on port %s." % intf.inout.PORT)
54+
pass
55+
elif opts.client:
56+
Mclient.main(opts, sys_argv)
57+
return
58+
59+
dbg_opts["orig_sys_argv"] = orig_sys_argv
60+
61+
if dbg is None:
62+
dbg = Mdebugger.Debugger(dbg_opts)
63+
dbg.core.add_ignore(main)
64+
pass
65+
Moptions._postprocess_options(dbg, opts)
66+
67+
# process_options has munged sys.argv to remove any options that
68+
# options that belong to this debugger. The original options to
69+
# invoke the debugger and script are in global sys_argv
70+
71+
if len(sys_argv) == 0:
72+
# No program given to debug. Set to go into a command loop
73+
# anyway
74+
mainpyfile = None
75+
else:
76+
mainpyfile = sys_argv[0] # Get script filename.
77+
if not osp.isfile(mainpyfile):
78+
mainpyfile = Mclifns.whence_file(mainpyfile)
79+
is_readable = Mfile.readable(mainpyfile)
80+
if is_readable is None:
81+
sys.stderr.write("%s: Python script file '%s' does not exist\n"
82+
% (__title__, mainpyfile))
83+
sys.exit(1)
84+
elif not is_readable:
85+
sys.stderr.write("%s: Can't read Python script file '%s'\n"
86+
% (__title__, mainpyfile, ))
87+
sys.exit(1)
88+
return
89+
90+
if Mfile.is_compiled_py(mainpyfile):
91+
try:
92+
from xdis import load_module
93+
from xdis_version import load_module, PYTHON_VERSION_TRIPLE, IS_PYPY, version_tuple_to_str
94+
95+
(
96+
python_version,
97+
timestamp,
98+
magic_int,
99+
co,
100+
is_pypy,
101+
source_size,
102+
) = load_module(mainpyfile, code_objects=None, fast_load=True)
103+
assert is_pypy == IS_PYPY
104+
assert (
105+
python_version == PYTHON_VERSION_TRIPLE
106+
), "bytecode is for version %s but we are version %s" % (
107+
python_version,
108+
version_tuple_to_str(),
109+
)
110+
# We should we check version magic_int
111+
112+
py_file = co.co_filename
113+
if osp.isabs(py_file):
114+
try_file = py_file
115+
else:
116+
mainpydir = osp.dirname(mainpyfile)
117+
dirnames = (
118+
[mainpydir] + os.environ["PATH"].split(os.pathsep) + ["."]
119+
)
120+
try_file = Mclifns.whence_file(py_file, dirnames)
121+
122+
if osp.isfile(try_file):
123+
mainpyfile = try_file
124+
pass
125+
else:
126+
# Move onto the except branch
127+
raise IOError(
128+
"Python file name embedded in code %s not found" % try_file
129+
)
130+
except:
131+
try:
132+
from uncompyle6 import decompile_file
133+
except ImportError:
134+
sys.stderr.write("%s: Compiled python file '%s', but uncompyle6 not found\n"
135+
% (__title__, mainpyfile))
136+
sys.exit(1)
137+
return
138+
139+
short_name = osp.basename(mainpyfile).strip(".pyc")
140+
fd = tempfile.NamedTemporaryFile(
141+
suffix=".py",
142+
prefix=short_name + "_",
143+
dir=dbg.settings["tempdir"],
144+
delete=False,
145+
)
146+
try:
147+
decompile_file(mainpyfile, outstream=fd)
148+
mainpyfile = fd.name
149+
fd.close()
150+
except:
151+
sys.stderr.write("%s: error uncompyling '%s'\n"
152+
% (__title__, mainpyfile))
153+
sys.exit(1)
154+
pass
155+
156+
# If mainpyfile is an optimized Python script try to find and
157+
# use non-optimized alternative.
158+
mainpyfile_noopt = pyficache.resolve_name_to_path(mainpyfile)
159+
if mainpyfile != mainpyfile_noopt \
160+
and Mfile.readable(mainpyfile_noopt):
161+
sys.stderr.write("%s: Compiled Python script given and we can't use that.\n"
162+
% __title__)
163+
sys.stderr.write("%s: Substituting non-compiled name: %s\n" %
164+
(__title__, mainpyfile_noopt))
165+
mainpyfile = mainpyfile_noopt
166+
pass
167+
168+
# Replace trepan's dir with script's dir in front of
169+
# module search path.
170+
sys.path[0] = dbg.main_dirname = osp.dirname(mainpyfile)
171+
172+
# XXX If a signal has been received we continue in the loop, otherwise
173+
# the loop exits for some reason.
174+
dbg.sig_received = False
175+
176+
# if not mainpyfile:
177+
# print('For now, you need to specify a Python script name!')
178+
# sys.exit(2)
179+
# pass
180+
181+
while True:
182+
183+
# Run the debugged script over and over again until we get it
184+
# right.
185+
186+
try:
187+
if dbg.program_sys_argv and mainpyfile:
188+
normal_termination = dbg.run_script(mainpyfile)
189+
if not normal_termination:
190+
break
191+
else:
192+
dbg.core.execution_status = "No program"
193+
dbg.core.processor.process_commands()
194+
pass
195+
196+
dbg.core.execution_status = "Terminated"
197+
dbg.intf[-1].msg("The program finished - quit or restart")
198+
dbg.core.processor.process_commands()
199+
except Mexcept.DebuggerQuit:
200+
break
201+
except Mexcept.DebuggerRestart:
202+
dbg.core.execution_status = "Restart requested"
203+
if dbg.program_sys_argv:
204+
sys.argv = list(dbg.program_sys_argv)
205+
part1 = "Restarting %s with arguments:" % dbg.core.filename(mainpyfile)
206+
args = " ".join(dbg.program_sys_argv[1:])
207+
dbg.intf[-1].msg(
208+
Mmisc.wrapped_lines(part1, args, dbg.settings["width"])
209+
)
210+
else:
211+
break
212+
except SystemExit:
213+
# In most cases SystemExit does not warrant a post-mortem session.
214+
break
215+
except:
216+
# FIXME: Should be handled above without this mess
217+
exception_name = str(sys.exc_info()[0])
218+
if exception_name == str(Mexcept.DebuggerQuit):
219+
break
220+
elif exception_name == str(Mexcept.DebuggerRestart):
221+
dbg.core.execution_status = "Restart requested"
222+
if dbg.program_sys_argv:
223+
sys.argv = list(dbg.program_sys_argv)
224+
part1 = "Restarting %s with arguments:" % dbg.core.filename(
225+
mainpyfile
226+
)
227+
args = " ".join(dbg.program_sys_argv[1:])
228+
dbg.intf[-1].msg(
229+
Mmisc.wrapped_lines(part1, args, dbg.settings["width"])
230+
)
231+
pass
232+
else:
233+
raise
234+
pass
235+
236+
# Restore old sys.argv
237+
sys.argv = orig_sys_argv
238+
return
239+
240+
241+
# When invoked as main program, invoke the debugger on a script
242+
if __name__ == "__main__":
243+
main()
244+
pass

0 commit comments

Comments
 (0)