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

Unified Diff: tools/heapcheck/heapcheck_test.py

Issue 113193008: Remove heapcheck support. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/heapcheck/heapcheck_std.sh ('k') | tools/heapcheck/ipc_tests.gtest-heapcheck.txt » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/heapcheck/heapcheck_test.py
diff --git a/tools/heapcheck/heapcheck_test.py b/tools/heapcheck/heapcheck_test.py
deleted file mode 100644
index 6987624146c981e235f70a94da5c6e7af0958e54..0000000000000000000000000000000000000000
--- a/tools/heapcheck/heapcheck_test.py
+++ /dev/null
@@ -1,250 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Wrapper for running the test under heapchecker and analyzing the output."""
-
-import datetime
-import logging
-import os
-import re
-
-import common
-import path_utils
-import suppressions
-
-
-class HeapcheckWrapper(object):
- TMP_FILE = 'heapcheck.log'
- SANITY_TEST_SUPPRESSION = "Heapcheck sanity test"
- LEAK_REPORT_RE = re.compile(
- 'Leak of ([0-9]*) bytes in ([0-9]*) objects allocated from:')
- # Workaround for http://crbug.com/132867, see below.
- HOOKED_ALLOCATOR_RE = re.compile(
- 'Hooked allocator frame not found, returning empty trace')
- STACK_LINE_RE = re.compile('\s*@\s*(?:0x)?[0-9a-fA-F]+\s*([^\n]*)')
- BORING_CALLERS = common.BoringCallers(mangled=False, use_re_wildcards=True)
-
- def __init__(self, supp_files):
- self._mode = 'strict'
- self._timeout = 3600
- self._nocleanup_on_exit = False
- self._suppressions = []
- for fname in supp_files:
- self._suppressions.extend(suppressions.ReadSuppressionsFromFile(fname))
- if os.path.exists(self.TMP_FILE):
- os.remove(self.TMP_FILE)
-
- def PutEnvAndLog(self, env_name, env_value):
- """Sets the env var |env_name| to |env_value| and writes to logging.info.
- """
- os.putenv(env_name, env_value)
- logging.info('export %s=%s', env_name, env_value)
-
- def Execute(self):
- """Executes the app to be tested."""
- logging.info('starting execution...')
- proc = ['sh', path_utils.ScriptDir() + '/heapcheck_std.sh']
- proc += self._args
- self.PutEnvAndLog('G_SLICE', 'always-malloc')
- self.PutEnvAndLog('NSS_DISABLE_ARENA_FREE_LIST', '1')
- self.PutEnvAndLog('NSS_DISABLE_UNLOAD', '1')
- self.PutEnvAndLog('GTEST_DEATH_TEST_USE_FORK', '1')
- self.PutEnvAndLog('HEAPCHECK', self._mode)
- self.PutEnvAndLog('HEAP_CHECK_ERROR_EXIT_CODE', '0')
- self.PutEnvAndLog('HEAP_CHECK_MAX_LEAKS', '-1')
- self.PutEnvAndLog('KEEP_SHADOW_STACKS', '1')
- self.PutEnvAndLog('PPROF_PATH',
- path_utils.ScriptDir() +
- '/../../third_party/tcmalloc/chromium/src/pprof')
- self.PutEnvAndLog('LD_LIBRARY_PATH',
- '/usr/lib/debug/:/usr/lib32/debug/')
- # CHROME_DEVEL_SANDBOX causes problems with heapcheck
- self.PutEnvAndLog('CHROME_DEVEL_SANDBOX', '');
-
- return common.RunSubprocess(proc, self._timeout)
-
- def Analyze(self, log_lines, check_sanity=False):
- """Analyzes the app's output and applies suppressions to the reports.
-
- Analyze() searches the logs for leak reports and tries to apply
- suppressions to them. Unsuppressed reports and other log messages are
- dumped as is.
-
- If |check_sanity| is True, the list of suppressed reports is searched for a
- report starting with SANITY_TEST_SUPPRESSION. If there isn't one, Analyze
- returns 2 regardless of the unsuppressed reports.
-
- Args:
- log_lines: An iterator over the app's log lines.
- check_sanity: A flag that determines whether we should check the tool's
- sanity.
- Returns:
- 2, if the sanity check fails,
- 1, if unsuppressed reports remain in the output and the sanity check
- passes,
- 0, if all the errors are suppressed and the sanity check passes.
- """
- return_code = 0
- # leak signature: [number of bytes, number of objects]
- cur_leak_signature = None
- cur_stack = []
- cur_report = []
- reported_hashes = {}
- # Statistics grouped by suppression description:
- # [hit count, bytes, objects].
- used_suppressions = {}
- hooked_allocator_line_encountered = False
- for line in log_lines:
- line = line.rstrip() # remove the trailing \n
- match = self.STACK_LINE_RE.match(line)
- if match:
- cur_stack.append(match.groups()[0])
- cur_report.append(line)
- continue
- else:
- if cur_stack:
- # Try to find the suppression that applies to the current leak stack.
- description = ''
- for supp in self._suppressions:
- if supp.Match(cur_stack):
- cur_stack = []
- description = supp.description
- break
- if cur_stack:
- if not cur_leak_signature:
- print 'Missing leak signature for the following stack: '
- for frame in cur_stack:
- print ' ' + frame
- print 'Aborting...'
- return 3
-
- # Drop boring callers from the stack to get less redundant info
- # and fewer unique reports.
- found_boring = False
- for i in range(1, len(cur_stack)):
- for j in self.BORING_CALLERS:
- if re.match(j, cur_stack[i]):
- cur_stack = cur_stack[:i]
- cur_report = cur_report[:i]
- found_boring = True
- break
- if found_boring:
- break
-
- error_hash = hash("".join(cur_stack)) & 0xffffffffffffffff
- if error_hash not in reported_hashes:
- reported_hashes[error_hash] = 1
- # Print the report and set the return code to 1.
- print ('Leak of %d bytes in %d objects allocated from:'
- % tuple(cur_leak_signature))
- print '\n'.join(cur_report)
- return_code = 1
- # Generate the suppression iff the stack contains more than one
- # frame (otherwise it's likely to be broken)
- if len(cur_stack) > 1 or found_boring:
- print '\nSuppression (error hash=#%016X#):\n{' % (error_hash)
- print ' <insert_a_suppression_name_here>'
- print ' Heapcheck:Leak'
- for frame in cur_stack:
- print ' fun:' + frame
- print '}\n\n'
- else:
- print ('This stack may be broken due to omitted frame pointers.'
- ' It is not recommended to suppress it.\n')
- else:
- # Update the suppressions histogram.
- if description in used_suppressions:
- hits, bytes, objects = used_suppressions[description]
- hits += 1
- bytes += cur_leak_signature[0]
- objects += cur_leak_signature[1]
- used_suppressions[description] = [hits, bytes, objects]
- else:
- used_suppressions[description] = [1] + cur_leak_signature
- cur_stack = []
- cur_report = []
- cur_leak_signature = None
- match = self.LEAK_REPORT_RE.match(line)
- if match:
- cur_leak_signature = map(int, match.groups())
- else:
- match = self.HOOKED_ALLOCATOR_RE.match(line)
- if match:
- hooked_allocator_line_encountered = True
- else:
- print line
- # Print the list of suppressions used.
- is_sane = False
- if used_suppressions:
- print
- print '-----------------------------------------------------'
- print 'Suppressions used:'
- print ' count bytes objects name'
- histo = {}
- for description in used_suppressions:
- if description.startswith(HeapcheckWrapper.SANITY_TEST_SUPPRESSION):
- is_sane = True
- hits, bytes, objects = used_suppressions[description]
- line = '%8d %8d %8d %s' % (hits, bytes, objects, description)
- if hits in histo:
- histo[hits].append(line)
- else:
- histo[hits] = [line]
- keys = histo.keys()
- keys.sort()
- for count in keys:
- for line in histo[count]:
- print line
- print '-----------------------------------------------------'
- if hooked_allocator_line_encountered:
- print ('WARNING: Workaround for http://crbug.com/132867 (tons of '
- '"Hooked allocator frame not found, returning empty trace") '
- 'in effect.')
- if check_sanity and not is_sane:
- logging.error("Sanity check failed")
- return 2
- else:
- return return_code
-
- def RunTestsAndAnalyze(self, check_sanity):
- exec_retcode = self.Execute()
- log_file = file(self.TMP_FILE, 'r')
- analyze_retcode = self.Analyze(log_file, check_sanity)
- log_file.close()
-
- if analyze_retcode:
- logging.error("Analyze failed.")
- return analyze_retcode
-
- if exec_retcode:
- logging.error("Test execution failed.")
- return exec_retcode
- else:
- logging.info("Test execution completed successfully.")
-
- return 0
-
- def Main(self, args, check_sanity=False):
- self._args = args
- start = datetime.datetime.now()
- retcode = -1
- retcode = self.RunTestsAndAnalyze(check_sanity)
- end = datetime.datetime.now()
- seconds = (end - start).seconds
- hours = seconds / 3600
- seconds %= 3600
- minutes = seconds / 60
- seconds %= 60
- logging.info('elapsed time: %02d:%02d:%02d', hours, minutes, seconds)
- logging.info('For more information on the Heapcheck bot see '
- 'http://dev.chromium.org/developers/how-tos/'
- 'using-the-heap-leak-checker')
- return retcode
-
-
-def RunTool(args, supp_files, module):
- tool = HeapcheckWrapper(supp_files)
- MODULES_TO_SANITY_CHECK = ["base"]
- check_sanity = module in MODULES_TO_SANITY_CHECK
- return tool.Main(args[1:], check_sanity)
« no previous file with comments | « tools/heapcheck/heapcheck_std.sh ('k') | tools/heapcheck/ipc_tests.gtest-heapcheck.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698