Skip to content

Commit 352bc4e

Browse files
committed
start refactoring
1 parent ea5409f commit 352bc4e

File tree

3 files changed

+1953
-0
lines changed

3 files changed

+1953
-0
lines changed

‎.gitignore

+8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
.\#*
2+
\#*
3+
14
*.pyc
25
*.egg
36
*.egg-info/
47
.eggs/
8+
.DS_Store
59
dist/
610
build/
711
docs/build/
@@ -13,6 +17,10 @@ venv/
1317
coverage.xml
1418

1519
Dockerfile
20+
.idea
21+
.mailmap
22+
.env
23+
.dockerignore
1624

1725
*~
1826
*.swp

‎testgres/gdb.py

+240
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
2+
3+
class GdbException(Exception):
4+
def __init__(self, message="False"):
5+
self.message = message
6+
7+
def __str__(self):
8+
return '\n ERROR: {0}\n'.format(repr(self.message))
9+
10+
11+
class GDBobj:
12+
def __init__(self, cmd, env, attach=False):
13+
self.verbose = env.verbose
14+
self.output = ''
15+
16+
# Check gdb flag is set up
17+
if not env.gdb:
18+
raise GdbException("No `PGPROBACKUP_GDB=on` is set, "
19+
"test should call ProbackupTest::check_gdb_flag_or_skip_test() on its start "
20+
"and be skipped")
21+
# Check gdb presense
22+
try:
23+
gdb_version, _ = subprocess.Popen(
24+
['gdb', '--version'],
25+
stdout=subprocess.PIPE
26+
).communicate()
27+
except OSError:
28+
raise GdbException("Couldn't find gdb on the path")
29+
30+
self.base_cmd = [
31+
'gdb',
32+
'--interpreter',
33+
'mi2',
34+
]
35+
36+
if attach:
37+
self.cmd = self.base_cmd + ['--pid'] + cmd
38+
else:
39+
self.cmd = self.base_cmd + ['--args'] + cmd
40+
41+
# Get version
42+
gdb_version_number = re.search(
43+
b"^GNU gdb [^\d]*(\d+)\.(\d)",
44+
gdb_version)
45+
self.major_version = int(gdb_version_number.group(1))
46+
self.minor_version = int(gdb_version_number.group(2))
47+
48+
if self.verbose:
49+
print([' '.join(map(str, self.cmd))])
50+
51+
self.proc = subprocess.Popen(
52+
self.cmd,
53+
stdin=subprocess.PIPE,
54+
stdout=subprocess.PIPE,
55+
stderr=subprocess.STDOUT,
56+
bufsize=0,
57+
universal_newlines=True
58+
)
59+
self.gdb_pid = self.proc.pid
60+
61+
while True:
62+
line = self.get_line()
63+
64+
if 'No such process' in line:
65+
raise GdbException(line)
66+
67+
if not line.startswith('(gdb)'):
68+
pass
69+
else:
70+
break
71+
72+
def get_line(self):
73+
line = self.proc.stdout.readline()
74+
self.output += line
75+
return line
76+
77+
def kill(self):
78+
self.proc.kill()
79+
self.proc.wait()
80+
81+
def set_breakpoint(self, location):
82+
83+
result = self._execute('break ' + location)
84+
for line in result:
85+
if line.startswith('~"Breakpoint'):
86+
return
87+
88+
elif line.startswith('=breakpoint-created'):
89+
return
90+
91+
elif line.startswith('^error'): #or line.startswith('(gdb)'):
92+
break
93+
94+
elif line.startswith('&"break'):
95+
pass
96+
97+
elif line.startswith('&"Function'):
98+
raise GdbException(line)
99+
100+
elif line.startswith('&"No line'):
101+
raise GdbException(line)
102+
103+
elif line.startswith('~"Make breakpoint pending on future shared'):
104+
raise GdbException(line)
105+
106+
raise GdbException(
107+
'Failed to set breakpoint.\n Output:\n {0}'.format(result)
108+
)
109+
110+
def remove_all_breakpoints(self):
111+
112+
result = self._execute('delete')
113+
for line in result:
114+
115+
if line.startswith('^done'):
116+
return
117+
118+
raise GdbException(
119+
'Failed to remove breakpoints.\n Output:\n {0}'.format(result)
120+
)
121+
122+
def run_until_break(self):
123+
result = self._execute('run', False)
124+
for line in result:
125+
if line.startswith('*stopped,reason="breakpoint-hit"'):
126+
return
127+
raise GdbException(
128+
'Failed to run until breakpoint.\n'
129+
)
130+
131+
def continue_execution_until_running(self):
132+
result = self._execute('continue')
133+
134+
for line in result:
135+
if line.startswith('*running') or line.startswith('^running'):
136+
return
137+
if line.startswith('*stopped,reason="breakpoint-hit"'):
138+
continue
139+
if line.startswith('*stopped,reason="exited-normally"'):
140+
continue
141+
142+
raise GdbException(
143+
'Failed to continue execution until running.\n'
144+
)
145+
146+
def continue_execution_until_exit(self):
147+
result = self._execute('continue', False)
148+
149+
for line in result:
150+
if line.startswith('*running'):
151+
continue
152+
if line.startswith('*stopped,reason="breakpoint-hit"'):
153+
continue
154+
if (
155+
line.startswith('*stopped,reason="exited') or
156+
line == '*stopped\n'
157+
):
158+
return
159+
160+
raise GdbException(
161+
'Failed to continue execution until exit.\n'
162+
)
163+
164+
def continue_execution_until_error(self):
165+
result = self._execute('continue', False)
166+
167+
for line in result:
168+
if line.startswith('^error'):
169+
return
170+
if line.startswith('*stopped,reason="exited'):
171+
return
172+
if line.startswith(
173+
'*stopped,reason="signal-received",signal-name="SIGABRT"'):
174+
return
175+
176+
raise GdbException(
177+
'Failed to continue execution until error.\n')
178+
179+
def continue_execution_until_break(self, ignore_count=0):
180+
if ignore_count > 0:
181+
result = self._execute(
182+
'continue ' + str(ignore_count),
183+
False
184+
)
185+
else:
186+
result = self._execute('continue', False)
187+
188+
for line in result:
189+
if line.startswith('*stopped,reason="breakpoint-hit"'):
190+
return
191+
if line.startswith('*stopped,reason="exited-normally"'):
192+
break
193+
194+
raise GdbException(
195+
'Failed to continue execution until break.\n')
196+
197+
def stopped_in_breakpoint(self):
198+
while True:
199+
line = self.get_line()
200+
if self.verbose:
201+
print(line)
202+
if line.startswith('*stopped,reason="breakpoint-hit"'):
203+
return True
204+
return False
205+
206+
def quit(self):
207+
self.proc.terminate()
208+
209+
# use for breakpoint, run, continue
210+
def _execute(self, cmd, running=True):
211+
output = []
212+
self.proc.stdin.flush()
213+
self.proc.stdin.write(cmd + '\n')
214+
self.proc.stdin.flush()
215+
sleep(1)
216+
217+
# look for command we just send
218+
while True:
219+
line = self.get_line()
220+
if self.verbose:
221+
print(repr(line))
222+
223+
if cmd not in line:
224+
continue
225+
else:
226+
break
227+
228+
while True:
229+
line = self.get_line()
230+
output += [line]
231+
if self.verbose:
232+
print(repr(line))
233+
if line.startswith('^done') or line.startswith('*stopped'):
234+
break
235+
if line.startswith('^error'):
236+
break
237+
if running and (line.startswith('*running') or line.startswith('^running')):
238+
# if running and line.startswith('*running'):
239+
break
240+
return output

0 commit comments

Comments
 (0)