How to use adb_path method in ATX

Best Python code snippet using ATX Github


Full Screen

1#2# Copyright (C) 2015 The Android Open Source Project3#4# Licensed under the Apache License, Version 2.0 (the "License");5# you may not use this file except in compliance with the License.6# You may obtain a copy of the License at7#8# Unless required by applicable law or agreed to in writing, software11# distributed under the License is distributed on an "AS IS" BASIS,12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13# See the License for the specific language governing permissions and14# limitations under the License.15#16import atexit17import base6418import logging19import os20import re21import subprocess22class FindDeviceError(RuntimeError):23 pass24class DeviceNotFoundError(FindDeviceError):25 def __init__(self, serial):26 self.serial = serial27 super(DeviceNotFoundError, self).__init__(28 'No device with serial {}'.format(serial))29class NoUniqueDeviceError(FindDeviceError):30 def __init__(self):31 super(NoUniqueDeviceError, self).__init__('No unique device')32class ShellError(RuntimeError):33 def __init__(self, cmd, stdout, stderr, exit_code):34 super(ShellError, self).__init__(35 '`{0}` exited with code {1}'.format(cmd, exit_code))36 self.cmd = cmd37 self.stdout = stdout38 self.stderr = stderr39 self.exit_code = exit_code40def get_devices(adb_path='adb'):41 with open(os.devnull, 'wb') as devnull:42 subprocess.check_call([adb_path, 'start-server'], stdout=devnull,43 stderr=devnull)44 out = split_lines(subprocess.check_output([adb_path, 'devices']))45 # The first line of `adb devices` just says "List of attached devices", so46 # skip that.47 devices = []48 for line in out[1:]:49 if not line.strip():50 continue51 if 'offline' in line:52 continue53 serial, _ = re.split(r'\s+', line, maxsplit=1)54 devices.append(serial)55 return devices56def _get_unique_device(product=None, adb_path='adb'):57 devices = get_devices(adb_path=adb_path)58 if len(devices) != 1:59 raise NoUniqueDeviceError()60 return AndroidDevice(devices[0], product, adb_path)61def _get_device_by_serial(serial, product=None, adb_path='adb'):62 for device in get_devices(adb_path=adb_path):63 if device == serial:64 return AndroidDevice(serial, product, adb_path)65 raise DeviceNotFoundError(serial)66def get_device(serial=None, product=None, adb_path='adb'):67 """Get a uniquely identified AndroidDevice if one is available.68 Raises:69 DeviceNotFoundError:70 The serial specified by `serial` or $ANDROID_SERIAL is not71 connected.72 NoUniqueDeviceError:73 Neither `serial` nor $ANDROID_SERIAL was set, and the number of74 devices connected to the system is not 1. Having 0 connected75 devices will also result in this error.76 Returns:77 An AndroidDevice associated with the first non-None identifier in the78 following order of preference:79 1) The `serial` argument.80 2) The environment variable $ANDROID_SERIAL.81 3) The single device connnected to the system.82 """83 if serial is not None:84 return _get_device_by_serial(serial, product, adb_path)85 android_serial = os.getenv('ANDROID_SERIAL')86 if android_serial is not None:87 return _get_device_by_serial(android_serial, product, adb_path)88 return _get_unique_device(product, adb_path=adb_path)89def _get_device_by_type(flag, adb_path):90 with open(os.devnull, 'wb') as devnull:91 subprocess.check_call([adb_path, 'start-server'], stdout=devnull,92 stderr=devnull)93 try:94 serial = subprocess.check_output(95 [adb_path, flag, 'get-serialno']).strip()96 except subprocess.CalledProcessError:97 raise RuntimeError('adb unexpectedly returned nonzero')98 if serial == 'unknown':99 raise NoUniqueDeviceError()100 return _get_device_by_serial(serial, adb_path=adb_path)101def get_usb_device(adb_path='adb'):102 """Get the unique USB-connected AndroidDevice if it is available.103 Raises:104 NoUniqueDeviceError:105 0 or multiple devices are connected via USB.106 Returns:107 An AndroidDevice associated with the unique USB-connected device.108 """109 return _get_device_by_type('-d', adb_path=adb_path)110def get_emulator_device(adb_path='adb'):111 """Get the unique emulator AndroidDevice if it is available.112 Raises:113 NoUniqueDeviceError:114 0 or multiple emulators are running.115 Returns:116 An AndroidDevice associated with the unique running emulator.117 """118 return _get_device_by_type('-e', adb_path=adb_path)119# If necessary, modifies subprocess.check_output() or subprocess.Popen() args120# to run the subprocess via Windows PowerShell to work-around an issue in121# Python 2's subprocess class on Windows where it doesn't support Unicode.122def _get_subprocess_args(args):123 # Only do this slow work-around if Unicode is in the cmd line on Windows.124 # PowerShell takes 600-700ms to startup on a 2013-2014 machine, which is125 # very slow.126 if != 'nt' or all(not isinstance(arg, unicode) for arg in args[0]):127 return args128 def escape_arg(arg):129 # Escape for the parsing that the C Runtime does in Windows apps. In130 # particular, this will take care of double-quotes.131 arg = subprocess.list2cmdline([arg])132 # Escape single-quote with another single-quote because we're about133 # to...134 arg = arg.replace(u"'", u"''")135 # ...put the arg in a single-quoted string for PowerShell to parse.136 arg = u"'" + arg + u"'"137 return arg138 # Escape command line args.139 argv = map(escape_arg, args[0])140 # Cause script errors (such as adb not found) to stop script immediately141 # with an error.142 ps_code = u'$ErrorActionPreference = "Stop"\r\n'143 # Add current directory to the PATH var, to match cmd.exe/CreateProcess()144 # behavior.145 ps_code += u'$env:Path = ".;" + $env:Path\r\n'146 # Precede by &, the PowerShell call operator, and separate args by space.147 ps_code += u'& ' + u' '.join(argv)148 # Make the PowerShell exit code the exit code of the subprocess.149 ps_code += u'\r\nExit $LastExitCode'150 # Encode as UTF-16LE (without Byte-Order-Mark) which Windows natively151 # understands.152 ps_code = ps_code.encode('utf-16le')153 # Encode the PowerShell command as base64 and use the special154 # -EncodedCommand option that base64 decodes. Base64 is just plain ASCII,155 # so it should have no problem passing through Win32 CreateProcessA()156 # (which python erroneously calls instead of CreateProcessW()).157 return (['powershell.exe', '-NoProfile', '-NonInteractive',158 '-EncodedCommand', base64.b64encode(ps_code)],) + args[1:]159# Call this instead of subprocess.check_output() to work-around issue in Python160# 2's subprocess class on Windows where it doesn't support Unicode.161def _subprocess_check_output(*args, **kwargs):162 try:163 return subprocess.check_output(*_get_subprocess_args(args), **kwargs)164 except subprocess.CalledProcessError as e:165 # Show real command line instead of the powershell.exe command line.166 raise subprocess.CalledProcessError(e.returncode, args[0],167 output=e.output)168# Call this instead of subprocess.Popen(). Like _subprocess_check_output().169def _subprocess_Popen(*args, **kwargs):170 return subprocess.Popen(*_get_subprocess_args(args), **kwargs)171def split_lines(s):172 """Splits lines in a way that works even on Windows and old devices.173 Windows will see \r\n instead of \n, old devices do the same, old devices174 on Windows will see \r\r\n.175 """176 # rstrip is used here to workaround a difference between splineslines and177 # re.split:178 # >>> 'foo\n'.splitlines()179 # ['foo']180 # >>> re.split(r'\n', 'foo\n')181 # ['foo', '']182 return re.split(r'[\r\n]+', s.rstrip())183def version(adb_path=None):184 """Get the version of adb (in terms of ADB_SERVER_VERSION)."""185 adb_path = adb_path if adb_path is not None else ['adb']186 version_output = subprocess.check_output(adb_path + ['version'])187 pattern = r'^Android Debug Bridge version 1.0.(\d+)$'188 result = re.match(pattern, version_output.splitlines()[0])189 if not result:190 return 0191 return int( AndroidDevice(object):193 # Delimiter string to indicate the start of the exit code.194 _RETURN_CODE_DELIMITER = 'x'195 # Follow any shell command with this string to get the exit196 # status of a program since this isn't propagated by adb.197 #198 # The delimiter is needed because `printf 1; echo $?` would print199 # "10", and we wouldn't be able to distinguish the exit code.200 _RETURN_CODE_PROBE = [';', 'echo', '{0}$?'.format(_RETURN_CODE_DELIMITER)]201 # Maximum search distance from the output end to find the delimiter.202 # adb on Windows returns \r\n even if adbd returns \n. Some old devices203 # seem to actually return \r\r\n.204 _RETURN_CODE_SEARCH_LENGTH = len(205 '{0}255\r\r\n'.format(_RETURN_CODE_DELIMITER))206 def __init__(self, serial, product=None, adb_path='adb'):207 self.serial = serial208 self.product = product209 self.adb_cmd = [adb_path]210 if self.serial is not None:211 self.adb_cmd.extend(['-s', serial])212 if self.product is not None:213 self.adb_cmd.extend(['-p', product])214 self._linesep = None215 self._features = None216 @property217 def linesep(self):218 if self._linesep is None:219 self._linesep = subprocess.check_output(self.adb_cmd +220 ['shell', 'echo'])221 return self._linesep222 @property223 def features(self):224 if self._features is None:225 try:226 self._features = split_lines(self._simple_call(['features']))227 except subprocess.CalledProcessError:228 self._features = []229 return self._features230 def has_shell_protocol(self):231 return version(self.adb_cmd) >= 35 and 'shell_v2' in self.features232 def _make_shell_cmd(self, user_cmd):233 command = self.adb_cmd + ['shell'] + user_cmd234 if not self.has_shell_protocol():235 command += self._RETURN_CODE_PROBE236 return command237 def _parse_shell_output(self, out):238 """Finds the exit code string from shell output.239 Args:240 out: Shell output string.241 Returns:242 An (exit_code, output_string) tuple. The output string is243 cleaned of any additional stuff we appended to find the244 exit code.245 Raises:246 RuntimeError: Could not find the exit code in |out|.247 """248 search_text = out249 if len(search_text) > self._RETURN_CODE_SEARCH_LENGTH:250 # We don't want to search over massive amounts of data when we know251 # the part we want is right at the end.252 search_text = search_text[-self._RETURN_CODE_SEARCH_LENGTH:]253 partition = search_text.rpartition(self._RETURN_CODE_DELIMITER)254 if partition[1] == '':255 raise RuntimeError('Could not find exit status in shell output.')256 result = int(partition[2])257 # partition[0] won't contain the full text if search_text was258 # truncated, pull from the original string instead.259 out = out[:-len(partition[1]) - len(partition[2])]260 return result, out261 def _simple_call(self, cmd):262' '.join(self.adb_cmd + cmd))263 return _subprocess_check_output(264 self.adb_cmd + cmd, stderr=subprocess.STDOUT)265 def shell(self, cmd):266 """Calls `adb shell`267 Args:268 cmd: command to execute as a list of strings.269 Returns:270 A (stdout, stderr) tuple. Stderr may be combined into stdout271 if the device doesn't support separate streams.272 Raises:273 ShellError: the exit code was non-zero.274 """275 exit_code, stdout, stderr = self.shell_nocheck(cmd)276 if exit_code != 0:277 raise ShellError(cmd, stdout, stderr, exit_code)278 return stdout, stderr279 def shell_nocheck(self, cmd):280 """Calls `adb shell`281 Args:282 cmd: command to execute as a list of strings.283 Returns:284 An (exit_code, stdout, stderr) tuple. Stderr may be combined285 into stdout if the device doesn't support separate streams.286 """287 cmd = self._make_shell_cmd(cmd)288' '.join(cmd))289 p = _subprocess_Popen(290 cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)291 stdout, stderr = p.communicate()292 if self.has_shell_protocol():293 exit_code = p.returncode294 else:295 exit_code, stdout = self._parse_shell_output(stdout)296 return exit_code, stdout, stderr297 def shell_popen(self, cmd, kill_atexit=True, preexec_fn=None,298 creationflags=0, **kwargs):299 """Calls `adb shell` and returns a handle to the adb process.300 This function provides direct access to the subprocess used to run the301 command, without special return code handling. Users that need the302 return value must retrieve it themselves.303 Args:304 cmd: Array of command arguments to execute.305 kill_atexit: Whether to kill the process upon exiting.306 preexec_fn: Argument forwarded to subprocess.Popen.307 creationflags: Argument forwarded to subprocess.Popen.308 **kwargs: Arguments forwarded to subprocess.Popen.309 Returns:310 subprocess.Popen handle to the adb shell instance311 """312 command = self.adb_cmd + ['shell'] + cmd313 # Make sure a ctrl-c in the parent script doesn't kill gdbserver.314 if == 'nt':315 creationflags |= subprocess.CREATE_NEW_PROCESS_GROUP316 else:317 if preexec_fn is None:318 preexec_fn = os.setpgrp319 elif preexec_fn is not os.setpgrp:320 fn = preexec_fn321 def _wrapper():322 fn()323 os.setpgrp()324 preexec_fn = _wrapper325 p = _subprocess_Popen(command, creationflags=creationflags,326 preexec_fn=preexec_fn, **kwargs)327 if kill_atexit:328 atexit.register(p.kill)329 return p330 def install(self, filename, replace=False):331 cmd = ['install']332 if replace:333 cmd.append('-r')334 cmd.append(filename)335 return self._simple_call(cmd)336 def push(self, local, remote):337 return self._simple_call(['push', local, remote])338 def pull(self, remote, local):339 return self._simple_call(['pull', remote, local])340 def sync(self, directory=None):341 cmd = ['sync']342 if directory is not None:343 cmd.append(directory)344 return self._simple_call(cmd)345 def tcpip(self, port):346 return self._simple_call(['tcpip', port])347 def usb(self):348 return self._simple_call(['usb'])349 def reboot(self):350 return self._simple_call(['reboot'])351 def remount(self):352 return self._simple_call(['remount'])353 def root(self):354 return self._simple_call(['root'])355 def unroot(self):356 return self._simple_call(['unroot'])357 def connect(self, host):358 return self._simple_call(['connect', host])359 def disconnect(self, host):360 return self._simple_call(['disconnect', host])361 def forward(self, local, remote):362 return self._simple_call(['forward', local, remote])363 def forward_list(self):364 return self._simple_call(['forward', '--list'])365 def forward_no_rebind(self, local, remote):366 return self._simple_call(['forward', '--no-rebind', local, remote])367 def forward_remove(self, local):368 return self._simple_call(['forward', '--remove', local])369 def forward_remove_all(self):370 return self._simple_call(['forward', '--remove-all'])371 def reverse(self, remote, local):372 return self._simple_call(['reverse', remote, local])373 def reverse_list(self):374 return self._simple_call(['reverse', '--list'])375 def reverse_no_rebind(self, local, remote):376 return self._simple_call(['reverse', '--no-rebind', local, remote])377 def reverse_remove_all(self):378 return self._simple_call(['reverse', '--remove-all'])379 def reverse_remove(self, remote):380 return self._simple_call(['reverse', '--remove', remote])381 def wait(self):382 return self._simple_call(['wait-for-device'])383 def get_props(self):384 result = {}385 output, _ =['getprop'])386 output = split_lines(output)387 pattern = re.compile(r'^\[([^]]+)\]: \[(.*)\]')388 for line in output:389 match = pattern.match(line)390 if match is None:391 raise RuntimeError('invalid getprop line: "{}"'.format(line))392 key = value = if key in result:395 raise RuntimeError('duplicate getprop key: "{}"'.format(key))396 result[key] = value397 return result398 def get_prop(self, prop_name):399 output = split_lines(['getprop', prop_name])[0])400 if len(output) != 1:401 raise RuntimeError('Too many lines in getprop output:\n' +402 '\n'.join(output))403 value = output[0]404 if not value.strip():405 return None406 return value407 def set_prop(self, prop_name, value):...

Full Screen

Full Screen Github


Full Screen

1#2# Copyright (C) 2015 The Android Open Source Project3#4# Licensed under the Apache License, Version 2.0 (the "License");5# you may not use this file except in compliance with the License.6# You may obtain a copy of the License at7#8# Unless required by applicable law or agreed to in writing, software11# distributed under the License is distributed on an "AS IS" BASIS,12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13# See the License for the specific language governing permissions and14# limitations under the License.15#16"""Helpers used by both and"""17import adb18import argparse19import atexit20import os21import subprocess22import sys23import tempfile24class ArgumentParser(argparse.ArgumentParser):25 """ArgumentParser subclass that provides adb device selection."""26 def __init__(self):27 super(ArgumentParser, self).__init__()28 self.add_argument(29 "--adb", dest="adb_path",30 help="use specific adb command")31 group = self.add_argument_group(title="device selection")32 group = group.add_mutually_exclusive_group()33 group.add_argument(34 "-a", action="store_const", dest="device", const="-a",35 help="directs commands to all interfaces")36 group.add_argument(37 "-d", action="store_const", dest="device", const="-d",38 help="directs commands to the only connected USB device")39 group.add_argument(40 "-e", action="store_const", dest="device", const="-e",41 help="directs commands to the only connected emulator")42 group.add_argument(43 "-s", metavar="SERIAL", action="store", dest="serial",44 help="directs commands to device/emulator with the given serial")45 def parse_args(self, args=None, namespace=None):46 result = super(ArgumentParser, self).parse_args(args, namespace)47 adb_path = result.adb_path or "adb"48 # Try to run the specified adb command49 try:50 subprocess.check_output([adb_path, "version"],51 stderr=subprocess.STDOUT)52 except (OSError, subprocess.CalledProcessError):53 msg = "ERROR: Unable to run adb executable (tried '{}')."54 if not result.adb_path:55 msg += "\n Try specifying its location with --adb."56 sys.exit(msg.format(adb_path))57 try:58 if result.device == "-a":59 result.device = adb.get_device(adb_path=adb_path)60 elif result.device == "-d":61 result.device = adb.get_usb_device(adb_path=adb_path)62 elif result.device == "-e":63 result.device = adb.get_emulator_device(adb_path=adb_path)64 else:65 result.device = adb.get_device(result.serial, adb_path=adb_path)66 except (adb.DeviceNotFoundError, adb.NoUniqueDeviceError, RuntimeError):67 # Don't error out if we can't find a device.68 result.device = None69 return result70def get_run_as_cmd(user, cmd):71 """Generate a run-as or su command depending on user."""72 if user is None:73 return cmd74 elif user == "root":75 return ["su", "0"] + cmd76 else:77 return ["run-as", user] + cmd78def get_processes(device):79 """Return a dict from process name to list of running PIDs on the device."""80 # Some custom ROMs use busybox instead of toolbox for ps. Without -w,81 # busybox truncates the output, and very long package names like82 # com.exampleisverylongtoolongbyfar.plasma exceed the limit.83 #84 # Perform the check for this on the device to avoid an adb roundtrip85 # Some devices might not have readlink or which, so we need to handle86 # this as well.87 #88 # Gracefully handle [ or readlink being missing by always using `ps` if89 # readlink is missing. (API 18 has [, but not readlink).90 ps_script = """91 if $(ls /system/bin/readlink >/dev/null 2>&1); then92 if [ $(readlink /system/bin/ps) == "toolbox" ]; then93 ps;94 else95 ps -w;96 fi97 else98 ps;99 fi100 """101 ps_script = " ".join([line.strip() for line in ps_script.splitlines()])102 output, _ =[ps_script])103 return parse_ps_output(output)104def parse_ps_output(output):105 processes = dict()106 output = adb.split_lines(output.replace("\r", ""))107 columns = output.pop(0).split()108 try:109 pid_column = columns.index("PID")110 except ValueError:111 pid_column = 1112 while output:113 columns = output.pop().split()114 process_name = columns[-1]115 pid = int(columns[pid_column])116 if process_name in processes:117 processes[process_name].append(pid)118 else:119 processes[process_name] = [pid]120 return processes121def get_pids(device, process_name):122 processes = get_processes(device)123 return processes.get(process_name, [])124def start_gdbserver(device, gdbserver_local_path, gdbserver_remote_path,125 target_pid, run_cmd, debug_socket, port, user=None):126 """Start gdbserver in the background and forward necessary ports.127 Args:128 device: ADB device to start gdbserver on.129 gdbserver_local_path: Host path to push gdbserver from, can be None.130 gdbserver_remote_path: Device path to push gdbserver to.131 target_pid: PID of device process to attach to.132 run_cmd: Command to run on the device.133 debug_socket: Device path to place gdbserver unix domain socket.134 port: Host port to forward the debug_socket to.135 user: Device user to run gdbserver as.136 Returns:137 Popen handle to the `adb shell` process gdbserver was started with.138 """139 assert target_pid is None or run_cmd is None140 # Push gdbserver to the target.141 if gdbserver_local_path is not None:142 device.push(gdbserver_local_path, gdbserver_remote_path)143 # Run gdbserver.144 gdbserver_cmd = [gdbserver_remote_path, "--once",145 "+{}".format(debug_socket)]146 if target_pid is not None:147 gdbserver_cmd += ["--attach", str(target_pid)]148 else:149 gdbserver_cmd += run_cmd150 device.forward("tcp:{}".format(port),151 "localfilesystem:{}".format(debug_socket))152 atexit.register(lambda: device.forward_remove("tcp:{}".format(port)))153 gdbserver_cmd = get_run_as_cmd(user, gdbserver_cmd)154 gdbserver_output_path = os.path.join(tempfile.gettempdir(),155 "gdbclient.log")156 print("Redirecting gdbserver output to {}".format(gdbserver_output_path))157 gdbserver_output = file(gdbserver_output_path, 'w')158 return device.shell_popen(gdbserver_cmd, stdout=gdbserver_output,159 stderr=gdbserver_output)160def find_file(device, executable_path, sysroot, user=None):161 """Finds a device executable file.162 This function first attempts to find the local file which will163 contain debug symbols. If that fails, it will fall back to164 downloading the stripped file from the device.165 Args:166 device: the AndroidDevice object to use.167 executable_path: absolute path to the executable or symlink.168 sysroot: absolute path to the built symbol sysroot.169 user: if necessary, the user to download the file as.170 Returns:171 A tuple containing (<open file object>, <was found locally>).172 Raises:173 RuntimeError: could not find the executable binary.174 ValueError: |executable_path| is not absolute.175 """176 if not os.path.isabs(executable_path):177 raise ValueError("'{}' is not an absolute path".format(executable_path))178 def generate_files():179 """Yields (<file name>, <found locally>) tuples."""180 # First look locally to avoid shelling into the device if possible.181 # os.path.join() doesn't combine absolute paths, use + instead.182 yield (sysroot + executable_path, True)183 # Next check if the path is a symlink.184 try:185 target =['readlink', '-e', '-n', executable_path])[0]186 yield (sysroot + target, True)187 except adb.ShellError:188 pass189 # Last, download the stripped executable from the device if necessary.190 file_name = "gdbclient-binary-{}".format(os.getppid())191 remote_temp_path = "/data/local/tmp/{}".format(file_name)192 local_path = os.path.join(tempfile.gettempdir(), file_name)193 cmd = get_run_as_cmd(user,194 ["cat", executable_path, ">", remote_temp_path])195 try:196 except adb.ShellError:198 raise RuntimeError("Failed to copy '{}' to temporary folder on "199 "device".format(executable_path))200 device.pull(remote_temp_path, local_path)201 yield (local_path, False)202 for path, found_locally in generate_files():203 if os.path.isfile(path):204 return (open(path, "r"), found_locally)205 raise RuntimeError('Could not find executable {}'.format(executable_path))206def find_binary(device, pid, sysroot, user=None):207 """Finds a device executable file corresponding to |pid|."""208 return find_file(device, "/proc/{}/exe".format(pid), sysroot, user)209def get_binary_arch(binary_file):210 """Parse a binary's ELF header for arch."""211 try:212 binary = except IOError:215 raise RuntimeError("failed to read binary file")216 ei_class = ord(binary[0x4]) # 1 = 32-bit, 2 = 64-bit217 ei_data = ord(binary[0x5]) # Endianness218 assert ei_class == 1 or ei_class == 2219 if ei_data != 1:220 raise RuntimeError("binary isn't little-endian?")221 e_machine = ord(binary[0x13]) << 8 | ord(binary[0x12])222 if e_machine == 0x28:223 assert ei_class == 1224 return "arm"225 elif e_machine == 0xB7:226 assert ei_class == 2227 return "arm64"228 elif e_machine == 0x03:229 assert ei_class == 1230 return "x86"231 elif e_machine == 0x3E:232 assert ei_class == 2233 return "x86_64"234 elif e_machine == 0x08:235 if ei_class == 1:236 return "mips"237 else:238 return "mips64"239 else:240 raise RuntimeError("unknown architecture: 0x{:x}".format(e_machine))241def start_gdb(gdb_path, gdb_commands, gdb_flags=None):242 """Start gdb in the background and block until it finishes.243 Args:244 gdb_path: Path of the gdb binary.245 gdb_commands: Contents of GDB script to run.246 gdb_flags: List of flags to append to gdb command.247 """248 # Windows disallows opening the file while it's open for writing.249 gdb_script_fd, gdb_script_path = tempfile.mkstemp()250 os.write(gdb_script_fd, gdb_commands)251 os.close(gdb_script_fd)252 gdb_args = [gdb_path, "-x", gdb_script_path] + (gdb_flags or [])253 kwargs = {}254 if sys.platform.startswith("win"):255 kwargs["creationflags"] = subprocess.CREATE_NEW_CONSOLE256 gdb_process = subprocess.Popen(gdb_args, **kwargs)257 while gdb_process.returncode is None:258 try:259 gdb_process.communicate()260 except KeyboardInterrupt:261 pass...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:


You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run ATX automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?