Skip to content

ability to attach to a process using pid #30

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 25 additions & 32 deletions debuggers/gdb/gdb_mi_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,22 @@ class GDBMiDebugger(Driver):

gdb_instances = None

def __init__(self, base_args, base_script_file_path, regression_args, regression_script_file_path):
def __init__(self, base_args, base_script_file_path, regression_args, regression_script_file_path,
base_pid=None, regression_pid=None):
self.base_gdb_instance = create_IDDGdbController(base_script_file_path)
self.regressed_gdb_instance = create_IDDGdbController(regression_script_file_path)

self.gdb_instances = { 'base': self.base_gdb_instance, 'regressed': self.regressed_gdb_instance }

self.run_single_raw_command('file ' + base_args, 'base')
self.run_single_raw_command('file ' + regression_args, 'regressed')
if base_pid is None:
self.run_single_raw_command('file ' + base_args, 'base')
else:
self.run_single_raw_command('attach ' + base_pid, 'base')

if regression_pid is None:
self.run_single_raw_command('file ' + regression_args, 'regressed')
else:
self.run_single_raw_command('attach ' + regression_pid, 'regressed')

dirname = os.path.dirname(__file__)
self.run_parallel_raw_command("source " + os.path.join(dirname, "gdb_commands.py"))
Expand All @@ -35,23 +43,11 @@ def run_parallel_command(self, command):

# wait till base is done
raw_result = self.base_gdb_instance.recv()

# make sure all output is flushed
# time.sleep(.005)
self.base_gdb_instance.send((("",), {"timeout_sec": 60}))
raw_result += self.base_gdb_instance.recv()

# parse output (base)
base_response = self.parse_command_output(raw_result)

# wait till regression is done
raw_result = self.regressed_gdb_instance.recv()

# make sure all output is flushed
# time.sleep(.005)
self.regressed_gdb_instance.send((("",), {"timeout_sec": 60}))
raw_result += self.regressed_gdb_instance.recv()

# parse output regression
regressed_response = self.parse_command_output(raw_result)

Expand All @@ -72,12 +68,7 @@ def run_single_command(self, command, version):

self.gdb_instances[version].send(((" {command}\n".format(command = command),), {"timeout_sec": 60}))
raw_result = self.gdb_instances[version].recv()

# make sure all output is flushed
# time.sleep(.005)
self.gdb_instances[version].send((("",), {"timeout_sec": 60}))
raw_result += self.gdb_instances[version].recv()


return self.parse_command_output(raw_result)

def run_single_special_command(self, command, version):
Expand All @@ -87,10 +78,6 @@ def run_single_special_command(self, command, version):
self.gdb_instances[version].send(((" {command}\n".format(command = command),), {"timeout_sec": 60}))
raw_result = self.gdb_instances[version].recv()

# flush output
self.gdb_instances[version].send((("",), {"timeout_sec": 60}))
raw_result += self.gdb_instances[version].recv()

return self.parse_special_command_output(raw_result)

def parse_special_command_output(self, raw_result):
Expand Down Expand Up @@ -155,20 +142,26 @@ def get_current_registers(self):
return { "base" : base_stack_frame, "regressed" : regression_stack_frame }

def run_parallel_raw_command(self, command):
base_result = str(self.run_single_raw_command(command, "base"))
regression_result = str(self.run_single_raw_command(command, "regressed"))
self.base_gdb_instance.send((("{command}\n".format(command = command),), {"timeout_sec": 60}))
self.regressed_gdb_instance.send((("{command}\n".format(command = command),), {"timeout_sec": 60}))

raw_result = self.base_gdb_instance.recv()
base_result = str(self.parse_raw_command_output(raw_result))
raw_result = self.regressed_gdb_instance.recv()
regression_result = str(self.parse_raw_command_output(raw_result))

return { "base": base_result, "regressed": regression_result }

def run_single_raw_command(self, command, version):
def parse_raw_command_output(self, raw_result):
result = []
self.gdb_instances[version].send((("{command}\n".format(command = command),), {"timeout_sec": 60}))
raw_result = self.gdb_instances[version].recv()

for item in raw_result:
result.append(str(item))

return result

def run_single_raw_command(self, command, version):
self.gdb_instances[version].send((("{command}\n".format(command = command),), {"timeout_sec": 60}))
raw_result = self.gdb_instances[version].recv()
return self.parse_raw_command_output(raw_result)

def terminate(self):
terminate_all_IDDGdbController()
29 changes: 25 additions & 4 deletions idd.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,9 +311,11 @@ async def execute_debugger_command(self, event: Input.Changed) -> None:

parser = argparse.ArgumentParser(description='Diff Debug for simple debugging!')
parser.add_argument('-c','--comparator', help='Choose a comparator', default='gdb')
parser.add_argument('-ba','--base-args', help='Base executable args', default='[]', nargs='+')
parser.add_argument('-ba','--base-args', help='Base executable args', default="", nargs='+')
parser.add_argument('-bpid','--base-processid', help='Base process ID', default=None)
parser.add_argument('-bs','--base-script-path', help='Base preliminary script file path', default=None, nargs='+')
parser.add_argument('-ra','--regression-args', help='Regression executable args', default='[]', nargs='+')
parser.add_argument('-ra','--regression-args', help='Regression executable args', default="", nargs='+')
parser.add_argument('-rpid','--regression-processid', help='Regression process ID', default=None)
parser.add_argument('-rs','--regression-script-path', help='Regression preliminary script file path', default=None, nargs='+')
parser.add_argument('-r','--remote_host', help='The host of the remote server', default='localhost')
parser.add_argument('-p','--platform', help='The platform of the remote server: macosx, linux', default='linux')
Expand All @@ -325,22 +327,41 @@ async def execute_debugger_command(self, event: Input.Changed) -> None:

comparator = args['comparator']
ba = ' '.join(args['base_args'])
bpid = args['base_processid']
bs = ' '.join(args['base_script_path']) if args['base_script_path'] is not None else None
ra = ' '.join(args['regression_args'])
rpid = args['regression_processid']
rs = ' '.join(args['regression_script_path']) if args["regression_script_path"] is not None else None

if comparator == 'gdb':
from debuggers.gdb.gdb_mi_driver import GDBMiDebugger

Debugger = GDBMiDebugger(ba, bs, ra, rs)
if ba != "" and bpid is not None:
raise Exception("Both executable and process ID given for base. This is not possible")
if ra != "" and rpid is not None:
raise Exception("Both executable and process ID given for regression. This is not possible")

if ba == "":
if ra == "":
Debugger = GDBMiDebugger(ba, bs, ra, rs, base_pid=bpid, regression_pid=rpid)
else:
Debugger = GDBMiDebugger(ba, bs, ra, rs, base_pid=bpid)
else:
if ra == "":
Debugger = GDBMiDebugger(ba, bs, ra, rs, regression_pid=rpid)
else:
Debugger = GDBMiDebugger(ba, bs, ra, rs)

elif comparator == 'lldb':
from debuggers.lldb.lldb_driver import LLDBDebugger

if ba == "" or ra == "":
raise Exception("LLDB can only be used by launching executable and executable is not provided")
Debugger = LLDBDebugger(ba, ra)
else:
sys.exit("Invalid comparator set")

disable_registers = args["disable_registers"]
disable_assembly = args["disable_assembly"]
dd = DiffDebug(disable_assembly, disable_registers)
dd.run()
dd.run()