def run_with_gdb(target_cmd, symbols=None, solib_search=None, env=None, callback=None,
                 callback_args=None, timeout=_common.DEFAULT_TIMEOUT, memory_limit=None,
                 idle_limit=None):
    """
    This function is similar to the :func:`run` function above,
    except the target is executed under control of the GNU Debugger.
    Symbols may be specified manually, otherwise they are expected
    to be findable by GDB (usually included in the target itself).

    :func:`run_with_gdb` returns a :class:`~alf.FuzzResult` instance.
    If no crash was detected, the :attr:`~alf.FuzzResult.classification`
    member of the :class:`~alf.FuzzResult` will be
    :data:`~alf.debug.NOT_AN_EXCEPTION`.

    Classifications: :data:`~alf.debug.NOT_AN_EXCEPTION`,
    :data:`~alf.debug.TIMEOUT`, :data:`~alf.debug.UNKNOWN`.

    Availability: Unix, Windows.
    """
    classification = None
    cpid = None
    if platform.system() == "Windows":
        _common._set_gflags(target_cmd[0])
    if platform.system() == "QNX":
        if not os.path.isfile("libc.so.3"):
            if not os.path.isfile("/root/symbols/x86/lib/libc.so.3.sym"):
                raise RuntimeError("Cannot find /root/symbols/x86/lib/libc.so.3.sym")
            os.symlink("/root/symbols/x86/lib/libc.so.3.sym", "libc.so.3")
    fd, temp_fn = tempfile.mkstemp(prefix="gdb", suffix=".log", dir=".")
    os.close(fd)
    nul = open(os.devnull, "w+")
    try:
        with open(temp_fn, "w+") as f:
            if env is None:
                env = dict(os.environ)
            env["LIBC_FATAL_STDERR_"] = "1"
            p = _common.subprocess.Popen(_gdb_cmd(target_cmd[0], solib_search) + target_cmd,
                close_fds=CLOSE_FDS, stdout=f, stderr=f, stdin=nul,
                creationflags=_common.POPEN_FLAGS, env=env)
            try:
                with open(temp_fn) as fr:
                    while p.poll() is None:
                        line = fr.readline()
                        m = re.match(r"^\*\s+1\s+Thread\s+\w+\s+\(LWP\s+(?P<pid>[0-9]+)\)", line)
                        if m is None:
                            m = re.match(r"^\*\s+1\s+(pid|process|Thread)\s+(?P<pid>[0-9]+)", line)
                        if m:
                            cpid = int(m.group("pid"))
                            break
                cb_res = _common._call_callback(callback, callback_args, p.pid)
                if cb_res == _common.CB_ERROR:
                    raise RuntimeError("callback() returned error")
                target_mon = _common.TargetMonitor(cpid, idle_limit=idle_limit,
                                                   memory_limit=memory_limit, time_limit=timeout)
                while p.poll() is None:
                    if target_mon.check_memory():
                        classification = _common.EXCESS_MEMORY_USAGE
                        break
                    if target_mon.check_idle():
                        break
                    if target_mon.check_timeout():
                        classification = _common.TIMEOUT
                        break
                    time.sleep(0.01)
            finally:
                while p.poll() is None:
                    try:
                        if platform.system() == "QNX":
                            attempt = -1
                            sigs = [signal.SIGTERM, signal.SIGKILL]
                            while p.poll() is None:
                                attempt += 1
                                assert attempt < len(sigs), "Failed to kill child process"
                                _send_signal(sigs[attempt], cpid, p.pid)
                                kill_time = _common.prof_timer()
                                while _common.prof_timer() - kill_time < SLAY_TIMEOUT:
                                    if p.poll() is not None:
                                        break
                                    time.sleep(0.25)
                        elif platform.system() == "Windows":
                            _send_signal(signal.CTRL_BREAK_EVENT, cpid, p.pid)
                        else:
                            _send_signal(signal.SIGTERM, cpid, p.pid)
                    except __HOLE__:
                        pass
                exit_code = p.wait()
            f.seek(0, os.SEEK_SET)
            stdout = f.read()
    finally:
        _common.delete(temp_fn)
        nul.close()
    m = re.search(r"Traceback \(\D+\):.+Python command:", stdout, re.DOTALL)
    if m:
        tb = m.group(0)
        tb = tb[:tb.rfind("\n")]
        if not tb.endswith("No threads running"):
            raise RuntimeError("GDB Python Failure\n\n%s" % tb)
        else:
            return _common.FuzzResult(_common.NOT_AN_EXCEPTION, stdout)
    backtrace, debug_classification = _process_gdb_output(stdout)
    if cb_res == _common.CB_HANG:
        classification = _common.TIMEOUT
    elif classification is None:
        if cb_res == _common.CB_FAIL:
            classification = _common.UNKNOWN
        else:
            classification = debug_classification
    stdout = _trim_disassembly(stdout)
    stdout = _common._limit_output_length(stdout)
    return _common.FuzzResult(classification, stdout, backtrace, exit_code)
dataset/ETHPy150Open blackberry/ALF/alf/debug/_gdb.py/run_with_gdb