Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Side by Side Diff: tools_webrtc/valgrind/common.py

Issue 2945753002: Roll chromium_revision b032878ebd..e438353b8b (480186:480311) (Closed)
Patch Set: Updated .gni Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools_webrtc/valgrind/chrome_tests.sh ('k') | tools_webrtc/valgrind/gdb_helper.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
2 #
3 # Use of this source code is governed by a BSD-style license
4 # that can be found in the LICENSE file in the root of the source
5 # tree. An additional intellectual property rights grant can be found
6 # in the file PATENTS. All contributing project authors may
7 # be found in the AUTHORS file in the root of the source tree.
8
9 import logging
10 import platform
11 import os
12 import signal
13 import subprocess
14 import sys
15 import time
16
17
18 class NotImplementedError(Exception):
19 pass
20
21
22 class TimeoutError(Exception):
23 pass
24
25
26 def RunSubprocessInBackground(proc):
27 """Runs a subprocess in the background. Returns a handle to the process."""
28 logging.info("running %s in the background" % " ".join(proc))
29 return subprocess.Popen(proc)
30
31
32 def RunSubprocess(proc, timeout=0):
33 """ Runs a subprocess, until it finishes or |timeout| is exceeded and the
34 process is killed with taskkill. A |timeout| <= 0 means no timeout.
35
36 Args:
37 proc: list of process components (exe + args)
38 timeout: how long to wait before killing, <= 0 means wait forever
39 """
40
41 logging.info("running %s, timeout %d sec" % (" ".join(proc), timeout))
42 sys.stdout.flush()
43 sys.stderr.flush()
44
45 # Manually read and print out stdout and stderr.
46 # By default, the subprocess is supposed to inherit these from its parent,
47 # however when run under buildbot, it seems unable to read data from a
48 # grandchild process, so we have to read the child and print the data as if
49 # it came from us for buildbot to read it. We're not sure why this is
50 # necessary.
51 # TODO(erikkay): should we buffer stderr and stdout separately?
52 p = subprocess.Popen(proc, universal_newlines=True,
53 bufsize=0, # unbuffered
54 stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
55
56 logging.info("started subprocess")
57
58 did_timeout = False
59 if timeout > 0:
60 wait_until = time.time() + timeout
61 while p.poll() is None and not did_timeout:
62 # Have to use readline rather than readlines() or "for line in p.stdout:",
63 # otherwise we get buffered even with bufsize=0.
64 line = p.stdout.readline()
65 while line and not did_timeout:
66 sys.stdout.write(line)
67 sys.stdout.flush()
68 line = p.stdout.readline()
69 if timeout > 0:
70 did_timeout = time.time() > wait_until
71
72 if did_timeout:
73 logging.info("process timed out")
74 else:
75 logging.info("process ended, did not time out")
76
77 if did_timeout:
78 if IsWindows():
79 subprocess.call(["taskkill", "/T", "/F", "/PID", str(p.pid)])
80 else:
81 # Does this kill all children, too?
82 os.kill(p.pid, signal.SIGINT)
83 logging.error("KILLED %d" % p.pid)
84 # Give the process a chance to actually die before continuing
85 # so that cleanup can happen safely.
86 time.sleep(1.0)
87 logging.error("TIMEOUT waiting for %s" % proc[0])
88 raise TimeoutError(proc[0])
89 else:
90 for line in p.stdout:
91 sys.stdout.write(line)
92 if not IsMac(): # stdout flush fails on Mac
93 logging.info("flushing stdout")
94 sys.stdout.flush()
95
96 logging.info("collecting result code")
97 result = p.poll()
98 if result:
99 logging.error("%s exited with non-zero result code %d" % (proc[0], result))
100 return result
101
102
103 def IsLinux():
104 return sys.platform.startswith('linux')
105
106
107 def IsMac():
108 return sys.platform.startswith('darwin')
109
110
111 def IsWindows():
112 return sys.platform == 'cygwin' or sys.platform.startswith('win')
113
114
115 def WindowsVersionName():
116 """Returns the name of the Windows version if it is known, or None.
117
118 Possible return values are: xp, vista, 7, 8, or None
119 """
120 if sys.platform == 'cygwin':
121 # Windows version number is hiding in system name. Looks like:
122 # CYGWIN_NT-6.1-WOW64
123 try:
124 version_str = platform.uname()[0].split('-')[1]
125 except:
126 return None
127 elif sys.platform.startswith('win'):
128 # Normal Windows version string. Mine: 6.1.7601
129 version_str = platform.version()
130 else:
131 return None
132
133 parts = version_str.split('.')
134 try:
135 major = int(parts[0])
136 minor = int(parts[1])
137 except:
138 return None # Can't parse, unknown version.
139
140 if major == 5:
141 return 'xp'
142 elif major == 6 and minor == 0:
143 return 'vista'
144 elif major == 6 and minor == 1:
145 return '7'
146 elif major == 6 and minor == 2:
147 return '8' # Future proof. ;)
148 return None
149
150
151 def PlatformNames():
152 """Return an array of string to be used in paths for the platform
153 (e.g. suppressions, gtest filters, ignore files etc.)
154 The first element of the array describes the 'main' platform
155 """
156 if IsLinux():
157 return ['linux']
158 if IsMac():
159 return ['mac']
160 if IsWindows():
161 names = ['win32']
162 version_name = WindowsVersionName()
163 if version_name is not None:
164 names.append('win-%s' % version_name)
165 return names
166 raise NotImplementedError('Unknown platform "%s".' % sys.platform)
167
168
169 def PutEnvAndLog(env_name, env_value):
170 os.putenv(env_name, env_value)
171 logging.info('export %s=%s', env_name, env_value)
172
173 def BoringCallers(mangled, use_re_wildcards):
174 """Return a list of 'boring' function names (optinally mangled)
175 with */? wildcards (optionally .*/.).
176 Boring = we drop off the bottom of stack traces below such functions.
177 """
178
179 need_mangling = [
180 # Don't show our testing framework:
181 ("testing::Test::Run", "_ZN7testing4Test3RunEv"),
182 ("testing::TestInfo::Run", "_ZN7testing8TestInfo3RunEv"),
183 ("testing::internal::Handle*ExceptionsInMethodIfSupported*",
184 "_ZN7testing8internal3?Handle*ExceptionsInMethodIfSupported*"),
185
186 # Depend on scheduling:
187 ("MessageLoop::Run", "_ZN11MessageLoop3RunEv"),
188 ("MessageLoop::RunTask", "_ZN11MessageLoop7RunTask*"),
189 ("RunnableMethod*", "_ZN14RunnableMethod*"),
190 ("DispatchToMethod*", "_Z*16DispatchToMethod*"),
191 ("base::internal::Invoker*::DoInvoke*",
192 "_ZN4base8internal8Invoker*DoInvoke*"), # Invoker{1,2,3}
193 ("base::internal::RunnableAdapter*::Run*",
194 "_ZN4base8internal15RunnableAdapter*Run*"),
195 ]
196
197 ret = []
198 for pair in need_mangling:
199 ret.append(pair[1 if mangled else 0])
200
201 ret += [
202 # Also don't show the internals of libc/pthread.
203 "start_thread",
204 "main",
205 "BaseThreadInitThunk",
206 ]
207
208 if use_re_wildcards:
209 for i in range(0, len(ret)):
210 ret[i] = ret[i].replace('*', '.*').replace('?', '.')
211
212 return ret
213
214 def NormalizeWindowsPath(path):
215 """If we're using Cygwin Python, turn the path into a Windows path.
216
217 Don't turn forward slashes into backslashes for easier copy-pasting and
218 escaping.
219
220 TODO(rnk): If we ever want to cut out the subprocess invocation, we can use
221 _winreg to get the root Cygwin directory from the registry key:
222 HKEY_LOCAL_MACHINE\SOFTWARE\Cygwin\setup\rootdir.
223 """
224 if sys.platform.startswith("cygwin"):
225 p = subprocess.Popen(["cygpath", "-m", path],
226 stdout=subprocess.PIPE,
227 stderr=subprocess.PIPE)
228 (out, err) = p.communicate()
229 if err:
230 logging.warning("WARNING: cygpath error: %s", err)
231 return out.strip()
232 else:
233 return path
234
235 ############################
236 # Common output format code
237
238 def PrintUsedSuppressionsList(suppcounts):
239 """ Prints out the list of used suppressions in a format common to all the
240 memory tools. If the list is empty, prints nothing and returns False,
241 otherwise True.
242
243 suppcounts: a dictionary of used suppression counts,
244 Key -> name, Value -> count.
245 """
246 if not suppcounts:
247 return False
248
249 print "-----------------------------------------------------"
250 print "Suppressions used:"
251 print " count name"
252 for (name, count) in sorted(suppcounts.items(), key=lambda (k,v): (v,k)):
253 print "%7d %s" % (count, name)
254 print "-----------------------------------------------------"
255 sys.stdout.flush()
256 return True
OLDNEW
« no previous file with comments | « tools_webrtc/valgrind/chrome_tests.sh ('k') | tools_webrtc/valgrind/gdb_helper.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698