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

Popular posts from this blog

PHP DOM loadHTML() method unusual warning -

python - How to create jsonb index using GIN on SQLAlchemy? -

c# - TransactionScope not rolling back although no complete() is called -