Best Python code snippet using ATX
device.py
Source:device.py  
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#      http://www.apache.org/licenses/LICENSE-2.09#10# 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 os.name != '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(result.group(1))192class 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        logging.info(' '.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        logging.info(' '.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 os.name == '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, _ = self.shell(['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 = match.group(1)393            value = match.group(2)394            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(self.shell(['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):...__init__.py
Source:__init__.py  
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#      http://www.apache.org/licenses/LICENSE-2.09#10# 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 gdbclient.py and ndk-gdb.py."""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, _ = device.shell([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 = device.shell(['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            device.shell(cmd)197        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_file.seek(0)213        binary = binary_file.read(0x14)214    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...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.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
