summaryrefslogtreecommitdiff
path: root/solter.py
blob: 6de8000a3644ea8127a59d5071b394a7c20fba33 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import argparse
import subprocess
import logging
import pprint


SO_SOCKET = 1

SO_KEEPALIVE = 9


def get_commands_enable_keepalive(sockfd: int):
    return (
            "set $rsp -= sizeof(int)",
            "set {int}$rsp = 1",
            f"call (int)setsockopt({sockfd}, {SO_SOCKET}, {SO_KEEPALIVE}, $rsp, sizeof(int))",
            "set $rsp += sizeof(int)",
    )


def main(args):
    numeric_level = getattr(logging, args["loglevel"].upper(), None)
    if not isinstance(numeric_level, int):
        raise ValueError(f"Invalid log level: {args['loglevel']}")
    logging.basicConfig(level=numeric_level)


    cmd = ["gdb", "--pid", str(args["pid"]), "--batch-silent"]

    gdb_cmds = list()
    gdb_cmds.extend(get_commands_enable_keepalive(args["sockfd"]))

    logging.debug("gdb commands: %s", pprint.pformat(gdb_cmds))

    cmd.extend(map(lambda gdb_cmd: f"--eval-command={gdb_cmd}", gdb_cmds))

    logging.debug("Executing: %s", pprint.pformat(cmd))

    subprocess.run(cmd)


if __name__ == "__main__":
    parser = argparse.ArgumentParser()

    parser.add_argument("--pid", type=int, required=True,
                        help="PID of the running process to alter")
    parser.add_argument("--sockfd", type=int, required=True,
                        help="Socket file-descriptor number to alter")
    parser.add_argument("--loglevel", default="info",
                        help="Change log level")

    main(vars(parser.parse_args()))