author | Nicholas Nethercote <nnethercote@mozilla.com> |
Sun, 28 Sep 2014 18:36:49 -0700 | |
changeset 233440 | 2b73787681bddb7b30b4b6c4c484278f10f582ab |
parent 233439 | d73853c26a1a571c1970295d71f38d075d9458ec |
child 233441 | 51509077b97ccd5b193f0d0504d64d10e22b9702 |
push id | 611 |
push user | raliiev@mozilla.com |
push date | Mon, 05 Jan 2015 23:23:16 +0000 |
treeherder | mozilla-release@345cd3b9c445 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | glandium |
bugs | 1074008 |
milestone | 35.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/build/Makefile.in +++ b/build/Makefile.in @@ -93,25 +93,32 @@ GARBAGE_DIRS += $(_VALGRIND_DIR) $(topsrcdir)/build/valgrind/i386-redhat-linux-gnu.sup \ $(topsrcdir)/build/valgrind/x86_64-redhat-linux-gnu.sup \ $(NULL) libs:: $(_VALGRIND_FILES) $(INSTALL) $^ $(_VALGRIND_DIR) endif -ifdef ENABLE_TESTS +ifneq (,$(ENABLE_TESTS)$(MOZ_DMD)) libs:: $(topsrcdir)/tools/rb/fix_stack_using_bpsyms.py $(INSTALL) $< $(DIST)/bin ifeq ($(OS_ARCH),Darwin) libs:: $(topsrcdir)/tools/rb/fix_macosx_stack.py $(INSTALL) $< $(DIST)/bin endif ifeq ($(OS_ARCH),Linux) libs:: $(topsrcdir)/tools/rb/fix_linux_stack.py $(INSTALL) $< $(DIST)/bin endif +endif # ENABLE_TESTS or MOZ_DMD +ifdef ENABLE_TESTS GARBAGE += $(srcdir)/automationutils.pyc +endif # ENABLE_TESTS -endif # ENABLE_TESTS +ifdef MOZ_DMD +libs:: $(topsrcdir)/memory/replace/dmd/dmd.py + $(INSTALL) $< $(DIST)/bin +endif +
--- a/memory/replace/dmd/check_test_output.py +++ b/memory/replace/dmd/check_test_output.py @@ -50,17 +50,17 @@ def test(src_dir, kind, options, i): sys.exit(1) subprocess.call(fix, stdin=open(in_name, "r"), stdout=open(fixed_name, "w")) # Convert from JSON convert = [os.path.join(src_dir, "memory", "replace", "dmd", "dmd.py")] + \ - options + [fixed_name] + options + ['--no-fix-stacks', fixed_name] subprocess.call(convert, stdout=open(converted_name, "w")) # Filter output # In heap block records we filter out most stack frames. The only thing # we leave behind is a "DMD.cpp" entry if we see one or more frames that # have DMD.cpp in them. There is simply too much variation to do anything # better than that.
--- a/memory/replace/dmd/dmd.py +++ b/memory/replace/dmd/dmd.py @@ -6,18 +6,22 @@ '''This script analyzes a JSON file emitted by DMD.''' from __future__ import print_function, division import argparse import collections import json +import os +import platform import re +import shutil import sys +import tempfile # The DMD output version this script handles. outputVersion = 1 # If --ignore-alloc-fns is specified, stack frames containing functions that # match these strings will be removed. allocatorFns = [ 'replace_malloc', @@ -91,16 +95,19 @@ def parseCommandLine(): msg = '{:s} is not in the range 1..24'.format(string) raise argparse.ArgumentTypeError(msg) return value description = ''' Analyze heap data produced by DMD. If no files are specified, read from stdin. Write to stdout unless -o/--output is specified. +Stack traces are fixed to show function names, filenames and line numbers +unless --no-fix-stacks is specified; stack fixing modifies the original file +and may take some time. ''' p = argparse.ArgumentParser(description=description) p.add_argument('-o', '--output', type=argparse.FileType('w'), help='output file; stdout if unspecified') p.add_argument('-f', '--max-frames', type=range_1_24, help='maximum number of frames to consider in each trace') @@ -114,24 +121,61 @@ Write to stdout unless -o/--output is sp help='sort the records by a particular metric') p.add_argument('-a', '--ignore-alloc-fns', action='store_true', help='ignore allocation functions at the start of traces') p.add_argument('-b', '--show-all-block-sizes', action='store_true', help='show individual block sizes for each record') + p.add_argument('--no-fix-stacks', action='store_true', + help='do not fix stacks') + p.add_argument('input_file', type=argparse.FileType('r')) return p.parse_args(sys.argv[1:]) +# Fix stacks if necessary: first write the output to a tempfile, then replace +# the original file with it. +def fixStackTraces(args): + # This append() call is needed to make the import statements work when this + # script is installed as a symlink. + sys.path.append(os.path.dirname(__file__)) + + # XXX: should incorporate fix_stack_using_bpsyms.py here as well, like in + # testing/mochitests/runtests.py + sysname = platform.system() + if sysname == 'Linux': + import fix_linux_stack as fixModule + fix = lambda line: fixModule.fixSymbols(line) + elif sysname == 'Darwin': + import fix_macosx_stack as fixModule + fix = lambda line: fixModule.fixSymbols(line) + else: + fix = None # there is no fix script for Windows + + if fix: + # Fix stacks, writing output to a temporary file, and then + # overwrite the original file. + with tempfile.NamedTemporaryFile(delete=False) as tmp: + for line in args.input_file: + tmp.write(fix(line)) + shutil.move(tmp.name, args.input_file.name) + + args.input_file = open(args.input_file.name) + + def main(): args = parseCommandLine() + # Fix stack traces unless otherwise instructed. + if not args.no_fix_stacks: + fixStackTraces(args) + j = json.load(args.input_file) if j['version'] != outputVersion: raise Exception("'version' property isn't '{:d}'".format(outputVersion)) # Extract the main parts of the JSON object. invocation = j['invocation'] dmdEnvVar = invocation['dmdEnvVar']