Simplify command exception debugging and make stdio work correctly (#251)

* Simplify command exception debugging and make stdio work correctly

* Make isort happy

* Reorganize exception handler, add default case

* Fix print statement

* Attempt to use ipdb where available

* Sort requirements and add ipdb

* Only use pwndbg.stdio in the exception handler

* Documentation, hook pdb.set_trace()

* Do not require ipdb

* Remove import loop, fix accidental call, set python print-stack

* Use the correct values for print-stack

* Use pdb.Pdb for better set_trace()
pull/276/head
Zach Riggle 9 years ago committed by GitHub
parent 5861c6a675
commit 63d107c1aa

@ -56,6 +56,7 @@ import pwndbg.disasm.sparc
import pwndbg.disasm.x86
import pwndbg.dt
import pwndbg.elf
import pwndbg.exception
import pwndbg.heap
import pwndbg.inthook
import pwndbg.memory
@ -64,7 +65,6 @@ import pwndbg.proc
import pwndbg.prompt
import pwndbg.regs
import pwndbg.stack
import pwndbg.stdio
import pwndbg.typeinfo
import pwndbg.version
import pwndbg.vmmap

@ -6,22 +6,19 @@ from __future__ import print_function
from __future__ import unicode_literals
import functools
import traceback
import gdb
import pwndbg.chain
import pwndbg.color
import pwndbg.enhance
import pwndbg.exception
import pwndbg.hexdump
import pwndbg.memory
import pwndbg.regs
import pwndbg.stdio
import pwndbg.symbol
import pwndbg.ui
debug = True
class _Command(gdb.Command):
"""Generic command wrapper"""
@ -48,8 +45,7 @@ class _Command(gdb.Command):
self.repeat = self.check_repeated(argument, from_tty)
return self(*argv)
except TypeError:
if debug:
print(traceback.format_exc())
pwndbg.exception.handle()
raise
finally:
self.repeat = False
@ -88,14 +84,13 @@ class _Command(gdb.Command):
def __call__(self, *args, **kwargs):
try:
with pwndbg.stdio.stdio:
return self.function(*args, **kwargs)
return self.function(*args, **kwargs)
except TypeError as te:
print(te)
print('%r: %s' % (self.function.__name__.strip(),
self.function.__doc__.strip()))
pwndbg.exception.handle()
except Exception:
print(traceback.format_exc())
pwndbg.exception.handle()
class _ParsedCommand(_Command):

@ -18,7 +18,7 @@ import gdb
import pwndbg.color
import pwndbg.config
import pwndbg.stdio
import pwndbg.exception
debug = pwndbg.config.Parameter('debug-events', False, 'display internal event debugging info')
@ -116,16 +116,14 @@ def connect(func, event_handler, name=''):
objfile_cache.add(path)
if pause: return
with pwndbg.stdio.stdio:
try:
func()
except Exception as e:
msg = "Exception during func={}.{} {!r}".format(func.__module__, func.__name__, a)
msg = pwndbg.color.red(msg)
print(msg, file=sys.stderr)
traceback.print_exc()
raise e
if pause:
return
try:
func()
except Exception as e:
pwndbg.exception.handle()
raise e
registered[event_handler].append(caller)
event_handler.connect(caller)

@ -0,0 +1,65 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import functools
import pdb
import sys
import traceback
import gdb
import pwndbg.config
try:
import ipdb as pdb
except ImportError:
pass
verbose = pwndbg.config.Parameter('exception-verbose', False, 'whether to print a full stacktracefor exceptions raised in Pwndbg commands')
debug = pwndbg.config.Parameter('exception-debugger', False, 'whether to debug exceptions raised in Pwndbg commands')
def handle():
"""Displays an exception to the user, optionally displaying a full traceback
and spawning an interactive post-moretem debugger.
Notes:
- ``set exception-verbose on`` enables stack traces.
- ``set exception-debugger on`` enables the post-mortem debugger.
"""
# Display the error
if debug or verbose:
print(traceback.format_exc())
else:
exc_type, exc_value, exc_traceback = sys.exc_info()
print(exc_type, exc_value)
# Break into the interactive debugger
if debug:
with pwndbg.stdio.stdio:
pdb.post_mortem()
@functools.wraps(pdb.set_trace)
def set_trace():
"""Enable sane debugging in Pwndbg by switching to the "real" stdio.
"""
debugger = pdb.Pdb(stdin=sys.__stdin__,
stdout=sys.__stdout__,
skip=['pwndbg.stdio', 'pwndbg.exception'])
debugger.set_trace()
pdb.set_trace = set_trace
@pwndbg.config.Trigger([verbose, debug])
def update():
if verbose or debug:
command = 'set python print-stack full'
else:
command = 'set python print-stack message'
gdb.execute(command, from_tty=True, to_string=True)

@ -9,7 +9,6 @@ import gdb
import pwndbg.events
import pwndbg.memoize
import pwndbg.stdio
hint_msg = 'Loaded %i commands. Type pwndbg [filter] for a list.' % len(pwndbg.commands._Command.commands)
@ -31,7 +30,6 @@ def prompt_hook(*a):
@pwndbg.memoize.reset_on_stop
def prompt_hook_on_stop(*a):
with pwndbg.stdio.stdio:
pwndbg.commands.context.context()
pwndbg.commands.context.context()
gdb.prompt_hook = prompt_hook

@ -19,36 +19,17 @@ import gdb
import pwndbg.compat
def get(fd, mode):
if pwndbg.compat.python3:
file = io.open(fd, mode=mode, buffering=0)
kw ={}
if pwndbg.compat.python3:
kw['write_through']=True
return io.TextIOWrapper(file, **kw)
else:
return codecs.open(fd, mode, 'utf-8')
class Stdio(object):
queue = []
def __enter__(self, *a, **kw):
self.queue.append((sys.stdin, sys.stdout, sys.stderr))
if pwndbg.compat.python3 or True:
sys.stdin = get('/dev/stdin', 'rb')
sys.stdout = get('/dev/stdout', 'wb')
sys.stderr = get('/dev/stderr', 'wb')
sys.stdin = sys.__stdin__
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
def __exit__(self, *a, **kw):
sys.stdin, sys.stdout, sys.stderr = self.queue.pop()
stdio = Stdio()
if False:
sys.stdin = get(0, 'rb')
sys.stdout = get(1, 'wb')
sys.stderr = get(2, 'wb')

@ -1,11 +1,11 @@
future
isort
pip
pycparser
psutil>=3.1.0
python-ptrace>=0.8
pycparser
pyelftools
isort
six
future
python-ptrace>=0.8
ROPgadget
six
unicorn>=1.0.0
https://github.com/aquynh/capstone/archive/next.zip#subdirectory=bindings/python
Loading…
Cancel
Save