pyflame
pyflame copied to clipboard
Pyflame fails on multithreaded applications with setuid
Reproducible on:
- Pyflame 1.6.3 (commit 4a9c3de) linux-gnu x86_64 (ABI list: 26)
- Python 2.7.8 built with GCC 4.4.6 on Linux
Details:
glibc with pthreads uses RT signal to interrupt syscalls and notify all threads when any thread changes uid of the process. Pyflame is unaware of this signal and fails on it.
How to reproduce:
test_setuid.py:
import threading
import time
import random
import os
def task():
time.sleep(random.randint(1, 6))
os.setresuid(random.randint(1000, 1005), 0, 0)
time.sleep(100)
threads = []
for _ in xrange(10):
t = threading.Thread(target=task)
t.daemon = True
t.start()
threads.append(t)
for t in threads:
t.join()
run:
sudo ./pyflame --threads -t python test_setuid.py > /dev/null
Unexpected ptrace(2) exception: waitpid() indicated a WIFSTOPPED process, but got unexpected signal 33
Thanks, this is a very good bug report. I have been working on other projects recently, but I will fix this next time I have some cycles for Pyflame. I imagine this would be a pretty small change if anyone else wants to get a PR in.
I get the same error without using setuid in the following case:
$ cat test.py
import time
import os
print os.getpid()
while True:
time.sleep(1)
In one terminal: python test.py
. In another sudo src/pyflame --threads -p 9699 -s 10
. In the third kill 9699
(alternatively, just ctrl+c the script).
Unexpected ptrace(2) exception: waitpid() indicated a WIFSTOPPED process, but got unexpected signal 15
("signal 2" in case with ctrl+c) Ubuntu 18, latest pyflame, Python 2.7.15rc1
And looks like the signals get caught only by pyflame - the script continues to run.