diff options
author | Robert Bradshaw <robertwb@math.washington.edu> | 2011-01-14 00:31:44 -0800 |
---|---|---|
committer | Robert Bradshaw <robertwb@math.washington.edu> | 2011-01-14 00:34:11 -0800 |
commit | 5f53144925e796bc7a92cf29f86b37e46514acfe (patch) | |
tree | 88712a1477c6b931c8828f71da1df0389c27fe5a /Cython/Debugger/libpython.py | |
parent | c5e16a3f5c5964b2e79cc9bc998a33197afed05a (diff) | |
download | cython-5f53144925e796bc7a92cf29f86b37e46514acfe.tar.gz |
Undo EOL whitespace additions.
Diffstat (limited to 'Cython/Debugger/libpython.py')
-rw-r--r-- | Cython/Debugger/libpython.py | 356 |
1 files changed, 178 insertions, 178 deletions
diff --git a/Cython/Debugger/libpython.py b/Cython/Debugger/libpython.py index 6df87f857..fd09e82d5 100644 --- a/Cython/Debugger/libpython.py +++ b/Cython/Debugger/libpython.py @@ -162,7 +162,7 @@ class TruncatedStringIO(object): all_pretty_typenames = set() class PrettyPrinterTrackerMeta(type): - + def __init__(self, name, bases, dict): super(PrettyPrinterTrackerMeta, self).__init__(name, bases, dict) all_pretty_typenames.add(self._typename) @@ -179,11 +179,11 @@ class PyObjectPtr(object): Note that at every stage the underlying pointer could be NULL, point to corrupt data, etc; this is the debugger, after all. """ - + __metaclass__ = PrettyPrinterTrackerMeta - + _typename = 'PyObject' - + def __init__(self, gdbval, cast_to=None): if cast_to: self._gdbval = gdbval.cast(cast_to) @@ -356,7 +356,7 @@ class PyObjectPtr(object): #print 'tp_flags = 0x%08x' % tp_flags #print 'tp_name = %r' % tp_name - + name_map = {'bool': PyBoolObjectPtr, 'classobj': PyClassObjectPtr, 'instance': PyInstanceObjectPtr, @@ -368,7 +368,7 @@ class PyObjectPtr(object): } if tp_name in name_map: return name_map[tp_name] - + if tp_flags & (Py_TPFLAGS_HEAPTYPE|Py_TPFLAGS_TYPE_SUBCLASS): return PyTypeObjectPtr @@ -484,7 +484,7 @@ def _PyObject_VAR_SIZE(typeobj, nitems): class PyTypeObjectPtr(PyObjectPtr): _typename = 'PyTypeObject' - + def get_attr_dict(self): ''' Get the PyDictObject ptr representing the attribute dictionary @@ -543,13 +543,13 @@ class PyTypeObjectPtr(PyObjectPtr): out.write('<...>') return visited.add(self.as_address()) - + try: tp_name = self.field('tp_name').string() except RuntimeError: tp_name = 'unknown' - - out.write('<type %s at remote 0x%x>' % (tp_name, + + out.write('<type %s at remote 0x%x>' % (tp_name, self.as_address())) # pyop_attrdict = self.get_attr_dict() # _write_instance_repr(out, visited, @@ -569,7 +569,7 @@ class PyBaseExceptionObjectPtr(PyObjectPtr): within the process being debugged. """ _typename = 'PyBaseExceptionObject' - + def proxyval(self, visited): # Guard against infinite loops: if self.as_address() in visited: @@ -682,7 +682,7 @@ class PyDictObjectPtr(PyObjectPtr): if not pyop_value.is_null(): pyop_key = PyObjectPtr.from_pyobject_ptr(ep['me_key']) yield (pyop_key, pyop_value) - + def proxyval(self, visited): # Guard against infinite loops: if self.as_address() in visited: @@ -716,7 +716,7 @@ class PyDictObjectPtr(PyObjectPtr): class PyInstanceObjectPtr(PyObjectPtr): _typename = 'PyInstanceObject' - + def proxyval(self, visited): # Guard against infinite loops: if self.as_address() in visited: @@ -761,7 +761,7 @@ class PyIntObjectPtr(PyObjectPtr): class PyListObjectPtr(PyObjectPtr): _typename = 'PyListObject' - + def __getitem__(self, i): # Get the gdb.Value for the (PyObject*) with the given index: field_ob_item = self.field('ob_item') @@ -794,7 +794,7 @@ class PyListObjectPtr(PyObjectPtr): class PyLongObjectPtr(PyObjectPtr): _typename = 'PyLongObject' - + def proxyval(self, visited): ''' Python's Include/longobjrep.h has this declaration: @@ -812,7 +812,7 @@ class PyLongObjectPtr(PyObjectPtr): where SHIFT can be either: #define PyLong_SHIFT 30 #define PyLong_SHIFT 15 - ''' + ''' ob_size = long(self.field('ob_size')) if ob_size == 0: return 0L @@ -843,7 +843,7 @@ class PyBoolObjectPtr(PyLongObjectPtr): <bool> instances (Py_True/Py_False) within the process being debugged. """ _typename = 'PyBoolObject' - + def proxyval(self, visited): castto = gdb.lookup_type('PyLongObject').pointer() self._gdbval = self._gdbval.cast(castto) @@ -1055,11 +1055,11 @@ class PySetObjectPtr(PyObjectPtr): class PyBytesObjectPtr(PyObjectPtr): _typename = 'PyBytesObject' - + def __str__(self): field_ob_size = self.field('ob_size') field_ob_sval = self.field('ob_sval') - return ''.join(struct.pack('b', field_ob_sval[i]) + return ''.join(struct.pack('b', field_ob_sval[i]) for i in safe_range(field_ob_size)) def proxyval(self, visited): @@ -1076,7 +1076,7 @@ class PyBytesObjectPtr(PyObjectPtr): quote = "'" if "'" in proxy and not '"' in proxy: quote = '"' - + if py3: out.write('b') @@ -1221,7 +1221,7 @@ class PyUnicodeObjectPtr(PyObjectPtr): else: # Python 2, write the 'u' out.write('u') - + if "'" in proxy and '"' not in proxy: quote = '"' else: @@ -1686,11 +1686,11 @@ class PyLocals(gdb.Command): namespace = self.get_namespace(pyop_frame) namespace = [(name.proxyval(set()), val) for name, val in namespace] - + if namespace: name, val = max(namespace, key=lambda (name, val): len(name)) max_name_length = len(name) - + for name, pyop_value in namespace: value = pyop_value.get_truncated_repr(MAX_OUTPUT_LEN) print ('%-*s = %s' % (max_name_length, name, value)) @@ -1701,7 +1701,7 @@ class PyLocals(gdb.Command): class PyGlobals(PyLocals): 'List all the globals in the currently select Python frame' - + def get_namespace(self, pyop_frame): return pyop_frame.iter_globals() @@ -1711,7 +1711,7 @@ PyGlobals("py-globals", gdb.COMMAND_DATA, gdb.COMPLETE_NONE) class PyNameEquals(gdb.Function): - + def _get_pycurframe_attr(self, attr): frame = Frame(gdb.selected_frame()) if frame.is_evalframeex(): @@ -1720,11 +1720,11 @@ class PyNameEquals(gdb.Function): warnings.warn("Use a Python debug build, Python breakpoints " "won't work otherwise.") return None - + return getattr(pyframe, attr).proxyval(set()) - + return None - + def invoke(self, funcname): attr = self._get_pycurframe_attr('co_name') return attr is not None and attr == funcname.string() @@ -1733,7 +1733,7 @@ PyNameEquals("pyname_equals") class PyModEquals(PyNameEquals): - + def invoke(self, modname): attr = self._get_pycurframe_attr('co_filename') if attr is not None: @@ -1747,20 +1747,20 @@ PyModEquals("pymod_equals") class PyBreak(gdb.Command): """ Set a Python breakpoint. Examples: - + Break on any function or method named 'func' in module 'modname' - - py-break modname.func - + + py-break modname.func + Break on any function or method named 'func' - + py-break func """ - + def invoke(self, funcname, from_tty): if '.' in funcname: modname, dot, funcname = funcname.rpartition('.') - cond = '$pyname_equals("%s") && $pymod_equals("%s")' % (funcname, + cond = '$pyname_equals("%s") && $pymod_equals("%s")' % (funcname, modname) else: cond = '$pyname_equals("%s")' % funcname @@ -1774,31 +1774,31 @@ class _LoggingState(object): """ State that helps to provide a reentrant gdb.execute() function. """ - + def __init__(self): self.fd, self.filename = tempfile.mkstemp() self.file = os.fdopen(self.fd, 'r+') _execute("set logging file %s" % self.filename) self.file_position_stack = [] - + atexit.register(os.close, self.fd) atexit.register(os.remove, self.filename) - + def __enter__(self): if not self.file_position_stack: _execute("set logging redirect on") _execute("set logging on") _execute("set pagination off") - + self.file_position_stack.append(os.fstat(self.fd).st_size) return self - + def getoutput(self): gdb.flush() self.file.seek(self.file_position_stack[-1]) result = self.file.read() return result - + def __exit__(self, exc_type, exc_val, tb): startpos = self.file_position_stack.pop() self.file.seek(startpos) @@ -1812,7 +1812,7 @@ class _LoggingState(object): def execute(command, from_tty=False, to_string=False): """ Replace gdb.execute() with this function and have it accept a 'to_string' - argument (new in 7.2). Have it properly capture stderr also. Ensure + argument (new in 7.2). Have it properly capture stderr also. Ensure reentrancy. """ if to_string: @@ -1835,9 +1835,9 @@ def get_selected_inferior(): # Woooh, another bug in gdb! Is there an end in sight? # http://sourceware.org/bugzilla/show_bug.cgi?id=12212 return gdb.inferiors()[0] - + selected_thread = gdb.selected_thread() - + for inferior in gdb.inferiors(): for thread in inferior.threads(): if thread == selected_thread: @@ -1847,7 +1847,7 @@ def source_gdb_script(script_contents, to_string=False): """ Source a gdb script with script_contents passed as a string. This is useful to provide defines for py-step and py-next to make them repeatable (this is - not possible with gdb.execute()). See + not possible with gdb.execute()). See http://sourceware.org/bugzilla/show_bug.cgi?id=12216 """ fd, filename = tempfile.mkstemp() @@ -1862,20 +1862,20 @@ def register_defines(): define py-step -py-step end - + define py-next -py-next end - + document py-step %s end - + document py-next %s end """) % (PyStep.__doc__, PyNext.__doc__)) - + def stackdepth(frame): "Tells the stackdepth of a gdb frame." @@ -1883,16 +1883,16 @@ def stackdepth(frame): while frame: frame = frame.older() depth += 1 - + return depth class ExecutionControlCommandBase(gdb.Command): """ Superclass for language specific execution control. Language specific - features should be implemented by lang_info using the LanguageInfo + features should be implemented by lang_info using the LanguageInfo interface. 'name' is the name of the command. """ - + def __init__(self, name, lang_info): super(ExecutionControlCommandBase, self).__init__( name, gdb.COMMAND_RUNNING, gdb.COMPLETE_NONE) @@ -1902,40 +1902,40 @@ class ExecutionControlCommandBase(gdb.Command): all_locations = itertools.chain( self.lang_info.static_break_functions(), self.lang_info.runtime_break_functions()) - + for location in all_locations: result = gdb.execute('break %s' % location, to_string=True) yield re.search(r'Breakpoint (\d+)', result).group(1) - + def delete_breakpoints(self, breakpoint_list): for bp in breakpoint_list: gdb.execute("delete %s" % bp) - + def filter_output(self, result): output = [] - + match_finish = re.search(r'^Value returned is \$\d+ = (.*)', result, re.MULTILINE) if match_finish: output.append('Value returned: %s' % match_finish.group(1)) - + reflags = re.MULTILINE regexes = [ (r'^Program received signal .*', reflags|re.DOTALL), (r'.*[Ww]arning.*', 0), (r'^Program exited .*', reflags), ] - + for regex, flags in regexes: match = re.search(regex, result, flags) if match: output.append(match.group(0)) - + return '\n'.join(output) - + def stopped(self): return get_selected_inferior().pid == 0 - + def finish_executing(self, result): """ After doing some kind of code running in the inferior, print the line @@ -1943,7 +1943,7 @@ class ExecutionControlCommandBase(gdb.Command): in as the `result` argument). """ result = self.filter_output(result) - + if self.stopped(): print result.strip() else: @@ -1955,10 +1955,10 @@ class ExecutionControlCommandBase(gdb.Command): print self.lang_info.get_source_line(frame) or result else: print result - + def _finish(self): """ - Execute until the function returns (or until something else makes it + Execute until the function returns (or until something else makes it stop) """ if gdb.selected_frame().older() is not None: @@ -1966,83 +1966,83 @@ class ExecutionControlCommandBase(gdb.Command): else: # outermost frame, continue return gdb.execute('cont', to_string=True) - + def _finish_frame(self): """ Execute until the function returns to a relevant caller. """ while True: result = self._finish() - + try: frame = gdb.selected_frame() except RuntimeError: break - + hitbp = re.search(r'Breakpoint (\d+)', result) is_relevant = self.lang_info.is_relevant_function(frame) if hitbp or is_relevant or self.stopped(): break - + return result - + def finish(self, *args): "Implements the finish command." result = self._finish_frame() self.finish_executing(result) - + def step(self, stepinto, stepover_command='next'): """ Do a single step or step-over. Returns the result of the last gdb command that made execution stop. - - This implementation, for stepping, sets (conditional) breakpoints for + + This implementation, for stepping, sets (conditional) breakpoints for all functions that are deemed relevant. It then does a step over until either something halts execution, or until the next line is reached. - - If, however, stepover_command is given, it should be a string gdb - command that continues execution in some way. The idea is that the - caller has set a (conditional) breakpoint or watchpoint that can work + + If, however, stepover_command is given, it should be a string gdb + command that continues execution in some way. The idea is that the + caller has set a (conditional) breakpoint or watchpoint that can work more efficiently than the step-over loop. For Python this means setting - a watchpoint for f->f_lasti, which means we can then subsequently + a watchpoint for f->f_lasti, which means we can then subsequently "finish" frames. - We want f->f_lasti instead of f->f_lineno, because the latter only - works properly with local trace functions, see + We want f->f_lasti instead of f->f_lineno, because the latter only + works properly with local trace functions, see PyFrameObjectPtr.current_line_num and PyFrameObjectPtr.addr2line. """ if stepinto: breakpoint_list = list(self.install_breakpoints()) - + beginframe = gdb.selected_frame() - + if self.lang_info.is_relevant_function(beginframe): # If we start in a relevant frame, initialize stuff properly. If - # we don't start in a relevant frame, the loop will halt - # immediately. So don't call self.lang_info.lineno() as it may + # we don't start in a relevant frame, the loop will halt + # immediately. So don't call self.lang_info.lineno() as it may # raise for irrelevant frames. beginline = self.lang_info.lineno(beginframe) - + if not stepinto: depth = stackdepth(beginframe) - + newframe = beginframe - + while True: if self.lang_info.is_relevant_function(newframe): result = gdb.execute(stepover_command, to_string=True) else: result = self._finish_frame() - + if self.stopped(): break - + newframe = gdb.selected_frame() is_relevant_function = self.lang_info.is_relevant_function(newframe) try: framename = newframe.name() except RuntimeError: framename = None - + m = re.search(r'Breakpoint (\d+)', result) if m: if is_relevant_function and m.group(1) in breakpoint_list: @@ -2050,16 +2050,16 @@ class ExecutionControlCommandBase(gdb.Command): # that the function, in case hit by a runtime breakpoint, # is in the right context break - + if newframe != beginframe: # new function - + if not stepinto: # see if we returned to the caller newdepth = stackdepth(newframe) - is_relevant_function = (newdepth < depth and + is_relevant_function = (newdepth < depth and is_relevant_function) - + if is_relevant_function: break else: @@ -2068,15 +2068,15 @@ class ExecutionControlCommandBase(gdb.Command): lineno = self.lang_info.lineno(newframe) if lineno and lineno != beginline: break - + if stepinto: self.delete_breakpoints(breakpoint_list) self.finish_executing(result) - + def run(self, *args): self.finish_executing(gdb.execute('run', to_string=True)) - + def cont(self, *args): self.finish_executing(gdb.execute('cont', to_string=True)) @@ -2085,32 +2085,32 @@ class LanguageInfo(object): """ This class defines the interface that ExecutionControlCommandBase needs to provide language-specific execution control. - + Classes that implement this interface should implement: - + lineno(frame) Tells the current line number (only called for a relevant frame). If lineno is a false value it is not checked for a difference. - + is_relevant_function(frame) tells whether we care about frame 'frame' - + get_source_line(frame) get the line of source code for the current line (only called for a - relevant frame). If the source code cannot be retrieved this + relevant frame). If the source code cannot be retrieved this function should return None - + exc_info(frame) -- optional tells whether an exception was raised, if so, it should return a string representation of the exception value, None otherwise. - - static_break_functions() - returns an iterable of function names that are considered relevant - and should halt step-into execution. This is needed to provide a + + static_break_functions() + returns an iterable of function names that are considered relevant + and should halt step-into execution. This is needed to provide a performing step-into - + runtime_break_functions() -- optional - list of functions that we should break into depending on the + list of functions that we should break into depending on the context """ @@ -2119,13 +2119,13 @@ class LanguageInfo(object): def runtime_break_functions(self): """ - Implement this if the list of step-into functions depends on the + Implement this if the list of step-into functions depends on the context. """ return () class PythonInfo(LanguageInfo): - + def pyframe(self, frame): pyframe = Frame(frame).get_pyop() if pyframe: @@ -2134,21 +2134,21 @@ class PythonInfo(LanguageInfo): raise gdb.RuntimeError( "Unable to find the Python frame, run your code with a debug " "build (configure with --with-pydebug or compile with -g).") - + def lineno(self, frame): return self.pyframe(frame).current_line_num() - + def is_relevant_function(self, frame): return Frame(frame).is_evalframeex() def get_source_line(self, frame): try: pyframe = self.pyframe(frame) - return '%4d %s' % (pyframe.current_line_num(), + return '%4d %s' % (pyframe.current_line_num(), pyframe.current_line().rstrip()) except IOError, e: return None - + def exc_info(self, frame): try: tstate = frame.read_var('tstate').dereference() @@ -2157,26 +2157,26 @@ class PythonInfo(LanguageInfo): inf_type = tstate['curexc_type'] inf_value = tstate['curexc_value'] if inf_type: - return 'An exception was raised: %s(%s)' % (inf_type, + return 'An exception was raised: %s(%s)' % (inf_type, inf_value) except (ValueError, RuntimeError), e: # Could not read the variable tstate or it's memory, it's ok pass - + def static_break_functions(self): yield 'PyEval_EvalFrameEx' class PythonStepperMixin(object): """ - Make this a mixin so CyStep can also inherit from this and use a + Make this a mixin so CyStep can also inherit from this and use a CythonCodeStepper at the same time. """ - + def python_step(self, stepinto): frame = gdb.selected_frame() framewrapper = Frame(frame) - + output = gdb.execute('watch f->f_lasti', to_string=True) watchpoint = int(re.search(r'[Ww]atchpoint (\d+):', output).group(1)) self.step(stepinto=stepinto, stepover_command='finish') @@ -2185,36 +2185,36 @@ class PythonStepperMixin(object): class PyStep(ExecutionControlCommandBase, PythonStepperMixin): "Step through Python code." - + stepinto = True - + def invoke(self, args, from_tty): self.python_step(stepinto=self.stepinto) - + class PyNext(PyStep): "Step-over Python code." - + stepinto = False - + class PyFinish(ExecutionControlCommandBase): "Execute until function returns to a caller." - + invoke = ExecutionControlCommandBase.finish class PyRun(ExecutionControlCommandBase): "Run the program." - + invoke = ExecutionControlCommandBase.run class PyCont(ExecutionControlCommandBase): - + invoke = ExecutionControlCommandBase.cont def _pointervalue(gdbval): """ - Return the value of the pionter as a Python int. - + Return the value of the pionter as a Python int. + gdbval.type must be a pointer type """ # don't convert with int() as it will raise a RuntimeError @@ -2235,14 +2235,14 @@ def pointervalue(gdbval): # work around yet another bug in gdb where you get random behaviour # and tracebacks pass - + return pointer def get_inferior_unicode_postfix(): try: gdb.parse_and_eval('PyUnicode_FromEncodedObject') except RuntimeError: - try: + try: gdb.parse_and_eval('PyUnicodeUCS2_FromEncodedObject') except RuntimeError: return 'UCS4' @@ -2250,37 +2250,37 @@ def get_inferior_unicode_postfix(): return 'UCS2' else: return '' - + class PythonCodeExecutor(object): - + Py_single_input = 256 Py_file_input = 257 Py_eval_input = 258 - + def malloc(self, size): chunk = (gdb.parse_and_eval("(void *) malloc((size_t) %d)" % size)) - + pointer = pointervalue(chunk) if pointer == 0: raise gdb.GdbError("No memory could be allocated in the inferior.") - + return pointer - + def alloc_string(self, string): pointer = self.malloc(len(string)) get_selected_inferior().write_memory(pointer, string) - + return pointer - + def alloc_pystring(self, string): stringp = self.alloc_string(string) PyString_FromStringAndSize = 'PyString_FromStringAndSize' - + try: gdb.parse_and_eval(PyString_FromStringAndSize) except RuntimeError: # Python 3 - PyString_FromStringAndSize = ('PyUnicode%s_FromStringAndSize' % + PyString_FromStringAndSize = ('PyUnicode%s_FromStringAndSize' % (get_inferior_unicode_postfix,)) try: @@ -2289,59 +2289,59 @@ class PythonCodeExecutor(object): PyString_FromStringAndSize, stringp, len(string))) finally: self.free(stringp) - + pointer = pointervalue(result) if pointer == 0: raise gdb.GdbError("Unable to allocate Python string in " "the inferior.") - + return pointer - + def free(self, pointer): gdb.parse_and_eval("free((void *) %d)" % pointer) - + def incref(self, pointer): "Increment the reference count of a Python object in the inferior." gdb.parse_and_eval('Py_IncRef((PyObject *) %d)' % pointer) - + def decref(self, pointer): "Decrement the reference count of a Python object in the inferior." # Py_DecRef is like Py_XDECREF, but a function. So we don't have # to check for NULL. This should also decref all our allocated # Python strings. gdb.parse_and_eval('Py_DecRef((PyObject *) %d)' % pointer) - + def evalcode(self, code, input_type, global_dict=None, local_dict=None): """ Evaluate python code `code` given as a string in the inferior and return the result as a gdb.Value. Returns a new reference in the inferior. - + Of course, executing any code in the inferior may be dangerous and may leave the debuggee in an unsafe state or terminate it alltogether. """ if '\0' in code: raise gdb.GdbError("String contains NUL byte.") - + code += '\0' - + pointer = self.alloc_string(code) - + globalsp = pointervalue(global_dict) localsp = pointervalue(local_dict) - + if globalsp == 0 or localsp == 0: raise gdb.GdbError("Unable to obtain or create locals or globals.") - + code = """ PyRun_String( (char *) %(code)d, (int) %(start)d, (PyObject *) %(globals)s, (PyObject *) %(locals)d) - """ % dict(code=pointer, start=input_type, + """ % dict(code=pointer, start=input_type, globals=globalsp, locals=localsp) - + with FetchAndRestoreError(): try: self.decref(gdb.parse_and_eval(code)) @@ -2358,25 +2358,25 @@ class FetchAndRestoreError(PythonCodeExecutor): def __init__(self): self.sizeof_PyObjectPtr = gdb.lookup_type('PyObject').pointer().sizeof self.pointer = self.malloc(self.sizeof_PyObjectPtr * 3) - + type = self.pointer value = self.pointer + self.sizeof_PyObjectPtr traceback = self.pointer + self.sizeof_PyObjectPtr * 2 - + self.errstate = type, value, traceback - + def __enter__(self): gdb.parse_and_eval("PyErr_Fetch(%d, %d, %d)" % self.errstate) - + def __exit__(self, *args): if gdb.parse_and_eval("(int) PyErr_Occurred()"): gdb.parse_and_eval("PyErr_Print()") - + pyerr_restore = ("PyErr_Restore(" "(PyObject *) *%d," "(PyObject *) *%d," "(PyObject *) *%d)") - + try: gdb.parse_and_eval(pyerr_restore % self.errstate) finally: @@ -2389,15 +2389,15 @@ class FixGdbCommand(gdb.Command): super(FixGdbCommand, self).__init__(command, gdb.COMMAND_DATA, gdb.COMPLETE_NONE) self.actual_command = actual_command - + def fix_gdb(self): """ - So, you must be wondering what the story is this time! Yeeees, indeed, + So, you must be wondering what the story is this time! Yeeees, indeed, I have quite the story for you! It seems that invoking either 'cy exec' - and 'py-exec' work perfectly fine, but after this gdb's python API is - entirely broken. Some unset exception value is still set? + and 'py-exec' work perfectly fine, but after this gdb's python API is + entirely broken. Some unset exception value is still set? sys.exc_clear() didn't help. A demonstration: - + (gdb) cy exec 'hello' 'hello' (gdb) python gdb.execute('cont') @@ -2405,17 +2405,17 @@ class FixGdbCommand(gdb.Command): Error while executing Python code. (gdb) python gdb.execute('cont') [15148 refs] - + Program exited normally. """ - warnings.filterwarnings('ignore', r'.*', RuntimeWarning, + warnings.filterwarnings('ignore', r'.*', RuntimeWarning, re.escape(__name__)) try: long(gdb.parse_and_eval("(void *) 0")) == 0 except RuntimeError: pass # warnings.resetwarnings() - + def invoke(self, args, from_tty): self.fix_gdb() try: @@ -2426,7 +2426,7 @@ class FixGdbCommand(gdb.Command): class PyExec(gdb.Command): - + def readcode(self, expr): if expr: return expr, PythonCodeExecutor.Py_single_input @@ -2440,23 +2440,23 @@ class PyExec(gdb.Command): else: if line.rstrip() == 'end': break - + lines.append(line) - + return '\n'.join(lines), Py_file_input - + def invoke(self, expr, from_tty): expr, input_type = self.readcode(expr) - + executor = PythonCodeExecutor() global_dict = gdb.parse_and_eval('PyEval_GetGlobals()') local_dict = gdb.parse_and_eval('PyEval_GetLocals()') - + if pointervalue(global_dict) == 0 or pointervalue(local_dict) == 0: raise gdb.GdbError("Unable to find the locals or globals of the " "most recent Python function (relative to the " "selected frame).") - + executor.evalcode(expr, input_type, global_dict, local_dict) @@ -2474,4 +2474,4 @@ if hasattr(gdb, 'GdbError'): py_exec = FixGdbCommand('py-exec', '-py-exec') _py_exec = PyExec("-py-exec", gdb.COMMAND_DATA, gdb.COMPLETE_NONE) else: - warnings.warn("Use gdb 7.2 or higher to use the py-exec command.")
\ No newline at end of file + warnings.warn("Use gdb 7.2 or higher to use the py-exec command.") |