में किसी ने कहा कि Wikipedia "ptrace" article में जोड़ा गया है कि लिनक्स पर, एक छेड़छाड़ की प्रक्रिया स्वयं एक और प्रक्रिया को छीन नहीं सकती है। मैं यह निर्धारित करने की कोशिश कर रहा हूं कि (और यदि ऐसा है तो) यह मामला है। नीचे एक सरल कार्यक्रम है जिसे मैंने परीक्षण करने के लिए प्रेरित किया है। मेरा प्रोग्राम विफल रहता है (उप उप प्रक्रिया ठीक से नहीं चलती है) लेकिन मुझे पूरा विश्वास है कि यह मेरी त्रुटि है और कुछ मौलिक नहीं है।एक छिद्रित लिनक्स प्रक्रिया
संक्षेप में प्रारंभिक प्रक्रिया एक कांटे बी जो बारी कांटे में सी की प्रक्रिया। ए अपने बच्चे को बी, बी अपने बच्चे को सी को छेड़छाड़ करता है। एक बार वे सेट अप हो जाने के बाद, सभी तीन प्रक्रियाएं केवल A
, B
, या C
प्रिंट करने के लिए लिखी जाती हैं ताकि प्रत्येक सेकेंड में एक बार स्टडआउट हो सके।
अभ्यास क्या होता है कि एक और बी काम ठीक है, लेकिन सी प्रिंट केवल एक बार और फिर अटक जाती है है। ps -eo pid,cmd,wchan
के साथ जांच सी कर्नेल फ़ंक्शन ptrace_stop
में फंस गया है जबकि शेष hrtimer_nanosleep
में हैं जहां मैं सभी तीनों की अपेक्षा करता हूं।
कभी-कभी तीनों काम करते हैं (इसलिए प्रोग्राम सीएस के साथ-साथ एएस और बीएस प्रिंट करता है), जो मुझे विश्वास दिलाता है कि शुरुआती सेटअप में कुछ दौड़ की स्थिति है।
मेरे अनुमान क्या गलत हो सकता है के रूप में कर रहे हैं: एक देखकर से कोई लेना देना
- कुछ एक
SIGCHLD
संबंधित एकSIGCHLD
देखकर के लिए एक संकेत के साथ क्या करना सी करने के लिए बी, और प्रतीक्षा करें (2) बी से आने वाले दोनों की रिपोर्टिंग (लेकिन दोनों पीड्स में PTRACE_CONT की एक हैकी कॉल चीजों को ठीक नहीं करती है)? - सीबी द्वारा ptraced जाना चाहिए - सी (बी की कॉल ptrace को और न errored है और न ही इस अधिलेखित कर दिया) एक बजाय द्वारा ptrace विरासत में मिला है?
क्या कोई यह पता लगा सकता है कि मैं क्या गलत कर रहा हूं? धन्यवाद।
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
static void a(){
while(1){
printf ("A\n");
fflush(stdout);
sleep(1);
}
}
static void b(){
while(1){
printf ("B\n");
fflush(stdout);
sleep(1);
}
}
static void c(){
while(1){
printf ("C\n");
fflush(stdout);
sleep(1);
}
}
static void sigchld_handler(int sig){
int result;
pid_t child_pid = wait(NULL); // find who send us this SIGCHLD
printf("SIGCHLD on %d\n", child_pid);
result=ptrace(PTRACE_CONT, child_pid, sig, NULL);
if(result) {
perror("continuing after SIGCHLD");
}
}
int main(int argc,
char **argv){
pid_t mychild_pid;
int result;
printf("pidA = %d\n", getpid());
signal(SIGCHLD, sigchld_handler);
mychild_pid = fork();
if (mychild_pid) {
printf("pidB = %d\n", mychild_pid);
result = ptrace(PTRACE_ATTACH, mychild_pid, NULL, NULL);
if(result==-1){
perror("outer ptrace");
}
a();
}
else {
mychild_pid = fork();
if (mychild_pid) {
printf("pidC = %d\n", mychild_pid);
result = ptrace(PTRACE_ATTACH, mychild_pid, NULL, NULL);
if(result==-1){
perror("inner ptrace");
}
b();
}
else {
c();
}
}
return 0;
}
मदद नहीं कर सकता है लेकिन 'ptrace (PTRACE_CONT, child_pid, sig, nULL) 'नोटिस ... आप शायद' ptrace (PTRACE_CONT, child_pid, NULL, sig) '(data = sig) – remram