Skip to content

Commit 3a6897a

Browse files
committed
Improve disassembly
1 parent 5eb5aea commit 3a6897a

2 files changed

Lines changed: 59 additions & 24 deletions

File tree

trepan/lib/disassemble.py

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
# -*- coding: utf-8 -*-
2-
# Modification of Python's Lib/dis.py
3-
# FIXME: see if we can use more of Lib/dis in Python3
2+
# Copyright (C) 2026 Rocky Bernstein
3+
#
4+
# This program is free software: you can redistribute it and/or modify
5+
# it under the terms of the GNU General Public License as published by
6+
# the Free Software Foundation, either version 3 of the License, or
7+
# (at your option) any later version.
8+
#
9+
# This program is distributed in the hope that it will be useful,
10+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
# GNU General Public License for more details.
13+
#
14+
# You should have received a copy of the GNU General Public License
15+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
416
"""Disassembly Routines"""
517

618
import bisect
@@ -200,17 +212,16 @@ def dis_from_file(
200212
msg(f"Starting line {start_line} not found; adjusting up to {new_start}")
201213
start_line = new_start
202214

203-
# FIXME: we really need to get the code from linecache_info.line_numbers
204-
code_object = linecache_info.code_map[filename]
205-
206-
dis(msg, msg_nocr, section, errmsg,
207-
x=code_object,
208-
start_line=start_line,
209-
end_line=end_line,
210-
style=style,
211-
include_header=include_header,
212-
asm_format=asm_format,
213-
)
215+
code_object = next((k for k, val in linecache_info.code_map.items() if val == filename), None)
216+
if code_object is not None:
217+
dis(msg, msg_nocr, section, errmsg,
218+
x=code_object,
219+
start_line=start_line,
220+
end_line=end_line,
221+
style=style,
222+
include_header=include_header,
223+
asm_format=asm_format,
224+
)
214225

215226

216227
# Default opc whene none is given.

trepan/processor/command/disassemble.py

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# -*- coding: utf-8 -*-
22
#
3-
# Copyright (C) 2009, 2012-2018, 2020, 2023-2024 Rocky Bernstein
3+
# Copyright (C) 2009, 2012-2018, 2020, 2023-2024, 2026 Rocky Bernstein
44
#
55
# This program is free software: you can redistribute it and/or modify
66
# it under the terms of the GNU General Public License as published by
@@ -19,7 +19,8 @@
1919
import os.path as osp
2020
import sys
2121

22-
from xdis.load import load_module
22+
from pyficache import code_line_info
23+
from xdis.load import is_bytecode_extension, load_module
2324

2425
import trepan.lib.file as Mfile
2526
from trepan.lib.disassemble import dis
@@ -138,6 +139,10 @@ def run(self, args):
138139
curframe = proc.curframe
139140
if curframe:
140141
line_no = inspect.getlineno(curframe)
142+
# Note that all of this may be wrong, depending
143+
# on whether a line number has been given.
144+
# But if that happens, we'll update the
145+
# below.
141146
opts["start_line"] = line_no - 1
142147
opts["end_line"] = line_no + 1
143148

@@ -184,7 +189,18 @@ def run(self, args):
184189
opts["start_offset"] = start
185190
else:
186191
opts["start_line"] = start
187-
opts["start_offset"] = 0
192+
if last is None:
193+
last = start + 1
194+
opts["end_line"] = last
195+
# Make sure start is in bytecode_file, and if so which
196+
# code object do we need to use in disassembly?
197+
code_map, line_info = code_line_info(bytecode_file, start)
198+
if not line_info:
199+
self.errmsg(f"Can't find code associated with starting line {start}.")
200+
return
201+
obj = code_map[line_info[0].name]
202+
203+
188204
if last_is_offset:
189205
opts["end_offset"] = last
190206
else:
@@ -193,7 +209,7 @@ def run(self, args):
193209

194210
if not obj and (
195211
bytecode_file
196-
and (not bytecode_file.endswith(".pyo") or bytecode_file.endswith("pyc"))
212+
and not is_bytecode_extension(bytecode_file)
197213
):
198214
# bytecode_file may be a source file. Try to tun it into a bytecode file for diassembly.
199215
bytecode_file = cache_from_source(bytecode_file)
@@ -223,7 +239,8 @@ def run(self, args):
223239
)
224240
return
225241

226-
# We now have all information. Do the listing.
242+
# We now have all information. Do the listing.
243+
breakpoint()
227244
(obj, proc.list_offset) = dis(
228245
self.msg, self.msg_nocr, self.section, self.errmsg, obj, **opts
229246
)
@@ -233,19 +250,27 @@ def run(self, args):
233250
# Demo it
234251
if __name__ == "__main__":
235252
# FIXME: make sure the below is in a unit test
253+
def get_line():
254+
return inspect.currentframe().f_back.f_lineno
255+
236256
def doit(cmd, args):
237257
proc = cmd.proc
238258
proc.current_command = " ".join(args)
239259
cmd.run(args)
240260

261+
doit_return_line = get_line() - 4
262+
241263
from trepan.processor.command import mock
242264

265+
243266
d, cp = mock.dbg_setup()
244267

245268
cp.list_object = cp.curframe = inspect.currentframe()
246269
command = DisassembleCommand(cp)
247270
prefix = "-" * 20 + " disassemble "
248271

272+
doit(command, ["disassemble", f"{doit_return_line}, {doit_return_line+2}"])
273+
249274
print(prefix + "os.path")
250275
doit(command, ["disassemble", "cp.errmsg()"])
251276

@@ -261,8 +286,8 @@ def doit(cmd, args):
261286
# print(prefix + 'me')
262287
# doit(command, ['disassemble', 'me()']) # reports invalid function correctly
263288

264-
print(prefix + "*0 +248")
265-
doit(command, ["disassemble", "*0,", "+248"])
289+
# print(prefix + "*0 +248")
290+
# doit(command, ["disassemble", "*0,", "+248"])
266291

267292
# print(prefix + '+ 2-1')
268293
# doit(command, ['disassemble', '+', '2-1']) # not valid?
@@ -273,14 +298,13 @@ def doit(cmd, args):
273298
print(prefix + ".")
274299
doit(command, ["disassemble", "."])
275300

276-
__file__ = "./disassemble.py:21"
277-
doit(command, ["disassemble", "%s:21" % __file__])
301+
doit(command, ["disassemble", "%s:%s" % (__file__, get_line())])
278302

279303
# bytecode_file = cache_from_source(__file__)
280304
# print(bytecode_file)
281305
# if bytecode_file:
282306
# doit(command, ["disassemble", bytecode_file + ":22,28"])
283307

284-
doit(command, ["disassemble", "*15,", "*25"])
285-
doit(command, ["disassemble", "30"])
308+
# doit(command, ["disassemble", "*15,", "*25"])
309+
# doit(command, ["disassemble", "30"])
286310
pass

0 commit comments

Comments
 (0)