# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/.
import json import os import shutil import sys from collections import namedtuple from subprocess import check_output
"""
Map of debugging programs to information about them, like default arguments and whether ornot they are interactive.
To add support for a new debugger, simply add the relative entry in
_DEBUGGER_INFO and optionally update the _DEBUGGER_PRIORITIES. """
_DEBUGGER_INFO = { # gdb requires that you supply the '--args' flag in order to pass arguments # after the executable name to the executable. "gdb": {"interactive": True, "args": ["-q", "--args"]}, "cgdb": {"interactive": True, "args": ["-q", "--args"]}, "rust-gdb": {"interactive": True, "args": ["-q", "--args"]}, "lldb": {"interactive": True, "args": ["--"], "requiresEscapedArgs": True}, # Visual Studio Debugger Support. "devenv.exe": {"interactive": True, "args": ["-debugexe"]}, # Visual C++ Express Debugger Support. "wdexpress.exe": {"interactive": True, "args": ["-debugexe"]}, # Windows Development Kit super-debugger. "windbg.exe": { "interactive": True,
},
}
# Maps each OS platform to the preferred debugger programs found in _DEBUGGER_INFO.
_DEBUGGER_PRIORITIES = { "win": ["devenv.exe", "wdexpress.exe"], "linux": ["gdb", "cgdb", "lldb"], "mac": ["lldb", "gdb"], "android": ["lldb"], "unknown": ["gdb"],
}
for suffix in programFilesSuffixes:
windowsKitsPrefix = os.path.join(programFiles + suffix, "Windows Kits") for version in windowsKitsVersions: yield os.path.join(
windowsKitsPrefix, version, "Debuggers", "x64", "windbg.exe"
)
def _vswhere_path(): try: import buildconfig
path = os.path.join(buildconfig.topsrcdir, "build", "win32", "vswhere.exe") if os.path.isfile(path): return path except ImportError: pass # Hope it's available on PATH! return"vswhere.exe"
def get_debugger_path(debugger): """
Get the full path of the debugger.
:param debugger: The name of the debugger. """
if mozinfo.os == "mac"and debugger == "lldb": # On newer OSX versions System Integrity Protections prevents us from # setting certain env vars for a process such as DYLD_LIBRARY_PATH if # it's in a protected directory such as /usr/bin. This is the case for # lldb, so we try to find an instance under the Xcode install instead.
# Attempt to use the xcrun util to find the path. try:
path = check_output(
["xcrun", "--find", "lldb"], universal_newlines=True
).strip() if path: return path except Exception: # Just default to shutil.which instead. pass
if mozinfo.os == "win"and debugger == "devenv.exe": # Attempt to use vswhere to find the path. try:
encoding = "mbcs"if sys.platform == "win32"else"utf-8"
vswhere = _vswhere_path()
vsinfo = check_output([vswhere, "-format", "json", "-latest"])
vsinfo = json.loads(vsinfo.decode(encoding, "replace")) return os.path.join(
vsinfo[0]["installationPath"], "Common7", "IDE", "devenv.exe"
) except Exception: # Just default to shutil.which instead. pass
return shutil.which(debugger)
def get_debugger_info(debugger, debuggerArgs=None, debuggerInteractive=False): """
Get the information about the requested debugger.
Returns a dictionary containing the ``path`` of the debugger executable, if it will run in ``interactive`` mode, its arguments and whether it needs
to escape arguments it passes to the debugged program (``requiresEscapedArgs``). If the debugger cannot be found in the system, returns ``None``.
:param debugger: The name of the debugger.
:param debuggerArgs: If specified, it's the arguments to pass to the debugger, as a string. Any debugger-specific separator arguments are appended after
these arguments.
:param debuggerInteractive: If specified, forces the debugger to be interactive. """
debuggerPath = None
if debugger: # Append '.exe' to the debugger on Windows if it's not present, # so things like '--debugger=devenv' work. if os.name == "nt"andnot debugger.lower().endswith(".exe"):
debugger += ".exe"
debuggerPath = get_debugger_path(debugger)
ifnot debuggerPath: # windbg is not installed with the standard set of tools, and it's # entirely possible that the user hasn't added the install location to # PATH, so we have to be a little more clever than normal to locate it. # Just try to look for it in the standard installed location(s). if debugger == "windbg.exe": for candidate in _windbg_installation_paths(): if os.path.exists(candidate):
debuggerPath = candidate break else: if os.path.exists(debugger):
debuggerPath = debugger
ifnot debuggerPath:
print("Error: Could not find debugger %s." % debugger)
print("Is it installed? Is it in your PATH?") returnNone
def get_debugger_info(type, default): if debuggerName in _DEBUGGER_INFO and type in _DEBUGGER_INFO[debuggerName]: return _DEBUGGER_INFO[debuggerName][type] return default
# Define a namedtuple to access the debugger information from the outside world.
debugger_arguments = []
if debuggerArgs: # Append the provided debugger arguments at the end of the arguments list.
debugger_arguments += debuggerArgs.split()
# Override the default debugger interactive mode if needed.
debugger_interactive = get_debugger_info("interactive", False) if debuggerInteractive:
debugger_interactive = debuggerInteractive
d = DebuggerInfo(
debuggerPath,
debugger_interactive,
debugger_arguments,
get_debugger_info("requiresEscapedArgs", False),
)
return d
# Defines the search policies to use in get_default_debugger_name.
class DebuggerSearch:
OnlyFirst = 1
KeepLooking = 2
def get_default_debugger_name(search=DebuggerSearch.OnlyFirst): """
Get the debugger name for the default debugger on current platform.
:param search: If specified, stops looking for the debugger if the
default one isnot found (``DebuggerSearch.OnlyFirst``) or keeps
looking for other compatible debuggers (``DebuggerSearch.KeepLooking``). """
mozinfo.find_and_update_from_json()
os = mozinfo.info["os"]
# Find out which debuggers are preferred for use on this platform.
debuggerPriorities = _DEBUGGER_PRIORITIES[
os if os in _DEBUGGER_PRIORITIES else"unknown"
]
# Finally get the debugger information. for debuggerName in debuggerPriorities:
debuggerPath = get_debugger_path(debuggerName) if debuggerPath: return debuggerName elifnot search == DebuggerSearch.KeepLooking: returnNone
returnNone
# Defines default values for Valgrind flags. # # --smc-check=all-non-file is required to deal with code generation and # patching by the various JITS. Note that this is only necessary on # x86 and x86_64, but not on ARM. This flag is only necessary for # Valgrind versions prior to 3.11. # # --vex-iropt-register-updates=allregs-at-mem-access is required so that # Valgrind generates correct register values whenever there is a # segfault that is caught and handled. In particular OdinMonkey # requires this. More recent Valgrinds (3.11 and later) provide # --px-default=allregs-at-mem-access and # --px-file-backed=unwindregs-at-mem-access # which provide a significantly cheaper alternative, by restricting the # precise exception behaviour to JIT generated code only. # # --trace-children=yes is required to get Valgrind to follow into # content and other child processes. The resulting output can be # difficult to make sense of, and --child-silent-after-fork=yes # helps by causing Valgrind to be silent for the child in the period # after fork() but before its subsequent exec(). # # --trace-children-skip lists processes that we are not interested # in tracing into. # # --leak-check=full requests full stack traces for all leaked blocks # detected at process exit. # # --show-possibly-lost=no requests blocks for which only an interior # pointer was found to be considered not leaked. # # # TODO: pass in the user supplied args for V (--valgrind-args=) and # use this to detect if a different tool has been selected. If so # adjust tool-specific args appropriately. # # TODO: pass in the path to the Valgrind to be used (--valgrind=), and # check what flags it accepts. Possible args that might be beneficial: # # --num-transtab-sectors=24 [reduces re-jitting overheads in long runs] # --px-default=allregs-at-mem-access # --px-file-backed=unwindregs-at-mem-access # [these reduce PX overheads as described above] #
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.