Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 594 lines (490 sloc) 20.87 kB
fac586f @devhawk Added ConsoleColorMgr class and modified all event handler to print i…
authored
1 from __future__ import with_statement
2
5858695 @devhawk added initial (hello, world) version of ipydbg, a simpletest script t…
authored
3 import clr
4 clr.AddReference('CorDebug')
5
6 import sys
965e2fb @devhawk Added OnUpdateModuleSymbols
authored
7
fac586f @devhawk Added ConsoleColorMgr class and modified all event handler to print i…
authored
8 from System import Array, Console, ConsoleKey, ConsoleModifiers, ConsoleColor
2e76819 @devhawk added code to show current line of code at top of input loop
authored
9 from System.IO import Path, File
5858695 @devhawk added initial (hello, world) version of ipydbg, a simpletest script t…
authored
10 from System.Reflection import Assembly
bc12743 @devhawk Added basic input loop (continue and terminate)
authored
11 from System.Threading import WaitHandle, AutoResetEvent
117cdce @devhawk added run_debugger to handle setting up an MTA thread if needed
authored
12 from System.Threading import Thread, ApartmentState, ParameterizedThreadStart
4a702fb @devhawk updated imports
authored
13 from System.Diagnostics.SymbolStore import ISymbolDocument
965e2fb @devhawk Added OnUpdateModuleSymbols
authored
14
5381899 @devhawk moved code to search thru all the symbol documents in a module from O…
authored
15 from Microsoft.Samples.Debugging.CorDebug import (CorDebugger, CorFrameType,
16 CorValue, CorReferenceValue, CorObjectValue, CorAppDomain, CorModule)
4a702fb @devhawk updated imports
authored
17 from Microsoft.Samples.Debugging.CorDebug.NativeApi import \
442527b @devhawk changed value_to_str to extract_value and changed the formatting of L…
authored
18 CorDebugUnmappedStop, COR_DEBUG_STEP_RANGE, CorDebugStepReason
19 from Microsoft.Samples.Debugging.CorDebug.NativeApi.CorElementType import *
5858695 @devhawk added initial (hello, world) version of ipydbg, a simpletest script t…
authored
20
41285e5 @devhawk moved console color code to consolecolor.py file
authored
21 import consolecolor as CC
fac586f @devhawk Added ConsoleColorMgr class and modified all event handler to print i…
authored
22
23 #--------------------------------------------
c2e5ee6 @devhawk added logic to spin up MTA thread if ipydbg is run from an STA thread
authored
24 # sequence point functions
92521a5 @devhawk Added get_location function and symbol_readers global dict
authored
25
ac1dd1b @devhawk Added sequence_point class, get_sequence_points function,
authored
26 class sequence_point(object):
27 def __init__(self, offset, doc, start_line, start_col, end_line, end_col):
28 self.offset = offset
29 self.doc = doc
30 self.start_line = start_line
31 self.start_col = start_col
32 self.end_line = end_line
33 self.end_col = end_col
34
4063fe6 @devhawk Modified get_location to return data instead of a string
authored
35 def __str__(self):
cdf0a84 @devhawk Modified sequence point's __str__ function to show more data
authored
36 return "%s %d:%d-%d:%d (offset:%d)" % (Path.GetFileName(self.doc.URL),
37 self.start_line, self.start_col, self.end_line, self.end_col, self.offset)
4063fe6 @devhawk Modified get_location to return data instead of a string
authored
38
7218d91 @devhawk Updated get_sequence_points to yield hidden lines if desired
authored
39 def get_sequence_points(symmethod, include_hidden_lines = False):
40 sp_count = symmethod.SequencePointCount
607873f @devhawk modified get_sequence_points to eliminate multiple calls to method.Se…
authored
41 spOffsets = Array.CreateInstance(int, sp_count)
7218d91 @devhawk Updated get_sequence_points to yield hidden lines if desired
authored
42 spDocs = Array.CreateInstance(ISymbolDocument, sp_count)
607873f @devhawk modified get_sequence_points to eliminate multiple calls to method.Se…
authored
43 spStartLines = Array.CreateInstance(int, sp_count)
44 spEndLines = Array.CreateInstance(int, sp_count)
45 spStartCol = Array.CreateInstance(int, sp_count)
46 spEndCol = Array.CreateInstance(int, sp_count)
ac1dd1b @devhawk Added sequence_point class, get_sequence_points function,
authored
47
7218d91 @devhawk Updated get_sequence_points to yield hidden lines if desired
authored
48 symmethod.GetSequencePoints(spOffsets, spDocs, spStartLines, spStartCol,
49 spEndLines, spEndCol)
ac1dd1b @devhawk Added sequence_point class, get_sequence_points function,
authored
50
607873f @devhawk modified get_sequence_points to eliminate multiple calls to method.Se…
authored
51 for i in range(sp_count):
7218d91 @devhawk Updated get_sequence_points to yield hidden lines if desired
authored
52 if spStartLines[i] != 0xfeefee or include_hidden_lines:
49edbe5 @devhawk modifed get_sequence_points to skip over hidden (aka so called FeeFee…
authored
53 yield sequence_point(spOffsets[i], spDocs[i], spStartLines[i],
54 spStartCol[i], spEndLines[i], spEndCol[i])
ac1dd1b @devhawk Added sequence_point class, get_sequence_points function,
authored
55
92521a5 @devhawk Added get_location function and symbol_readers global dict
authored
56
c2e5ee6 @devhawk added logic to spin up MTA thread if ipydbg is run from an STA thread
authored
57 #--------------------------------------------
58 # breakpoint funcitons
59
5381899 @devhawk moved code to search thru all the symbol documents in a module from O…
authored
60 def create_breakpoint(module, filename, linenum):
61 reader = module.SymbolReader
62 if reader == None:
c223608 @devhawk added _bp_add function for adding breakpoints
authored
63 return None
5381899 @devhawk moved code to search thru all the symbol documents in a module from O…
authored
64
65 # currently, I'm only comparing filenames. This algorithm may need to get more
66 # sophisticated to support differntiating files with the same name in different paths
67 filename = Path.GetFileName(filename)
68 for doc in reader.GetDocuments():
69 if str.Compare(filename, Path.GetFileName(doc.URL), True) == 0:
70 linenum = doc.FindClosestLine(linenum)
b40b91e @devhawk fixed small bug in create_breakpoint
authored
71 method = reader.GetMethodFromDocumentPosition(doc, linenum, 0)
5381899 @devhawk moved code to search thru all the symbol documents in a module from O…
authored
72 function = module.GetFunctionFromToken(method.Token.GetToken())
73
74 for sp in get_sequence_points(method):
75 if sp.doc.URL == doc.URL and sp.start_line == linenum:
76 return function.ILCode.CreateBreakpoint(sp.offset)
77
78 return function.CreateBreakpoint()
ac1dd1b @devhawk Added sequence_point class, get_sequence_points function,
authored
79
c2e5ee6 @devhawk added logic to spin up MTA thread if ipydbg is run from an STA thread
authored
80 #--------------------------------------------
81 # frame functions
82
29f6a29 @devhawk Added get_dynamic_frames to filter out IPy and DLR stack frames
authored
83 def get_dynamic_frames(chain):
84 for f in chain.Frames:
0b50760 @devhawk Moved GetMethodInfo for frames and functions to C#. Moved GetTYpeInfo…
authored
85 method_info = f.GetMethodInfo()
ec0cf6a @devhawk added get_method_info_for_frame
authored
86 if method_info == None:
dab527c @devhawk Added frametype checks
authored
87 continue
29f6a29 @devhawk Added get_dynamic_frames to filter out IPy and DLR stack frames
authored
88 typename = method_info.DeclaringType.Name
89 if typename.startswith("Microsoft.Scripting.") \
90 or typename.startswith("IronPython.") \
91 or typename == "PythonConsoleHost":
92 continue
93 yield f
a12e505 @devhawk moved _get_location and _do_step out of IPyDebugProcess
authored
94
150c1fa @devhawk refactored get_location into seperate get_location and get_frame_loca…
authored
95 def get_location(function, offset):
fc6dd06 @devhawk Added CorFunction.GetSymbolMethod and updated
authored
96 symmethod = function.GetSymbolMethod()
97 if symmethod == None:
98 return None
a12e505 @devhawk moved _get_location and _do_step out of IPyDebugProcess
authored
99
150c1fa @devhawk refactored get_location into seperate get_location and get_frame_loca…
authored
100 prev_sp = None
fc6dd06 @devhawk Added CorFunction.GetSymbolMethod and updated
authored
101 for sp in get_sequence_points(symmethod):
a12e505 @devhawk moved _get_location and _do_step out of IPyDebugProcess
authored
102 if sp.offset > offset:
103 break
150c1fa @devhawk refactored get_location into seperate get_location and get_frame_loca…
authored
104 prev_sp = sp
105 return prev_sp
a12e505 @devhawk moved _get_location and _do_step out of IPyDebugProcess
authored
106
150c1fa @devhawk refactored get_location into seperate get_location and get_frame_loca…
authored
107 def get_frame_location(frame):
108 offset, mapping_result = frame.GetIP()
109
110 if frame.FrameType != CorFrameType.ILFrame:
111 return offset, None
112 return offset, get_location(frame.Function, offset)
113
36a012c @devhawk added step functionality (step, step in and step out)
authored
114 #--------------------------------------------
115 # stepper functions
116
39eb5ea @devhawk Added JMC support
authored
117 def create_stepper(thread, JMC = True):
36a012c @devhawk added step functionality (step, step in and step out)
authored
118 stepper = thread.ActiveFrame.CreateStepper()
119 stepper.SetUnmappedStopMask(CorDebugUnmappedStop.STOP_NONE)
39eb5ea @devhawk Added JMC support
authored
120 stepper.SetJmcStatus(JMC)
36a012c @devhawk added step functionality (step, step in and step out)
authored
121 return stepper
122
123 from System import UInt32
124 def create_step_range(start, end):
125 range = Array.CreateInstance(COR_DEBUG_STEP_RANGE, 1)
0840b8c @devhawk Minor cleanup - changing Console.WriteLine to print and formatting so…
authored
126 range[0] = COR_DEBUG_STEP_RANGE(
127 startOffset = UInt32(start),
128 endOffset = UInt32(end))
36a012c @devhawk added step functionality (step, step in and step out)
authored
129 return range
130
131 def get_step_ranges(thread, reader):
0840b8c @devhawk Minor cleanup - changing Console.WriteLine to print and formatting so…
authored
132 frame = thread.ActiveFrame
133 offset, mapResult = frame.GetIP()
fc6dd06 @devhawk Added CorFunction.GetSymbolMethod and updated
authored
134 symmethod = frame.Function.GetSymbolMethod()
135 for sp in get_sequence_points(symmethod):
36a012c @devhawk added step functionality (step, step in and step out)
authored
136 if sp.offset > offset:
137 return create_step_range(offset, sp.offset)
0840b8c @devhawk Minor cleanup - changing Console.WriteLine to print and formatting so…
authored
138 return create_step_range(offset, frame.Function.ILCode.Size)
39eb5ea @devhawk Added JMC support
authored
139
a12e505 @devhawk moved _get_location and _do_step out of IPyDebugProcess
authored
140 def do_step(thread, step_in):
141 stepper = create_stepper(thread)
142 reader = thread.ActiveFrame.Function.Module.SymbolReader
143 if reader == None:
144 stepper.Step(step_in)
145 else:
146 range = get_step_ranges(thread, reader)
147 stepper.StepRange(step_in, range)
148
36a012c @devhawk added step functionality (step, step in and step out)
authored
149 #--------------------------------------------
791b6b6 @devhawk prototype locals implementation
authored
150 # value functions
151
4495bbc @devhawk moved show_hiding code to client method (_input_locals_cmd)
authored
152 def get_locals(frame, scope=None, offset = None):
2e13f02 @devhawk cleaned up get_locals method
authored
153 #if the scope is unspecified, try and get it from the frame
68ab611 @devhawk moved get_locals to a top level function
authored
154 if scope == None:
2e13f02 @devhawk cleaned up get_locals method
authored
155 symmethod = frame.Function.GetSymbolMethod()
156 if symmethod != None:
157 scope = symmethod.RootScope
158 #if scope still not available, yield the local variables
159 #from the frame, with auto-gen'ed names (local_1, etc)
160 else:
161 for i in range(frame.GetLocalVariablesCount()):
162 yield "local_%d" % i, frame.GetLocalVariable(i)
163 return
164
165 #if we have a scope, get the locals from the scope
166 #and their values from the frame
167 for lv in scope.GetLocals():
f676f1e @devhawk Always hide $site local variables in get_locals
authored
168 #always skip $site locals - they are cached callsites and
169 #not relevant to the ironpython developer
4495bbc @devhawk moved show_hiding code to client method (_input_locals_cmd)
authored
170 if lv.Name == "$site":
171 continue
172 v = frame.GetLocalVariable(lv.AddressField1)
173 yield lv.Name, v
f676f1e @devhawk Always hide $site local variables in get_locals
authored
174
2e13f02 @devhawk cleaned up get_locals method
authored
175 if offset == None: offset = frame.GetIP()[0]
68ab611 @devhawk moved get_locals to a top level function
authored
176
2e13f02 @devhawk cleaned up get_locals method
authored
177 #recusively call get_locals for all the child scopes
178 for s in scope.GetChildren():
179 if s.StartOffset <= offset and s.EndOffset >= offset:
4495bbc @devhawk moved show_hiding code to client method (_input_locals_cmd)
authored
180 for ret in get_locals(frame, s, offset): yield ret
61549bb @devhawk Updated value_to_str to support more types
authored
181
4495bbc @devhawk moved show_hiding code to client method (_input_locals_cmd)
authored
182 def get_arguments(frame):
2f9902c @devhawk added get_arguments function
authored
183 mi = frame.GetMethodInfo()
184 for pi in mi.GetParameters():
185 if pi.Position == 0: continue
4495bbc @devhawk moved show_hiding code to client method (_input_locals_cmd)
authored
186 arg = frame.GetArgument(pi.Position - 1)
187 yield pi.Name, arg
2f9902c @devhawk added get_arguments function
authored
188
189
1d6b8dc @devhawk updated extract_value() to retrieve the value of boxed primitive values
authored
190 _type_map = {
191 'System.Boolean': ELEMENT_TYPE_BOOLEAN,
192 'System.SByte' : ELEMENT_TYPE_I1,
193 'System.Byte' : ELEMENT_TYPE_U1,
194 'System.Int16' : ELEMENT_TYPE_I2,
195 'System.UInt16' : ELEMENT_TYPE_U2,
196 'System.Int32' : ELEMENT_TYPE_I4,
197 'System.UInt32' : ELEMENT_TYPE_U4,
198 'System.IntPtr' : ELEMENT_TYPE_I,
199 'System.UIntPtr': ELEMENT_TYPE_U,
200 'System.Int64' : ELEMENT_TYPE_I8,
201 'System.UInt64' : ELEMENT_TYPE_U8,
202 'System.Single' : ELEMENT_TYPE_R4,
203 'System.Double' : ELEMENT_TYPE_R8,
204 'System.Char' : ELEMENT_TYPE_CHAR, }
205
206 _generic_element_types = _type_map.values()
207
208
209 class NullCorValue(object):
210 def __init__(self, typename):
211 self.typename = typename
212
442527b @devhawk changed value_to_str to extract_value and changed the formatting of L…
authored
213 def extract_value(value):
4fa8915 @devhawk fixed bug in value_to_str for ELEMENT_TYPE_STRING
authored
214 rv = value.CastToReferenceValue()
215 if rv != None:
1d6b8dc @devhawk updated extract_value() to retrieve the value of boxed primitive values
authored
216 if rv.IsNull:
217 typename = rv.ExactType.Class.GetTypeInfo().Name
218 return NullCorValue(typename)
442527b @devhawk changed value_to_str to extract_value and changed the formatting of L…
authored
219 return extract_value(rv.Dereference())
4fa8915 @devhawk fixed bug in value_to_str for ELEMENT_TYPE_STRING
authored
220 bv = value.CastToBoxValue()
221 if bv != None:
71600dd @devhawk fixed bug in extract_value and updated locals command
authored
222 return extract_value(bv.GetObject())
4fa8915 @devhawk fixed bug in value_to_str for ELEMENT_TYPE_STRING
authored
223
61549bb @devhawk Updated value_to_str to support more types
authored
224 if value.Type in _generic_element_types:
442527b @devhawk changed value_to_str to extract_value and changed the formatting of L…
authored
225 return value.CastToGenericValue().GetValue()
226 elif value.Type == ELEMENT_TYPE_STRING:
61549bb @devhawk Updated value_to_str to support more types
authored
227 return value.CastToStringValue().String
1d6b8dc @devhawk updated extract_value() to retrieve the value of boxed primitive values
authored
228 elif value.Type == ELEMENT_TYPE_VALUETYPE:
229 typename = value.ExactType.Class.GetTypeInfo().Name
230 if typename in _type_map:
231 gv = value.CastToGenericValue()
232 return gv.UnsafeGetValueAsType(_type_map[typename])
233 else:
234 return value.CastToObjectValue()
235 elif value.Type in [ELEMENT_TYPE_CLASS, ELEMENT_TYPE_OBJECT]:
71600dd @devhawk fixed bug in extract_value and updated locals command
authored
236 return value.CastToObjectValue()
61549bb @devhawk Updated value_to_str to support more types
authored
237 else:
1d6b8dc @devhawk updated extract_value() to retrieve the value of boxed primitive values
authored
238 raise (Exception,
239 "<processing CorValue of type: %s not implemented>" % str(value.Type))
9dd12da @devhawk refactored CorValue display code out of _input_locals_cmd and into di…
authored
240
241 def display_value(value):
242 if type(value) == str:
243 return (('"%s"' % value), 'System.String')
244 elif type(value) == CorObjectValue:
245 return ("<...>", value.ExactType.Class.GetTypeInfo().FullName)
246 elif type(value) == NullCorValue:
247 return ("<None>", value.typename)
248 else:
249 return (str(value), value.GetType().FullName)
250
791b6b6 @devhawk prototype locals implementation
authored
251 #--------------------------------------------
36a012c @devhawk added step functionality (step, step in and step out)
authored
252 # main IPyDebugProcess class
d56c115 @devhawk Added inputcmd decorator to automatically store command methods in a …
authored
253
254 def inputcmd(cmddict, key):
255 def deco(f):
256 cmddict[key] = f
257 return f
258 return deco
259
df3a46a @devhawk Refactored ipydbg code into a class IPyDebugProcess
authored
260 class IPyDebugProcess(object):
261 def __init__(self, debugger=None):
262 self.debugger = debugger if debugger != None \
263 else CorDebugger(CorDebugger.GetDefaultDebuggerVersion())
264
265 def run(self, py_file):
266 self.py_file = py_file
267 #use the current executing version of IPY to launch the debug process
268 ipy = Assembly.GetEntryAssembly().Location
269 cmd_line = "\"%s\" -D \"%s\"" % (ipy, py_file)
270 self.process = self.debugger.CreateProcess(ipy, cmd_line)
271
272 self.process.OnCreateAppDomain += self.OnCreateAppDomain
273 self.process.OnProcessExit += self.OnProcessExit
274 self.process.OnUpdateModuleSymbols += self.OnUpdateModuleSymbols
275 self.process.OnBreakpoint += self.OnBreakpoint
276 self.process.OnStepComplete += self.OnStepComplete
39eb5ea @devhawk Added JMC support
authored
277 self.process.OnClassLoad += self.OnClassLoad
df3a46a @devhawk Refactored ipydbg code into a class IPyDebugProcess
authored
278
279 self.terminate_event = AutoResetEvent(False)
280 self.break_event = AutoResetEvent(False)
281
282 self.initial_breakpoint = None
0de57ed @devhawk moved to storing breakpoint list in IPyDebugProces instead of queryin…
authored
283 self.breakpoints = []
2e76819 @devhawk added code to show current line of code at top of input loop
authored
284 self.source_files = dict()
df3a46a @devhawk Refactored ipydbg code into a class IPyDebugProcess
authored
285
286 handles = Array.CreateInstance(WaitHandle, 2)
287 handles[0] = self.terminate_event
288 handles[1] = self.break_event
289
290 while True:
0cc6f38 @devhawk added active_appdomain field to IPyDebugProcess and updated run to re…
authored
291 if hasattr(self, 'active_thread'): delattr(self, 'active_thread')
292 if hasattr(self, 'active_appdomain'): delattr(self, 'active_appdomain')
df3a46a @devhawk Refactored ipydbg code into a class IPyDebugProcess
authored
293 self.process.Continue(False)
294 i = WaitHandle.WaitAny(handles)
295 if i == 0:
296 break
297 self._input()
e8e04dd @devhawk Modified IPyDebugProcess._print_source_line to handle statements that…
authored
298
5359ea5 @devhawk added _print_source_line to colorize current source line printing
authored
299 def _print_source_line(self, sp, lines):
e8e04dd @devhawk Modified IPyDebugProcess._print_source_line to handle statements that…
authored
300 linecount = len(lines)
b69f101 @devhawk cleaned up _print_source_line
authored
301 linecount_fmt = "%%%dd: " % len(str(linecount))
e8e04dd @devhawk Modified IPyDebugProcess._print_source_line to handle statements that…
authored
302
303 for i in range(sp.start_line, sp.end_line+1):
304 with CC.Cyan:
b69f101 @devhawk cleaned up _print_source_line
authored
305 Console.Write(linecount_fmt % i)
e8e04dd @devhawk Modified IPyDebugProcess._print_source_line to handle statements that…
authored
306 line = lines[i-1] if i <= linecount else ""
307 start = sp.start_col if i==sp.start_line else 1
308 end = sp.end_col if i == sp.end_line else len(line)+1
5359ea5 @devhawk added _print_source_line to colorize current source line printing
authored
309
e8e04dd @devhawk Modified IPyDebugProcess._print_source_line to handle statements that…
authored
310 with CC.Gray:
311 Console.Write(line.Substring(0, start-1))
312 with CC.Yellow:
313 Console.Write(line.Substring(start-1, end-start))
314 Console.Write(line.Substring(end-1))
315
316 if sp.start_line == sp.end_line == i and sp.start_col == sp.end_col:
317 with CC.Yellow: Console.Write(" ^^^")
318 Console.WriteLine()
d56c115 @devhawk Added inputcmd decorator to automatically store command methods in a …
authored
319
320 _inputcmds = dict()
47a92ed @devhawk renamed _breakpoint_mgmt to input_breakpoint and changed it to use @i…
authored
321 _breakpointcmds = dict()
d56c115 @devhawk Added inputcmd decorator to automatically store command methods in a …
authored
322
7516e69 @devhawk rename debug mode to REPL console, including changing the keyboard co…
authored
323 @inputcmd(_inputcmds, ConsoleKey.R)
324 def _input_repl_cmd(self, keyinfo):
ec1ed1c @devhawk changed REPL color to gray on black
authored
325 with CC.Gray:
1993f26 @devhawk tweaked _input_repl_cmd and added support Ctrl-Z to exit the REPL con…
authored
326 print "\nREPL Console\nPress Ctl-Z to Exit"
67c0f31 @devhawk added _input_debug_cmd (aka the debug console)
authored
327 cmd = ""
1993f26 @devhawk tweaked _input_repl_cmd and added support Ctrl-Z to exit the REPL con…
authored
328 _locals = {'self': self}
329
67c0f31 @devhawk added _input_debug_cmd (aka the debug console)
authored
330 while True:
1993f26 @devhawk tweaked _input_repl_cmd and added support Ctrl-Z to exit the REPL con…
authored
331 Console.Write(">>>" if not cmd else "...")
0e68e83 @devhawk updated _input_repl_cmd to use codeop.compile_command from PSL
authored
332
67c0f31 @devhawk added _input_debug_cmd (aka the debug console)
authored
333 line = Console.ReadLine()
1993f26 @devhawk tweaked _input_repl_cmd and added support Ctrl-Z to exit the REPL con…
authored
334 if line == None:
0e68e83 @devhawk updated _input_repl_cmd to use codeop.compile_command from PSL
authored
335 break
336
1993f26 @devhawk tweaked _input_repl_cmd and added support Ctrl-Z to exit the REPL con…
authored
337 if line:
338 cmd = cmd + line + "\n"
339 else:
340 try:
341 if len(cmd) > 0:
342 exec compile(cmd, "<input>", "single") in globals(),_locals
343 except Exception, ex:
344 with CC.Red: print type(ex), ex
0e68e83 @devhawk updated _input_repl_cmd to use codeop.compile_command from PSL
authored
345 cmd = ""
67c0f31 @devhawk added _input_debug_cmd (aka the debug console)
authored
346
d56c115 @devhawk Added inputcmd decorator to automatically store command methods in a …
authored
347 @inputcmd(_inputcmds, ConsoleKey.Spacebar)
348 def _input_continue_cmd(self, keyinfo):
349 print "\nContinuing"
350 return True
351
352 @inputcmd(_inputcmds, ConsoleKey.Q)
353 def _input_quit_cmd(self, keyinfo):
354 print "\nQuitting"
355 self.process.Stop(0)
356 self.process.Terminate(255)
357 return True
59712bd @devhawk refactored value printing code in _input_locals_cmd into seperate fun…
authored
358
d56c115 @devhawk Added inputcmd decorator to automatically store command methods in a …
authored
359 @inputcmd(_inputcmds, ConsoleKey.L)
360 def _input_locals_cmd(self, keyinfo):
59712bd @devhawk refactored value printing code in _input_locals_cmd into seperate fun…
authored
361 def print_value(name, value):
362 display, type_name = display_value(extract_value(value))
d56c115 @devhawk Added inputcmd decorator to automatically store command methods in a …
authored
363 with CC.Magenta: print " ", name,
9dd12da @devhawk refactored CorValue display code out of _input_locals_cmd and into di…
authored
364 print display,
365 with CC.Green: print type_name
59712bd @devhawk refactored value printing code in _input_locals_cmd into seperate fun…
authored
366
b858056 @devhawk refactored value looping code into print_all_values function
authored
367 def print_all_values(f, show_hidden):
368 count = 0
4495bbc @devhawk moved show_hiding code to client method (_input_locals_cmd)
authored
369 for name,value in f(self.active_thread.ActiveFrame):
370 if name.startswith("$") and not show_hidden:
371 continue
b858056 @devhawk refactored value looping code into print_all_values function
authored
372 print_value(name, value)
373 count+=1
374 return count
375
59712bd @devhawk refactored value printing code in _input_locals_cmd into seperate fun…
authored
376 print "\nLocals"
377 show_hidden = (keyinfo.Modifiers & ConsoleModifiers.Alt) == ConsoleModifiers.Alt
b858056 @devhawk refactored value looping code into print_all_values function
authored
378 count = print_all_values(get_locals, show_hidden)
379 count += print_all_values(get_arguments, show_hidden)
380
59712bd @devhawk refactored value printing code in _input_locals_cmd into seperate fun…
authored
381 if count == 0:
d56c115 @devhawk Added inputcmd decorator to automatically store command methods in a …
authored
382 with CC.Magenta: print " No Locals Found"
383
384 @inputcmd(_inputcmds, ConsoleKey.T)
385 def _input_stack_trace_cmd(self, keyinfo):
386 print "\nStack Trace"
387 get_frames = get_dynamic_frames(self.active_thread.ActiveChain) \
388 if (keyinfo.Modifiers & ConsoleModifiers.Alt) != ConsoleModifiers.Alt \
389 else self.active_thread.ActiveChain.Frames
390 for f in get_frames:
391 offset, sp = get_frame_location(f)
392 method_info = f.GetMethodInfo()
393 print " ",
394 if method_info != None:
395 print "%s::%s --" % (method_info.DeclaringType.Name, method_info.Name),
396 print sp if sp != None else "(offset %d)" % offset, f.FrameType
397 return False
398
399 @inputcmd(_inputcmds, ConsoleKey.S)
400 def _input_step_over_cmd(self, keyinfo):
401 print "\nStepping"
402 do_step(self.active_thread, False)
403 return True
404
405 @inputcmd(_inputcmds, ConsoleKey.I)
406 def _input_step_in_cmd(self, keyinfo):
407 print "\nStepping In"
408 do_step(self.active_thread, True)
409 return True
410
411 @inputcmd(_inputcmds, ConsoleKey.O)
412 def _input_step_out_cmd(self, keyinfo):
413 print "\nStepping Out"
414 stepper = create_stepper(self.active_thread)
415 stepper.StepOut()
416 return True
417
c223608 @devhawk added _bp_add function for adding breakpoints
authored
418 @inputcmd(_breakpointcmds, ConsoleKey.A)
419 def _bp_add(self, keyinfo):
420 try:
421 args = Console.ReadLine().Trim().split(':')
422 if len(args) != 2: raise Exception, "Only pass two arguments"
423 linenum = int(args[1])
424
425 for assm in self.active_appdomain.Assemblies:
426 for mod in assm.Modules:
427 bp = create_breakpoint(mod, args[0], linenum)
428 if bp != None:
0de57ed @devhawk moved to storing breakpoint list in IPyDebugProces instead of queryin…
authored
429 self.breakpoints.append(bp)
c223608 @devhawk added _bp_add function for adding breakpoints
authored
430 bp.Activate(True)
431 Console.WriteLine( "Breakpoint set")
432 return False
433 raise Exception, "Couldn't find %s:%d" % (args[0], linenum)
434
435 except Exception, msg:
436 with CC.Red:
437 print "Add breakpoint failed", msg
438
47a92ed @devhawk renamed _breakpoint_mgmt to input_breakpoint and changed it to use @i…
authored
439 @inputcmd(_breakpointcmds, ConsoleKey.L)
440 def _bp_list(self, keyinfo):
441 print "\nList Breakpoints"
0de57ed @devhawk moved to storing breakpoint list in IPyDebugProces instead of queryin…
authored
442 for i, bp in enumerate(self.breakpoints):
47a92ed @devhawk renamed _breakpoint_mgmt to input_breakpoint and changed it to use @i…
authored
443 sp = get_location(bp.Function, bp.Offset)
e31fcf5 @devhawk updated _bp_list to include breakpoint number and state (active or in…
authored
444 state = "Active" if bp.IsActive else "Inactive"
445 print " %d. %s:%d %s" % (i+1, sp.doc.URL, sp.start_line, state)
47a92ed @devhawk renamed _breakpoint_mgmt to input_breakpoint and changed it to use @i…
authored
446 return False
447
0de57ed @devhawk moved to storing breakpoint list in IPyDebugProces instead of queryin…
authored
448 @inputcmd(_breakpointcmds, ConsoleKey.E)
449 def _bp_enable(self, keyinfo):
b0caaf2 @devhawk refactored common parts of _bp_enable and _bp_disable into _set_bp_st…
authored
450 self._set_bp_status(True)
0de57ed @devhawk moved to storing breakpoint list in IPyDebugProces instead of queryin…
authored
451
452 @inputcmd(_breakpointcmds, ConsoleKey.D)
453 def _bp_disable(self, keyinfo):
b0caaf2 @devhawk refactored common parts of _bp_enable and _bp_disable into _set_bp_st…
authored
454 self._set_bp_status(False)
455
456 def _set_bp_status(self, activate):
457 stat = "Enable" if activate else "Disable"
0de57ed @devhawk moved to storing breakpoint list in IPyDebugProces instead of queryin…
authored
458 try:
459 bp_num = int(Console.ReadLine())
460 for i, bp in enumerate(self.breakpoints):
68db593 @devhawk added _bp_delete command
authored
461 if i+1 == bp_num:
b0caaf2 @devhawk refactored common parts of _bp_enable and _bp_disable into _set_bp_st…
authored
462 bp.Activate(activate)
463 print "\nBreakpoint %d %sd" % (bp_num, stat)
68db593 @devhawk added _bp_delete command
authored
464 return False
465 raise Exception, "Breakpoint %d not found" % bp_num
466
467 except Exception, msg:
b0caaf2 @devhawk refactored common parts of _bp_enable and _bp_disable into _set_bp_st…
authored
468 with CC.Red: print "&s breakpoint Failed %s" % (stat, msg)
469
2a54def @devhawk breakpoint work in progress
authored
470 @inputcmd(_inputcmds, ConsoleKey.B)
47a92ed @devhawk renamed _breakpoint_mgmt to input_breakpoint and changed it to use @i…
authored
471 def _input_breakpoint(self, keyinfo):
472 keyinfo2 = Console.ReadKey()
473 if keyinfo2.Key in IPyDebugProcess._breakpointcmds:
474 return IPyDebugProcess._breakpointcmds[keyinfo2.Key](self, keyinfo2)
475 else:
476 print "\nInvalid breakpoint command", str(keyinfo2.Key)
477 return False
2a54def @devhawk breakpoint work in progress
authored
478
df3a46a @devhawk Refactored ipydbg code into a class IPyDebugProcess
authored
479 def _input(self):
150c1fa @devhawk refactored get_location into seperate get_location and get_frame_loca…
authored
480 offset, sp = get_frame_location(self.active_thread.ActiveFrame)
2e76819 @devhawk added code to show current line of code at top of input loop
authored
481 lines = self._get_file(sp.doc.URL)
5359ea5 @devhawk added _print_source_line to colorize current source line printing
authored
482 self._print_source_line(sp, lines)
df3a46a @devhawk Refactored ipydbg code into a class IPyDebugProcess
authored
483
d56c115 @devhawk Added inputcmd decorator to automatically store command methods in a …
authored
484 while True:
485 print "ipydbg» ",
486 keyinfo = Console.ReadKey()
487 if keyinfo.Key in IPyDebugProcess._inputcmds:
488 if IPyDebugProcess._inputcmds[keyinfo.Key](self, keyinfo):
36a012c @devhawk added step functionality (step, step in and step out)
authored
489 return
df3a46a @devhawk Refactored ipydbg code into a class IPyDebugProcess
authored
490 else:
491 print "\nPlease enter a valid command"
492
493 def OnCreateAppDomain(self, sender,e):
41285e5 @devhawk moved console color code to consolecolor.py file
authored
494 with CC.DarkGray:
fac586f @devhawk Added ConsoleColorMgr class and modified all event handler to print i…
authored
495 print "OnCreateAppDomain", e.AppDomain.Name
df3a46a @devhawk Refactored ipydbg code into a class IPyDebugProcess
authored
496 e.AppDomain.Attach()
497
498 def OnProcessExit(self, sender,e):
41285e5 @devhawk moved console color code to consolecolor.py file
authored
499 with CC.DarkGray:
fac586f @devhawk Added ConsoleColorMgr class and modified all event handler to print i…
authored
500 print "OnProcessExit"
df3a46a @devhawk Refactored ipydbg code into a class IPyDebugProcess
authored
501 self.terminate_event.Set()
39eb5ea @devhawk Added JMC support
authored
502
63000a7 @devhawk moved infrastructure_methods to be a static field on IPyDebugProcess
authored
503 infrastructure_methods = ['TryGetExtraValue',
504 'TrySetExtraValue',
505 '.cctor',
506 '.ctor',
507 'CustomSymbolDictionary.GetExtraKeys',
508 'IModuleDictionaryInitialization.InitializeModuleDictionary']
509
39eb5ea @devhawk Added JMC support
authored
510 def OnClassLoad(self, sender, e):
0b50760 @devhawk Moved GetMethodInfo for frames and functions to C#. Moved GetTYpeInfo…
authored
511 mt = e.Class.GetTypeInfo()
41285e5 @devhawk moved console color code to consolecolor.py file
authored
512 with CC.DarkGray:
fac586f @devhawk Added ConsoleColorMgr class and modified all event handler to print i…
authored
513 print "OnClassLoad", mt.Name
39eb5ea @devhawk Added JMC support
authored
514
515 #python code is always in a dynamic module,
516 #so non-dynamic modules aren't JMC
517 if not e.Class.Module.IsDynamic:
518 e.Class.JMCStatus = False
519
520 #python classes in the IronPython.NewTypes only implement python class
521 #semantics, they have no python code in them so they aren't JMC
522 elif mt.Name.startswith('IronPython.NewTypes'):
523 e.Class.JMCStatus = False
524
525 #assume that dynamic module classes not in the IronPython.NewTypes
526 #namespace are python modules, so mark them as JMC and iterate thru
527 #the methods looking for standard infrastructure methods to mark as
528 #JMC disabled
529 else:
530 e.Class.JMCStatus = True
531
532 for mmi in mt.GetMethods():
63000a7 @devhawk moved infrastructure_methods to be a static field on IPyDebugProcess
authored
533 if mmi.Name in IPyDebugProcess.infrastructure_methods:
39eb5ea @devhawk Added JMC support
authored
534 f = e.Class.Module.GetFunctionFromToken(mmi.MetadataToken)
535 f.JMCStatus = False
df3a46a @devhawk Refactored ipydbg code into a class IPyDebugProcess
authored
536
537 def OnUpdateModuleSymbols(self, sender,e):
41285e5 @devhawk moved console color code to consolecolor.py file
authored
538 with CC.DarkGray:
b53ac99 @devhawk Added SymbolReader support to CorModule and updated ipydbg to use
authored
539 print "OnUpdateModuleSymbols", e.Module.Name
df3a46a @devhawk Refactored ipydbg code into a class IPyDebugProcess
authored
540
b53ac99 @devhawk Added SymbolReader support to CorModule and updated ipydbg to use
authored
541 e.Module.UpdateSymbolReaderFromStream(e.Stream)
5381899 @devhawk moved code to search thru all the symbol documents in a module from O…
authored
542 if self.initial_breakpoint == None:
543 self.initial_breakpoint = create_breakpoint(e.Module, self.py_file, 1)
544 if self.initial_breakpoint != None:
545 self.initial_breakpoint.Activate(True)
0de57ed @devhawk moved to storing breakpoint list in IPyDebugProces instead of queryin…
authored
546 self.breakpoints.append(self.initial_breakpoint)
df3a46a @devhawk Refactored ipydbg code into a class IPyDebugProcess
authored
547
548 def OnBreakpoint(self, sender,e):
0b50760 @devhawk Moved GetMethodInfo for frames and functions to C#. Moved GetTYpeInfo…
authored
549 method_info = e.Thread.ActiveFrame.Function.GetMethodInfo()
150c1fa @devhawk refactored get_location into seperate get_location and get_frame_loca…
authored
550 offset, sp = get_frame_location(e.Thread.ActiveFrame)
41285e5 @devhawk moved console color code to consolecolor.py file
authored
551 with CC.DarkGray:
fac586f @devhawk Added ConsoleColorMgr class and modified all event handler to print i…
authored
552 print "OnBreakpoint", method_info.Name, "Location:", sp if sp != None else "offset %d" % offset
df3a46a @devhawk Refactored ipydbg code into a class IPyDebugProcess
authored
553 self._do_break_event(e)
554
555 def OnStepComplete(self, sender,e):
150c1fa @devhawk refactored get_location into seperate get_location and get_frame_loca…
authored
556 offset, sp = get_frame_location(e.Thread.ActiveFrame)
41285e5 @devhawk moved console color code to consolecolor.py file
authored
557 with CC.DarkGray:
fac586f @devhawk Added ConsoleColorMgr class and modified all event handler to print i…
authored
558 print "OnStepComplete Reason:", e.StepReason, "Location:", sp if sp != None else "offset %d" % offset
2ab015f @devhawk modified OnStepComplete to automatically step to the first sequence p…
authored
559 if e.StepReason == CorDebugStepReason.STEP_CALL:
a12e505 @devhawk moved _get_location and _do_step out of IPyDebugProcess
authored
560 do_step(e.Thread, False)
2ab015f @devhawk modified OnStepComplete to automatically step to the first sequence p…
authored
561 else:
562 self._do_break_event(e)
563
df3a46a @devhawk Refactored ipydbg code into a class IPyDebugProcess
authored
564 def _do_break_event(self, e):
0cc6f38 @devhawk added active_appdomain field to IPyDebugProcess and updated run to re…
authored
565 self.active_appdomain = e.AppDomain
df3a46a @devhawk Refactored ipydbg code into a class IPyDebugProcess
authored
566 self.active_thread = e.Thread
567 e.Continue = False
568 self.break_event.Set()
569
2e76819 @devhawk added code to show current line of code at top of input loop
authored
570 def _get_file(self,filename):
caee624 @devhawk Fixed bug in IPyDebugProcess._get_file - changed GetFileName to GetFu…
authored
571 filename = Path.GetFullPath(filename)
2e76819 @devhawk added code to show current line of code at top of input loop
authored
572 if not filename in self.source_files:
573 self.source_files[filename] = File.ReadAllLines(filename)
574 return self.source_files[filename]
575
a12e505 @devhawk moved _get_location and _do_step out of IPyDebugProcess
authored
576
36a012c @devhawk added step functionality (step, step in and step out)
authored
577
df3a46a @devhawk Refactored ipydbg code into a class IPyDebugProcess
authored
578
117cdce @devhawk added run_debugger to handle setting up an MTA thread if needed
authored
579 def run_debugger(py_file):
580 if Thread.CurrentThread.GetApartmentState() == ApartmentState.STA:
581 t = Thread(ParameterizedThreadStart(run_debugger))
582 t.SetApartmentState(ApartmentState.MTA)
583 t.Start(py_file)
584 t.Join()
585 else:
c2e5ee6 @devhawk added logic to spin up MTA thread if ipydbg is run from an STA thread
authored
586 p = IPyDebugProcess()
587 p.run(py_file)
588
117cdce @devhawk added run_debugger to handle setting up an MTA thread if needed
authored
589 if __name__ == "__main__":
590
591 run_debugger(sys.argv[1])
0840b8c @devhawk Minor cleanup - changing Console.WriteLine to print and formatting so…
authored
592
593
Something went wrong with that request. Please try again.