retracesoftware-proxy 0.1.18__py3-none-any.whl → 0.1.20__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- retracesoftware/config.json +3 -0
- retracesoftware/install/patcher.py +65 -30
- retracesoftware/install/record.py +5 -0
- retracesoftware/install/replay.py +4 -0
- retracesoftware/install/tracer.py +76 -43
- retracesoftware/install/typeutils.py +20 -0
- retracesoftware/proxy/proxysystem.py +20 -36
- retracesoftware/proxy/record.py +11 -1
- retracesoftware/proxy/replay.py +17 -2
- {retracesoftware_proxy-0.1.18.dist-info → retracesoftware_proxy-0.1.20.dist-info}/METADATA +1 -1
- {retracesoftware_proxy-0.1.18.dist-info → retracesoftware_proxy-0.1.20.dist-info}/RECORD +13 -13
- {retracesoftware_proxy-0.1.18.dist-info → retracesoftware_proxy-0.1.20.dist-info}/WHEEL +0 -0
- {retracesoftware_proxy-0.1.18.dist-info → retracesoftware_proxy-0.1.20.dist-info}/top_level.txt +0 -0
retracesoftware/config.json
CHANGED
|
@@ -15,6 +15,7 @@ import gc
|
|
|
15
15
|
import os
|
|
16
16
|
import atexit
|
|
17
17
|
import threading
|
|
18
|
+
from types import SimpleNamespace, MethodType
|
|
18
19
|
|
|
19
20
|
from retracesoftware.install.typeutils import modify
|
|
20
21
|
# from retracesoftware.proxy.immutabletypes import ImmutableTypes
|
|
@@ -336,20 +337,20 @@ class Patcher:
|
|
|
336
337
|
@patch
|
|
337
338
|
def patch_exec(self, exec):
|
|
338
339
|
|
|
339
|
-
def
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
340
|
+
def is_module(source, *args):
|
|
341
|
+
return isinstance(source, types.CodeType) and source.co_name == '<module>'
|
|
342
|
+
|
|
343
|
+
def after_exec(source, globals = None, locals = None):
|
|
344
|
+
self(sys.modules[globals['__name__']])
|
|
343
345
|
|
|
344
346
|
def first(x): return x[0]
|
|
345
347
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
return self.thread_state.dispatch(exec, internal = wrapped_exec)
|
|
348
|
+
def disable(func): return self.thread_state.wrap('disabled', func)
|
|
349
|
+
|
|
350
|
+
return self.thread_state.dispatch(
|
|
351
|
+
exec,
|
|
352
|
+
internal = functional.sequence(
|
|
353
|
+
functional.vector(exec, functional.when(is_module, disable(after_exec))), first))
|
|
353
354
|
|
|
354
355
|
# self.thread_state.wrap(desired_state = 'disabled', function = exec_wrapper)
|
|
355
356
|
|
|
@@ -415,14 +416,21 @@ class Patcher:
|
|
|
415
416
|
@patch
|
|
416
417
|
def patch_extension_exec(self, exec):
|
|
417
418
|
|
|
418
|
-
def
|
|
419
|
-
with self.thread_state.select('internal'):
|
|
420
|
-
res = exec(module)
|
|
419
|
+
def first(x): return x[0]
|
|
421
420
|
|
|
422
|
-
|
|
423
|
-
|
|
421
|
+
def disable(func): return self.thread_state.wrap('disabled', func)
|
|
422
|
+
|
|
423
|
+
return self.thread_state.dispatch(exec,
|
|
424
|
+
internal = functional.sequence(functional.vector(exec, disable(self)), first))
|
|
425
|
+
|
|
426
|
+
# def wrapper(module):
|
|
427
|
+
# with self.thread_state.select('internal'):
|
|
428
|
+
# res = exec(module)
|
|
429
|
+
|
|
430
|
+
# self(module)
|
|
431
|
+
# return res
|
|
424
432
|
|
|
425
|
-
return wrapper
|
|
433
|
+
# return wrapper
|
|
426
434
|
|
|
427
435
|
@patch
|
|
428
436
|
def path_predicates(self, func, param):
|
|
@@ -494,9 +502,7 @@ class Patcher:
|
|
|
494
502
|
def patch_module_with_name(self, mod_name, module):
|
|
495
503
|
with self.disable:
|
|
496
504
|
|
|
497
|
-
|
|
498
|
-
print('DWFEWFW!!!!!!!!!')
|
|
499
|
-
|
|
505
|
+
assert self.thread_state.value == 'disabled'
|
|
500
506
|
|
|
501
507
|
self.log('install.module', mod_name)
|
|
502
508
|
|
|
@@ -525,7 +531,7 @@ class Patcher:
|
|
|
525
531
|
self.post_commit(mod_name, updates)
|
|
526
532
|
|
|
527
533
|
def __call__(self, module):
|
|
528
|
-
|
|
534
|
+
|
|
529
535
|
if not hasattr(module, '__retrace__'):
|
|
530
536
|
|
|
531
537
|
configs = list(self.configs(module))
|
|
@@ -616,28 +622,57 @@ def install(mode):
|
|
|
616
622
|
|
|
617
623
|
importlib.invalidate_caches()
|
|
618
624
|
|
|
619
|
-
with thread_state.select('internal'):
|
|
625
|
+
# with thread_state.select('internal'):
|
|
620
626
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
627
|
+
atexit.register(lambda: at_exit)
|
|
628
|
+
|
|
629
|
+
for key, module in list(sys.modules.items()):
|
|
630
|
+
if not key.startswith('retracesoftware'):
|
|
631
|
+
patcher(module)
|
|
626
632
|
|
|
627
|
-
|
|
633
|
+
for library in config.get('preload', []):
|
|
634
|
+
with thread_state.select('internal'):
|
|
628
635
|
importlib.import_module(library)
|
|
629
636
|
|
|
630
637
|
importlib.invalidate_caches()
|
|
631
638
|
# # if env_truthy('RETRACE_TRACE_CALLS'):
|
|
632
639
|
# # trace_calls(system = retracesystem)
|
|
633
640
|
|
|
634
|
-
thread_state.value = 'internal'
|
|
641
|
+
# thread_state.value = 'internal'
|
|
635
642
|
|
|
636
643
|
# import threading
|
|
637
644
|
# threading.current_thread().retrace = system
|
|
638
645
|
|
|
639
646
|
threading.current_thread().__retrace__ = system
|
|
640
647
|
|
|
641
|
-
#
|
|
648
|
+
# original = atexit.register
|
|
649
|
+
|
|
650
|
+
# def atexit_register(function):
|
|
651
|
+
# return original(thread_state.wrap('internal', function))
|
|
652
|
+
|
|
653
|
+
def wrap_internal(func): return thread_state.wrap('internal', func)
|
|
654
|
+
|
|
655
|
+
atexit.register = \
|
|
656
|
+
thread_state.dispatch(atexit.register, internal = functional.sequence(wrap_internal, atexit.register))
|
|
657
|
+
|
|
658
|
+
def disable_after_main(frame):
|
|
659
|
+
if system.is_entry_frame(frame):
|
|
660
|
+
print('enabling retrace!!!!')
|
|
661
|
+
# utils.intercept_frame_eval(None)
|
|
662
|
+
thread_state.value = 'internal'
|
|
663
|
+
|
|
664
|
+
def on_return():
|
|
665
|
+
thread_state.value = 'disabled'
|
|
666
|
+
|
|
667
|
+
obj = SimpleNamespace()
|
|
668
|
+
obj.on_return = on_return
|
|
669
|
+
|
|
670
|
+
return obj
|
|
671
|
+
else:
|
|
672
|
+
return disable_after_main
|
|
673
|
+
|
|
674
|
+
utils.intercept_frame_eval(disable_after_main)
|
|
642
675
|
|
|
676
|
+
# utils.sigtrap(None)
|
|
677
|
+
print(f'retrace installed: {thread_state}')
|
|
643
678
|
return system
|
|
@@ -70,6 +70,10 @@ def record_system(thread_state, immutable_types, config):
|
|
|
70
70
|
with open(recording_path / 'tracing_config.json', 'w') as f:
|
|
71
71
|
json.dump(tracing_config, f, indent=2)
|
|
72
72
|
|
|
73
|
+
def write_main_path(path):
|
|
74
|
+
with open(recording_path / 'mainscript', 'w') as f:
|
|
75
|
+
f.write(path)
|
|
76
|
+
|
|
73
77
|
# writer = stream.writer(path = recording_path / 'trace.bin')
|
|
74
78
|
|
|
75
79
|
# os.register_at_fork(
|
|
@@ -106,4 +110,5 @@ def record_system(thread_state, immutable_types, config):
|
|
|
106
110
|
return RecordProxySystem(thread_state = thread_state,
|
|
107
111
|
immutable_types = immutable_types,
|
|
108
112
|
tracing_config = tracing_config,
|
|
113
|
+
write_main_path = write_main_path,
|
|
109
114
|
path = recording_path / 'trace.bin')
|
|
@@ -48,7 +48,11 @@ def replay_system(thread_state, immutable_types, config):
|
|
|
48
48
|
with open(recording_path / "tracing_config.json", "r", encoding="utf-8") as f:
|
|
49
49
|
tracing_config = json.load(f)
|
|
50
50
|
|
|
51
|
+
with open(recording_path / "mainscript", "r", encoding="utf-8") as f:
|
|
52
|
+
mainscript = f.read()
|
|
53
|
+
|
|
51
54
|
return ReplayProxySystem(thread_state = thread_state,
|
|
52
55
|
immutable_types = immutable_types,
|
|
53
56
|
tracing_config = tracing_config,
|
|
57
|
+
mainscript = mainscript,
|
|
54
58
|
path = recording_path / 'trace.bin')
|
|
@@ -13,6 +13,38 @@ def format_kwargs(kwargs):
|
|
|
13
13
|
|
|
14
14
|
return tuple(result)
|
|
15
15
|
|
|
16
|
+
class CallTracer:
|
|
17
|
+
|
|
18
|
+
ignore = set([('abc', '__subclasscheck__'),
|
|
19
|
+
('threading', '_shutdown'),
|
|
20
|
+
('typing', 'inner')])
|
|
21
|
+
|
|
22
|
+
def __init__(self, writer, thread_state):
|
|
23
|
+
self.writer = writer
|
|
24
|
+
self.thread_state = thread_state
|
|
25
|
+
|
|
26
|
+
def on_result(self, result):
|
|
27
|
+
if type(result) in [str]:
|
|
28
|
+
self.writer(result)
|
|
29
|
+
else:
|
|
30
|
+
self.writer(str(type(result)))
|
|
31
|
+
|
|
32
|
+
def on_error(self, exc_type, exc_value, exc_traceback):
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
def __call__(self, frame):
|
|
36
|
+
if self.thread_state.value == 'internal':
|
|
37
|
+
with self.thread_state.select('disabled'):
|
|
38
|
+
func = frame.function
|
|
39
|
+
|
|
40
|
+
key = (func.__module__, func.__name__)
|
|
41
|
+
|
|
42
|
+
if key not in CallTracer.ignore and func.__name__ != '__hash__':
|
|
43
|
+
self.writer(f'{func.__module__}.{func.__name__}')
|
|
44
|
+
return self
|
|
45
|
+
else:
|
|
46
|
+
return lambda *args, **kwargs: self(*args, **kwargs)
|
|
47
|
+
|
|
16
48
|
class Tracer:
|
|
17
49
|
|
|
18
50
|
def __init__(self, config, writer):
|
|
@@ -44,65 +76,66 @@ class Tracer:
|
|
|
44
76
|
|
|
45
77
|
def trace_calls(self, thread_state):
|
|
46
78
|
if 'tracecalls' in self.config:
|
|
47
|
-
def on_call(frame):
|
|
48
|
-
|
|
79
|
+
# def on_call(frame):
|
|
80
|
+
|
|
81
|
+
# func = frame.function
|
|
49
82
|
|
|
50
|
-
|
|
83
|
+
# key = (func.__module__, func.__name__)
|
|
51
84
|
|
|
52
|
-
|
|
53
|
-
|
|
85
|
+
# ignore = set([('abc', '__subclasscheck__'),
|
|
86
|
+
# ('threading', '_shutdown')])
|
|
54
87
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
88
|
+
# if key in ignore:
|
|
89
|
+
# print('About to throw!!!')
|
|
90
|
+
# raise Exception()
|
|
58
91
|
|
|
59
|
-
|
|
92
|
+
# objtype = None
|
|
60
93
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
94
|
+
# if 'self' in frame.locals:
|
|
95
|
+
# this = frame.locals['self']
|
|
96
|
+
# objtype = type(this)
|
|
64
97
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
98
|
+
# # if objtype:
|
|
99
|
+
# # print(f'Called!!!!: {func.__module__}.{objtype.__name__}.{func.__name__}')
|
|
100
|
+
# # else:
|
|
101
|
+
# # print(f'Called!!!!: {func.__module__}.{func.__name__}')
|
|
69
102
|
|
|
70
|
-
|
|
103
|
+
# qualname = (func.__module__, objtype, func.__name__)
|
|
71
104
|
|
|
72
|
-
|
|
105
|
+
# self.writer(f'{func.__module__}.{func.__name__}')
|
|
73
106
|
|
|
74
|
-
|
|
75
|
-
|
|
107
|
+
# # if func.__name__ == '_path_stat':
|
|
108
|
+
# # utils.sigtrap('_path_stat start')
|
|
76
109
|
|
|
77
|
-
|
|
110
|
+
# return qualname
|
|
78
111
|
|
|
79
|
-
def on_result(qualname, res):
|
|
80
|
-
|
|
112
|
+
# def on_result(qualname, res):
|
|
113
|
+
# mod, obj, func = qualname
|
|
81
114
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
115
|
+
# # if obj:
|
|
116
|
+
# # print(f'Returning!!!!: {mod}.{obj}.{func}')
|
|
117
|
+
# # else:
|
|
118
|
+
# # print(f'Returning!!!!: {mod}.{func}')
|
|
86
119
|
|
|
87
|
-
|
|
88
|
-
|
|
120
|
+
# # if func == '_path_stat':
|
|
121
|
+
# # utils.sigtrap('_path_stat res')
|
|
89
122
|
|
|
90
|
-
|
|
91
|
-
|
|
123
|
+
# if func != '__hash__':
|
|
124
|
+
# ignore = set(('typing', 'inner'))
|
|
92
125
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
def on_call_disabled(frame):
|
|
100
|
-
func = frame.function
|
|
101
|
-
print(f'disabled: {func.__module__}.{func.__name__}')
|
|
102
|
-
|
|
103
|
-
utils.intercept_frame_eval(on_call = thread_state.dispatch(utils.noop, internal = thread_state.wrap('disabled', on_call)),
|
|
104
|
-
on_result = thread_state.dispatch(utils.noop, internal = thread_state.wrap('disabled', on_result)))
|
|
126
|
+
# if qualname not in ignore:
|
|
127
|
+
# if type(res) in [str, int]:
|
|
128
|
+
# self.writer(res)
|
|
129
|
+
# else:
|
|
130
|
+
# self.writer(str(type(res)))
|
|
105
131
|
|
|
132
|
+
# def on_call_disabled(frame):
|
|
133
|
+
# func = frame.function
|
|
134
|
+
# print(f'disabled: {func.__module__}.{func.__name__}')
|
|
135
|
+
|
|
136
|
+
callback = CallTracer(writer = self.writer, thread_state = thread_state)
|
|
137
|
+
utils.intercept_frame_eval(callback)
|
|
138
|
+
|
|
106
139
|
def serialize(self, obj):
|
|
107
140
|
try:
|
|
108
141
|
if obj is None: return None
|
|
@@ -35,6 +35,25 @@ class WithoutFlags:
|
|
|
35
35
|
def __exit__(self, *args):
|
|
36
36
|
utils.set_type_flags(self.cls, self.saved)
|
|
37
37
|
|
|
38
|
+
class WithFlags:
|
|
39
|
+
|
|
40
|
+
def __init__(self, cls , *flags):
|
|
41
|
+
self.cls = cls
|
|
42
|
+
self.flags = flags
|
|
43
|
+
|
|
44
|
+
def __enter__(self):
|
|
45
|
+
self.saved = utils.type_flags(self.cls)
|
|
46
|
+
flags = self.saved
|
|
47
|
+
|
|
48
|
+
for flag in self.flags:
|
|
49
|
+
flags |= utils.TypeFlags[flag]
|
|
50
|
+
|
|
51
|
+
utils.set_type_flags(self.cls, flags)
|
|
52
|
+
return self.cls
|
|
53
|
+
|
|
54
|
+
def __exit__(self, *args):
|
|
55
|
+
utils.set_type_flags(self.cls, self.saved)
|
|
56
|
+
|
|
38
57
|
def add_flag(cls : type, flag):
|
|
39
58
|
if isinstance(flag, str):
|
|
40
59
|
flag = utils.TypeFlags[flag]
|
|
@@ -45,6 +64,7 @@ def add_flag(cls : type, flag):
|
|
|
45
64
|
def modify(cls):
|
|
46
65
|
return WithoutFlags(cls, "Py_TPFLAGS_IMMUTABLETYPE")
|
|
47
66
|
|
|
67
|
+
|
|
48
68
|
def type_has_feature(cls, flag):
|
|
49
69
|
if isinstance(flag, str):
|
|
50
70
|
flag = utils.TypeFlags[flag]
|
|
@@ -5,7 +5,7 @@ from retracesoftware.proxy.gateway import adapter_pair
|
|
|
5
5
|
from types import SimpleNamespace
|
|
6
6
|
from retracesoftware.proxy.proxytype import *
|
|
7
7
|
from retracesoftware.proxy.stubfactory import Stub
|
|
8
|
-
from retracesoftware.install.typeutils import modify
|
|
8
|
+
from retracesoftware.install.typeutils import modify, WithFlags
|
|
9
9
|
|
|
10
10
|
import sys
|
|
11
11
|
import gc
|
|
@@ -166,8 +166,16 @@ class ProxySystem:
|
|
|
166
166
|
|
|
167
167
|
def proxy_function(self, obj):
|
|
168
168
|
return utils.wrapped_function(handler = self.ext_handler, target = obj)
|
|
169
|
-
|
|
169
|
+
|
|
170
|
+
def proxy__new__(self, *args, **kwargs):
|
|
171
|
+
return self.ext_handler(*args, **kwargs)
|
|
172
|
+
|
|
170
173
|
def patchtype(self, cls):
|
|
174
|
+
if not utils.is_extendable(cls):
|
|
175
|
+
with WithFlags(cls, "Py_TPFLAGS_BASETYPE"):
|
|
176
|
+
assert utils.is_extendable(cls)
|
|
177
|
+
return self.patchtype(cls)
|
|
178
|
+
|
|
171
179
|
if cls in self.immutable_types or issubclass(cls, tuple):
|
|
172
180
|
return cls
|
|
173
181
|
|
|
@@ -184,45 +192,21 @@ class ProxySystem:
|
|
|
184
192
|
|
|
185
193
|
return self.thread_state.dispatch(func, internal = new)
|
|
186
194
|
|
|
187
|
-
#
|
|
188
|
-
# def update(name, f):
|
|
189
|
-
# setattr(cls, name, f(getattr(cls, name)))
|
|
195
|
+
# slots = {'__module__': cls.__module__, '__slots__': []}
|
|
190
196
|
|
|
191
|
-
|
|
192
|
-
# if callable(value) and not is_instance_method(value):
|
|
193
|
-
# update(name, wrap_new if name == '__new__' else wrap)
|
|
194
|
-
|
|
195
|
-
# return cls
|
|
196
|
-
if utils.is_extendable(cls):
|
|
197
|
-
slots = {'__module__': cls.__module__, '__slots__': []}
|
|
197
|
+
extended = utils.extend_type(cls)
|
|
198
198
|
|
|
199
|
-
|
|
199
|
+
for name, value in superdict(cls).items():
|
|
200
|
+
if callable(value) and not is_instance_method(value):
|
|
201
|
+
setattr(extended, name, wrap_new(value) if name == '__new__' else wrap(value))
|
|
200
202
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
setattr(extended, name, wrap_new(value) if name == '__new__' else wrap(value))
|
|
203
|
+
# slots[name] = wrap_new(value) if name == '__new__' else wrap(value)
|
|
204
|
+
extended.__module__ = cls.__module__
|
|
204
205
|
|
|
205
|
-
|
|
206
|
-
extended.__module__ = cls.__module__
|
|
206
|
+
return extended
|
|
207
207
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
elif not utils.is_immutable(cls):
|
|
212
|
-
def update(name, f):
|
|
213
|
-
setattr(cls, name, f(getattr(cls, name)))
|
|
214
|
-
|
|
215
|
-
for name, value in superdict(cls).items():
|
|
216
|
-
if callable(value) and not is_instance_method(value):
|
|
217
|
-
if name == '__new__':
|
|
218
|
-
handler = self.thread_state.dispatch(functional.apply, internal = self.ext_handler)
|
|
219
|
-
|
|
220
|
-
utils.intercept__new__(type = cls, handler = handler)
|
|
221
|
-
else:
|
|
222
|
-
update(name, wrap)
|
|
223
|
-
# update(name, wrap_new if name == '__new__' else wrap)
|
|
224
|
-
else:
|
|
225
|
-
return wrap(cls)
|
|
208
|
+
def is_entry_frame(self, frame):
|
|
209
|
+
return frame.globals.get("__name__", None) == "__main__"
|
|
226
210
|
|
|
227
211
|
def __call__(self, obj):
|
|
228
212
|
assert not isinstance(obj, BaseException)
|
retracesoftware/proxy/record.py
CHANGED
|
@@ -75,12 +75,20 @@ class RecordProxySystem(ProxySystem):
|
|
|
75
75
|
utils.set_thread_id(self.writer.handle(ThreadSwitch(id)))
|
|
76
76
|
# utils.set_thread_id(id)
|
|
77
77
|
|
|
78
|
+
def is_entry_frame(self, frame):
|
|
79
|
+
if super().is_entry_frame(frame):
|
|
80
|
+
self.write_main_path(frame.function.__code__.co_filename)
|
|
81
|
+
return True
|
|
82
|
+
return False
|
|
83
|
+
|
|
78
84
|
def __init__(self, thread_state,
|
|
79
85
|
immutable_types,
|
|
80
86
|
tracing_config,
|
|
87
|
+
write_main_path,
|
|
81
88
|
path):
|
|
82
89
|
|
|
83
90
|
self.fork_counter = 0
|
|
91
|
+
self.write_main_path = write_main_path
|
|
84
92
|
|
|
85
93
|
self.getpid = thread_state.wrap(
|
|
86
94
|
desired_state = 'disabled', function = os.getpid)
|
|
@@ -123,8 +131,10 @@ class RecordProxySystem(ProxySystem):
|
|
|
123
131
|
|
|
124
132
|
sync_handle = self.writer.handle('SYNC')
|
|
125
133
|
|
|
134
|
+
write_sync = thread_state.dispatch(utils.noop, internal = functional.lazy(sync_handle))
|
|
135
|
+
|
|
126
136
|
self.sync = lambda function: \
|
|
127
|
-
utils.observer(on_call =
|
|
137
|
+
utils.observer(on_call = write_sync, function = function)
|
|
128
138
|
|
|
129
139
|
error = self.writer.handle('ERROR')
|
|
130
140
|
|
retracesoftware/proxy/replay.py
CHANGED
|
@@ -154,12 +154,20 @@ class ReplayProxySystem(ProxySystem):
|
|
|
154
154
|
|
|
155
155
|
return super().proxy_function(func)
|
|
156
156
|
|
|
157
|
+
def proxy__new__(self, __new__, *args, **kwargs):
|
|
158
|
+
func = functional.repeatedly(self.next_result)
|
|
159
|
+
func.__name__ = '__new__'
|
|
160
|
+
return super().proxy__new__(func, *args, **kwargs)
|
|
161
|
+
|
|
157
162
|
def basetype(self, cls):
|
|
158
163
|
return self.stub_factory.create_stubtype(StubRef(cls))
|
|
159
164
|
|
|
160
165
|
def readnext(self):
|
|
161
166
|
with self.thread_state.select('disabled'):
|
|
162
167
|
try:
|
|
168
|
+
# obj = self.messages()
|
|
169
|
+
# print(f'read: {obj}')
|
|
170
|
+
# return obj
|
|
163
171
|
return self.messages()
|
|
164
172
|
except Exception as error:
|
|
165
173
|
# print(f'Error reading stream: {error}')
|
|
@@ -222,19 +230,26 @@ class ReplayProxySystem(ProxySystem):
|
|
|
222
230
|
print(f'on_thread_exit!!!!')
|
|
223
231
|
self.reader.wake_pending()
|
|
224
232
|
|
|
233
|
+
def is_entry_frame(self, frame):
|
|
234
|
+
if super().is_entry_frame(frame) and frame.function.__code__.co_filename == self.mainscript:
|
|
235
|
+
return True
|
|
236
|
+
return False
|
|
225
237
|
|
|
226
238
|
def __init__(self,
|
|
227
239
|
thread_state,
|
|
228
240
|
immutable_types,
|
|
229
241
|
tracing_config,
|
|
242
|
+
mainscript,
|
|
230
243
|
path,
|
|
231
244
|
fork_path = []):
|
|
232
245
|
|
|
233
246
|
# self.messages_read = 0
|
|
234
247
|
|
|
248
|
+
self.mainscript = mainscript
|
|
249
|
+
|
|
235
250
|
self.reader = stream.reader(path,
|
|
236
251
|
thread = thread_id,
|
|
237
|
-
timeout_seconds =
|
|
252
|
+
timeout_seconds = 60)
|
|
238
253
|
|
|
239
254
|
self.bindings = utils.id_dict()
|
|
240
255
|
# self.set_thread_id = utils.set_thread_id
|
|
@@ -271,7 +286,7 @@ class ReplayProxySystem(ProxySystem):
|
|
|
271
286
|
self.reader.type_deserializer[StubRef] = self.stub_factory
|
|
272
287
|
self.reader.type_deserializer[GlobalRef] = lambda ref: ref()
|
|
273
288
|
|
|
274
|
-
read_sync = functional.lazy(thread_state.wrap('disabled', self.read_required), 'SYNC')
|
|
289
|
+
read_sync = thread_state.dispatch(utils.noop, internal = functional.lazy(thread_state.wrap('disabled', self.read_required), 'SYNC'))
|
|
275
290
|
|
|
276
291
|
self.sync = lambda function: utils.observer(on_call = read_sync, function = function)
|
|
277
292
|
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
retracesoftware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
retracesoftware/config.json,sha256=
|
|
2
|
+
retracesoftware/config.json,sha256=iy5d3441PtihMT2QH-ikTYdzlf8zfIcSyvtpsJK5tUQ,9261
|
|
3
3
|
retracesoftware/config.yaml,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
retracesoftware/install/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
retracesoftware/install/config.py,sha256=EzE5ifQF2lo--hu2njI4T0FJ-zlnWDJV6i7x0DMkVTw,1364
|
|
6
6
|
retracesoftware/install/edgecases.py,sha256=NR3lyvad9sRsyeDv_Ya8V4xMgPsMPOi9rMcnFOJGOEA,6330
|
|
7
7
|
retracesoftware/install/globals.py,sha256=F8XvIoZQQ10gSRalk30dvdKllxlwxkaggYY6FogLDxY,510
|
|
8
8
|
retracesoftware/install/install.py,sha256=HCD_ji8XCr96b5fNzNdL_8qcEp0Jf05Em7T6GA6u8HU,4969
|
|
9
|
-
retracesoftware/install/patcher.py,sha256=
|
|
9
|
+
retracesoftware/install/patcher.py,sha256=XwpySyqaop3bnLc8ewtowxLchAC0mOtXWDfmk5zTE_s,22195
|
|
10
10
|
retracesoftware/install/predicate.py,sha256=tX7NQc0rGkyyHYO3mduYHcJHbw1wczT53m_Dpkzo6do,2679
|
|
11
|
-
retracesoftware/install/record.py,sha256=
|
|
11
|
+
retracesoftware/install/record.py,sha256=mjk4bien8uWp8c-vWNw3Y4BRR5xO4AWsZi1aodkW5yc,3590
|
|
12
12
|
retracesoftware/install/references.py,sha256=A-G651IDOfuo00MkbAdpbIQh_15ChvJ7uAVTSmE6zd4,1721
|
|
13
|
-
retracesoftware/install/replay.py,sha256=
|
|
14
|
-
retracesoftware/install/tracer.py,sha256=
|
|
15
|
-
retracesoftware/install/typeutils.py,sha256
|
|
13
|
+
retracesoftware/install/replay.py,sha256=36x40dk8pCmVjHz8zKd2OLY3B7UkP0NEb-1V1X8o3Rg,1992
|
|
14
|
+
retracesoftware/install/tracer.py,sha256=MiaTPlUwcRbgL4CTNhvC4Y5mUhkb--Y7_icTPhscSmY,9014
|
|
15
|
+
retracesoftware/install/typeutils.py,sha256=-oFzgUfq_nHeOkj3YKZiMLlMzQhCedg3qymLiEJNkVE,2253
|
|
16
16
|
retracesoftware/proxy/__init__.py,sha256=ntIyqKhBRkKEkcW_oOPodikh-mxYl8OXRnSaj-9-Xwc,178
|
|
17
17
|
retracesoftware/proxy/gateway.py,sha256=xESohWXkiNm4ZutU0RgWUwxjxcBWRQ4rQyxIGQXv_F4,1590
|
|
18
18
|
retracesoftware/proxy/globalref.py,sha256=yXtJsOeBHN9xoEgJWA3MJco-jD2SQUef_fDatA4A6rg,803
|
|
19
19
|
retracesoftware/proxy/proxyfactory.py,sha256=qhOqDfMJnLDNkQs26JqDB431MwjjRhGQi8xupJ45asg,12272
|
|
20
|
-
retracesoftware/proxy/proxysystem.py,sha256=
|
|
20
|
+
retracesoftware/proxy/proxysystem.py,sha256=zXrK4eMBJHZlmRJ2pQMltzYHF5CjnAZV6Z_teGH6DO8,8071
|
|
21
21
|
retracesoftware/proxy/proxytype.py,sha256=83y5rQRSts-5rLZu_k3tT90mwX2M-Ny6RZ91l-LTJ6k,13199
|
|
22
|
-
retracesoftware/proxy/record.py,sha256=
|
|
23
|
-
retracesoftware/proxy/replay.py,sha256=
|
|
22
|
+
retracesoftware/proxy/record.py,sha256=AsoVhuTX0pVVAqOih9-Mgh54psyggqfAXwAYYwy7umM,5818
|
|
23
|
+
retracesoftware/proxy/replay.py,sha256=mMb3jiCPS8W-Nev1JMaBIQSxRjV1sKTJYRPWAurw4i0,10264
|
|
24
24
|
retracesoftware/proxy/stubfactory.py,sha256=eHlbzWR1LoQVkIRX1HoLPPQSOpYhOO_5R_p3buD4o7s,5256
|
|
25
25
|
retracesoftware/proxy/thread.py,sha256=T1ME6DHB8O0xVnX3Rt1lMl7oCJ2Y0aoFT91D76yNICk,3073
|
|
26
|
-
retracesoftware_proxy-0.1.
|
|
27
|
-
retracesoftware_proxy-0.1.
|
|
28
|
-
retracesoftware_proxy-0.1.
|
|
29
|
-
retracesoftware_proxy-0.1.
|
|
26
|
+
retracesoftware_proxy-0.1.20.dist-info/METADATA,sha256=rTN6xgpmhR225Wnal7A_PNhHmi_Xj98A_Xej4IUscoc,203
|
|
27
|
+
retracesoftware_proxy-0.1.20.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
28
|
+
retracesoftware_proxy-0.1.20.dist-info/top_level.txt,sha256=hYHsR6txLidmqvjBMITpIHvmJJbmoCAgr76-IpZPRz8,16
|
|
29
|
+
retracesoftware_proxy-0.1.20.dist-info/RECORD,,
|
|
File without changes
|
{retracesoftware_proxy-0.1.18.dist-info → retracesoftware_proxy-0.1.20.dist-info}/top_level.txt
RENAMED
|
File without changes
|