gdb - How to pass SIGINT to child process with Python subprocess.Popen() using shell = true -
i trying write (python 2.7.3) kind of wrapper gdb, allow me dynamically switch scripted input interactive communication gdb.
so far use
self.process = subprocess.popen(["gdb vuln"], stdin = subprocess.pipe, shell = true)
to start gdb within script. (vuln
binary want examine)
since key feature of gdb pause execution of attached process , allow user inspect registers , memory on receiving sigint (strg+c) need way pass sigint signal it.
neither
self.process.send_signal(signal.sigint)
nor
os.kill(self.process.pid, signal.sigint)
or
os.killpg(self.process.pid, signal.sigint)
work me.
when use 1 of these functions there no response. suppose problem arises use of shell=true
. however, @ point out of ideas. old friend google couldn't me out time, maybe can me. thank's in advance.
cheers, mike
i looked deeper problem , found interesting things. maybe these findings in future.
when calling gdb vuln
using suprocess.popen() in fact create 3 processes, pid returned 1 of sh
(5180).
ps -a 5180 pts/0 00:00:00 sh 5181 pts/0 00:00:00 gdb 5183 pts/0 00:00:00 vuln
consequently sending sigint process in fact send sigint sh
.
besides, continued looking answer , stumbled upon post https://bugzilla.kernel.org/show_bug.cgi?id=9039
to keep short, mentioned there following:
when pressing strg+c while using gdb regularly sigint in fact sent examined program (in case vuln
), ptrace intercept , pass gdb. means is, if use self.process.send_signal(signal.sigint)
in fact never reach gdb way.
temporary workaround:
i managed work around problem calling subprocess.popen()
follows:
subprocess.popen("killall -s int " + self.binary, shell = true)
this nothing more first workaround. when multiple applications same name running might serious damage. besides, somehow fails, if shell=true
not set. if has better fix (e.g. how pid of process startet gdb), please let me know.
cheers, mike
edit:
thanks mark pointing out @ ppid of process. managed narrow down process's sigint sent using following approach:
out = subprocess.check_output(['ps', '-aefj']) line in out.splitlines(): if self.binary in line: l = line.split(" ") while "" in l: l.remove("") # sid , pgid of child process (/bin/sh) sid = os.getsid(self.process.pid) pgid = os.getpgid(self.process.pid) #only true target process if l[4] == str(sid) , l[3] != str(pgid): os.kill(pid, signal.sigint)
Comments
Post a Comment