Bug 1074656 - Merge |mach debug| and |mach dmd| into |mach run|. r=gps.

--HG--
extra : rebase_source : a9da86cadae7fdbb0fe9e3931fb1163f4239527c
This commit is contained in:
Nicholas Nethercote 2014-10-08 15:12:02 -07:00
parent fb69fa73f3
commit c72cb48004

View File

@ -14,6 +14,7 @@ import mozpack.path as mozpath
from mach.decorators import (
CommandArgument,
CommandArgumentGroup,
CommandProvider,
Command,
)
@ -780,112 +781,54 @@ class Install(MachCommandBase):
def install(self):
return self._run_make(directory=".", target='install', ensure_exit_code=False)
def get_run_args(mach_command, params, remote, background, noprofile):
"""
Parses the given options to create an args array for running firefox.
Creates a scratch profile and uses that if one is not specified.
"""
try:
args = [mach_command.get_binary_path('app')]
except Exception as e:
print("It looks like your program isn't built.",
"You can run |mach build| to build it.")
print(e)
return None
if not remote:
args.append('-no-remote')
if not background and sys.platform == 'darwin':
args.append('-foreground')
if '-profile' not in params and '-P' not in params and not noprofile:
path = os.path.join(mach_command.topobjdir, 'tmp', 'scratch_user')
if not os.path.isdir(path):
os.makedirs(path)
args.append('-profile')
args.append(path)
if params:
args.extend(params)
return args
@CommandProvider
class RunProgram(MachCommandBase):
"""Launch the compiled binary"""
"""Run the compiled program."""
prog_group = 'the compiled program'
@Command('run', category='post-build',
description='Run the compiled program.')
@CommandArgument('params', nargs='...',
description='Run the compiled program, possibly under a debugger or DMD.')
@CommandArgument('params', nargs='...', group=prog_group,
help='Command-line arguments to be passed through to the program. Not specifying a -profile or -P option will result in a temporary profile being used.')
@CommandArgument('-remote', '-r', action='store_true',
@CommandArgumentGroup(prog_group)
@CommandArgument('-remote', '-r', action='store_true', group=prog_group,
help='Do not pass the -no-remote argument by default.')
@CommandArgument('-background', '-b', action='store_true',
help='Do not pass the -foreground argument by default on Mac')
@CommandArgument('-noprofile', '-n', action='store_true',
@CommandArgument('-background', '-b', action='store_true', group=prog_group,
help='Do not pass the -foreground argument by default on Mac.')
@CommandArgument('-noprofile', '-n', action='store_true', group=prog_group,
help='Do not pass the -profile argument by default.')
def run(self, params, remote, background, noprofile):
args = get_run_args(self, params, remote, background, noprofile)
if not args:
return 1
return self.run_process(args=args, ensure_exit_code=False,
pass_thru=True)
@CommandProvider
class DebugProgram(MachCommandBase):
"""Debug the compiled binary"""
@Command('debug', category='post-build',
description='Debug the compiled program.')
@CommandArgument('params', nargs='...',
help='Command-line arguments to be passed through to the program. Not specifying a -profile or -P option will result in a temporary profile being used.')
@CommandArgument('-remote', '-r', action='store_true',
help='Do not pass the -no-remote argument by default')
@CommandArgument('-background', '-b', action='store_true',
help='Do not pass the -foreground argument by default on Mac')
@CommandArgument('-debugger', default=None, type=str,
help='Name of debugger to launch')
@CommandArgument('-debugparams', default=None, metavar='params', type=str,
@CommandArgumentGroup('debugging')
@CommandArgument('--debug', action='store_true', group='debugging',
help='Enable the debugger. Not specifying a --debugger option will result in the default debugger being used. The following arguments have no effect without this.')
@CommandArgument('--debugger', default=None, type=str, group='debugging',
help='Name of debugger to use.')
@CommandArgument('--debugparams', default=None, metavar='params', type=str,
group='debugging',
help='Command-line arguments to pass to the debugger itself; split as the Bourne shell would.')
# Bug 933807 introduced JS_DISABLE_SLOW_SCRIPT_SIGNALS to avoid clever
# segfaults induced by the slow-script-detecting logic for Ion/Odin JITted
# code. If we don't pass this, the user will need to periodically type
# "continue" to (safely) resume execution. There are ways to implement
# automatic resuming; see the bug.
@CommandArgument('-slowscript', action='store_true',
help='Do not set the JS_DISABLE_SLOW_SCRIPT_SIGNALS env variable; when not set, recoverable but misleading SIGSEGV instances may occur in Ion/Odin JIT code')
@CommandArgument('-noprofile', '-n', action='store_true',
help='Do not pass the -profile argument by default.')
def debug(self, params, remote, background, debugger, debugparams, slowscript, noprofile):
# Parameters come from the CLI. We need to convert them before their use.
if debugparams:
import pymake.process
argv, badchar = pymake.process.clinetoargv(debugparams, os.getcwd())
if badchar:
print("The -debugparams you passed require a real shell to parse them.")
print("(We can't handle the %r character.)" % (badchar,))
return 1
debugparams = argv;
@CommandArgument('--slowscript', action='store_true', group='debugging',
help='Do not set the JS_DISABLE_SLOW_SCRIPT_SIGNALS env variable; when not set, recoverable but misleading SIGSEGV instances may occur in Ion/Odin JIT code.')
import mozdebug
if not debugger:
# No debugger name was provided. Look for the default ones on current OS.
debugger = mozdebug.get_default_debugger_name(mozdebug.DebuggerSearch.KeepLooking)
self.debuggerInfo = mozdebug.get_debugger_info(debugger, debugparams)
# We could not find the information about the desired debugger.
if not self.debuggerInfo:
print("Could not find a suitable debugger in your PATH.")
return 1
extra_env = { 'MOZ_CRASHREPORTER_DISABLE' : '1' }
binpath = None
@CommandArgumentGroup('DMD')
@CommandArgument('--dmd', action='store_true', group='DMD',
help='Enable DMD. The following arguments have no effect without this.')
@CommandArgument('--sample-below', default=None, type=str, group='DMD',
help='Sample blocks smaller than this. Use 1 for no sampling. The default is 4093.')
@CommandArgument('--max-frames', default=None, type=str, group='DMD',
help='The maximum depth of stack traces. The default and maximum is 24.')
@CommandArgument('--show-dump-stats', action='store_true', group='DMD',
help='Show stats when doing dumps.')
@CommandArgument('--mode', choices=['normal', 'test', 'stress'], group='DMD',
help='Mode of operation. The default is normal.')
def run(self, params, remote, background, noprofile, debug, debugger,
debugparams, slowscript, dmd, sample_below, max_frames,
show_dump_stats, mode):
try:
binpath = self.get_binary_path('app')
@ -895,95 +838,101 @@ class DebugProgram(MachCommandBase):
print(e)
return 1
# Build the list of arguments to pass to run_process
args = [self.debuggerInfo.path] + self.debuggerInfo.args
args.append(binpath)
args = [binpath]
if params:
args.extend(params)
if not remote:
args.append('-no-remote')
if not background and sys.platform == 'darwin':
args.append('-foreground')
if params:
args.extend(params)
if '-profile' not in params and '-P' not in params and not noprofile:
path = os.path.join(self.topobjdir, 'tmp', 'scratch_user')
if not os.path.isdir(path):
os.makedirs(path)
args.append('-profile')
args.append(path)
if not slowscript:
extra_env['JS_DISABLE_SLOW_SCRIPT_SIGNALS'] = '1'
return self.run_process(args=args, append_env=extra_env,
ensure_exit_code=False, pass_thru=True)
@CommandProvider
class RunDmd(MachCommandBase):
"""Launch the compiled binary with DMD enabled"""
extra_env = {}
@Command('dmd', category='post-build',
description='Run the compiled program with DMD enabled.')
@CommandArgument('params', nargs='...',
help=('Command-line arguments to be passed through to the program. '
'Not specifying a -profile or -P option will result in a '
'temporary profile being used. If passing -params use a "--" to '
'indicate the start of params to pass to firefox.'))
@CommandArgument('--remote', '-r', action='store_true',
help='Do not pass the -no-remote argument by default.')
@CommandArgument('--background', '-b', action='store_true',
help='Do not pass the -foreground argument by default on Mac')
@CommandArgument('--noprofile', '-n', action='store_true',
help='Do not pass the -profile argument by default.')
@CommandArgument('--sample-below', default=None, type=str,
help='The sample size to use, [1..n]. Default is 4093.')
@CommandArgument('--max-frames', default=None, type=str,
help='The max number of stack frames to capture in allocation traces, [1..24] Default is 24.')
@CommandArgument('--show-dump-stats', action='store_true',
help='Show stats when doing dumps.')
def dmd(self, params, remote, background, noprofile, sample_below, max_frames, show_dump_stats):
args = get_run_args(self, params, remote, background, noprofile)
if not args:
return 1
if debug:
import mozdebug
if not debugger:
# No debugger name was provided. Look for the default ones on
# current OS.
debugger = mozdebug.get_default_debugger_name(mozdebug.DebuggerSearch.KeepLooking)
lib_dir = os.path.join(self.distdir, 'lib')
lib_name = self.substs['DLL_PREFIX'] + 'dmd' + self.substs['DLL_SUFFIX']
dmd_lib = os.path.join(lib_dir, lib_name)
if not os.path.exists(dmd_lib):
print("You need to build with |--enable-dmd| to use dmd.")
return 1
self.debuggerInfo = mozdebug.get_debugger_info(debugger, debugparams)
if not self.debuggerInfo:
print("Could not find a suitable debugger in your PATH.")
return 1
dmd_params = []
# Parameters come from the CLI. We need to convert them before
# their use.
if debugparams:
import pymake.process
argv, badchar = pymake.process.clinetoargv(debugparams, os.getcwd())
if badchar:
print("The --debugparams you passed require a real shell to parse them.")
print("(We can't handle the %r character.)" % (badchar,))
return 1
debugparams = argv;
if sample_below:
dmd_params.append('--sample-below=' + sample_below)
if max_frames:
dmd_params.append('--max-frames=' + max_frames)
if show_dump_stats:
dmd_params.append('--show-dump-stats=yes')
if not slowscript:
extra_env['JS_DISABLE_SLOW_SCRIPT_SIGNALS'] = '1'
if dmd_params:
dmd_str = " ".join(dmd_params)
else:
dmd_str = "1"
extra_env['MOZ_CRASHREPORTER_DISABLE'] = '1'
env_vars = {
"Darwin": {
"DYLD_INSERT_LIBRARIES": dmd_lib,
"LD_LIBRARY_PATH": lib_dir,
"DMD": dmd_str,
},
"Linux": {
"LD_PRELOAD": dmd_lib,
"LD_LIBRARY_PATH": lib_dir,
"DMD": dmd_str,
},
"WINNT": {
"MOZ_REPLACE_MALLOC_LIB": dmd_lib,
"DMD": dmd_str,
},
}
# Prepend the debugger args.
args = [self.debuggerInfo.path] + self.debuggerInfo.args + args
if dmd:
dmd_params = []
if sample_below:
dmd_params.append('--sample-below=' + sample_below)
if max_frames:
dmd_params.append('--max-frames=' + max_frames)
if show_dump_stats:
dmd_params.append('--show-dump-stats=yes')
if mode:
dmd_params.append('--mode=' + mode)
if dmd_params:
dmd_env_var = " ".join(dmd_params)
else:
dmd_env_var = "1"
bin_dir = os.path.dirname(binpath)
lib_name = self.substs['DLL_PREFIX'] + 'dmd' + self.substs['DLL_SUFFIX']
dmd_lib = os.path.join(bin_dir, lib_name)
if not os.path.exists(dmd_lib):
print("Please build with |--enable-dmd| to use DMD.")
return 1
env_vars = {
"Darwin": {
"DYLD_INSERT_LIBRARIES": dmd_lib,
"LD_LIBRARY_PATH": bin_dir,
"DMD": dmd_env_var,
},
"Linux": {
"LD_PRELOAD": dmd_lib,
"LD_LIBRARY_PATH": bin_dir,
"DMD": dmd_env_var,
},
"WINNT": {
"MOZ_REPLACE_MALLOC_LIB": dmd_lib,
"DMD": dmd_env_var,
},
}
extra_env.update(env_vars.get(self.substs['OS_ARCH'], {}))
return self.run_process(args=args, ensure_exit_code=False,
pass_thru=True, append_env=env_vars[self.substs['OS_ARCH']])
pass_thru=True, append_env=extra_env)
@CommandProvider
class Buildsymbols(MachCommandBase):