Fixes #460 - getting SP reg on threaded apps (#463)

* Fixes #460 - getting SP reg on threaded apps

As the issue described: as we cache registers,
we might get their values wrong as we don't invalidate cache when thread is changed.

This leads to showing wrong context stack values in threaded apps.

This commit/PR adds a new memoization solution: `reset_on_prompt` which resets cache on `gdb.events.before_prompt` event.

* Fix isort
pull/464/head
Disconnect3d 8 years ago committed by GitHub
parent 96b226f7d0
commit 9fd5d35712
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -10,8 +10,9 @@ from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import functools
import sys
from functools import partial
from functools import wraps
import gdb
@ -65,11 +66,14 @@ gdb.events.start = StartEvent()
# In order to support reloading, we must be able to re-fire
# all 'objfile' and 'stop' events.
registered = {gdb.events.exited: [],
gdb.events.cont: [],
gdb.events.new_objfile: [],
gdb.events.stop: [],
gdb.events.start: []}
registered = {
gdb.events.exited: [],
gdb.events.cont: [],
gdb.events.new_objfile: [],
gdb.events.stop: [],
gdb.events.start: [],
gdb.events.before_prompt: []
}
# GDB 7.9 and above only
try:
@ -96,7 +100,7 @@ def connect(func, event_handler, name=''):
if debug:
print("Connecting", func.__name__, event_handler)
@functools.wraps(func)
@wraps(func)
def caller(*a):
if debug:
sys.stdout.write('%r %s.%s %r\n' % (name, func.__module__, func.__name__, a))
@ -131,6 +135,9 @@ def cont(func): return connect(func, gdb.events.cont, 'cont')
def new_objfile(func): return connect(func, gdb.events.new_objfile, 'obj')
def stop(func): return connect(func, gdb.events.stop, 'stop')
def start(func): return connect(func, gdb.events.start, 'start')
before_prompt = partial(connect, event_handler=gdb.events.before_prompt, name='before_prompt')
def reg_changed(func):
try:
return connect(func, gdb.events.register_changed, 'reg_changed')

@ -96,6 +96,19 @@ class reset_on_stop(memoize):
_reset = __reset_on_stop
class reset_on_prompt(memoize):
caches = []
kind = 'prompt'
@staticmethod
@pwndbg.events.before_prompt
def __reset_on_prompt():
for obj in reset_on_prompt.caches:
obj.cache.clear()
_reset = __reset_on_prompt
class reset_on_exit(memoize):
caches = []
kind = 'exit'

@ -266,7 +266,7 @@ ARCH_GET_GS = 0x1004
class module(ModuleType):
last = {}
@pwndbg.memoize.reset_on_stop
@pwndbg.memoize.reset_on_prompt
def __getattr__(self, attr):
attr = attr.lstrip('$')
try:

Loading…
Cancel
Save