मैं ptrace
का उपयोग करना चाहता हूं यह जांचने के लिए कि कौन सा सिस्टम मेरे प्रोग्राम द्वारा प्रोग्राम किए गए प्रोग्राम को कॉल करता है। मैंने this tutorial से शुरू किया क्योंकि इसे मेरे previous question के उत्तर में समझाया गया था। मैं मंच मैं उपयोग कर रहा हूँ करने के लिए यह अनुकूल कोड को संशोधित (SLES 11 64 बिट), और साथ में निम्नलिखित परीक्षण कोड है कि हर प्रणाली बाहर प्रिंट फोन पैदा की प्रक्रिया बनाता है डाल:मल्टीथ्रेडेड अनुप्रयोगों से ptrace का उपयोग
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/reg.h>
#include <sys/syscall.h> /* For SYS_write etc */
pid_t child;
void run()
{
long orig_eax;
int status;
while(1) {
int pid = wait(&status);
if (pid == -1) {
perror("wait");
kill(child, SIGKILL);
return;
}
printf("Got event from %d.\n", pid);
if(WIFEXITED(status))
break;
orig_eax = ptrace(PTRACE_PEEKUSER,
pid, 8 * ORIG_RAX, NULL);
if (orig_eax == -1) {
perror("ptrace");
kill(child, SIGKILL);
return;
} else {
printf("Syscall %ld called.\n", orig_eax);
}
ptrace(PTRACE_SYSCALL,
pid, NULL, NULL);
}
}
int main(int /*argc*/, char* argv[])
{
child = fork();
if(child == 0) {
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
execl(argv[1], argv[1], NULL);
}
else {
printf("Child process id = %d.\n", child);
run();
}
return 0;
}
यह बहुत अच्छी तरह से काम करता है : यह प्रोग्राम द्वारा बनाई गई सिस्टम कॉल की आईडी प्रिंट करता है (वास्तव में यह दो बार प्रिंट करता है, एक बार प्रवेश पर और एक बार बाहर निकलने के लिए, लेकिन इससे कोई फर्क नहीं पड़ता)। हालांकि, मेरे कार्यक्रम को सिस्टम कॉल की जांच करने के अलावा अन्य चीजों को करने की ज़रूरत है, इसलिए मैंने जांच को अलग थ्रेड पर ले जाने का फैसला किया (मैं सी से सी ++ के साथ अधिक आरामदायक हूं, इसलिए मैंने इसे सी ++ तरीके से किया, लेकिन मैं महत्वपूर्ण मत सोचो)। बेशक इस कार्यक्रम में, मैं केवल धागा शुरू करता हूं और फिर इसमें शामिल होता हूं।
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/reg.h>
#include <sys/syscall.h> /* For SYS_write etc */
#include <boost/thread.hpp>
pid_t child;
void run()
{
long orig_eax;
int status;
while(1) {
int pid = wait(&status);
if (pid == -1) {
perror("wait");
kill(child, SIGKILL);
return;
}
printf("Got event from %d.\n", pid);
if(WIFEXITED(status))
break;
orig_eax = ptrace(PTRACE_PEEKUSER,
pid, 8 * ORIG_RAX, NULL);
if (orig_eax == -1) {
perror("ptrace");
kill(child, SIGKILL);
return;
} else {
printf("Syscall %ld called.\n", orig_eax);
}
ptrace(PTRACE_SYSCALL,
pid, NULL, NULL);
}
}
int main(int /*argc*/, char* argv[])
{
child = fork();
if(child == 0) {
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
execl(argv[1], argv[1], NULL);
}
else {
printf("Child process id = %d.\n", child);
boost::thread t(run);
t.join();
}
return 0;
}
इस बार मैं एक त्रुटि संदेश मिलता है:
Child process id = 24682.
Got event from 24682.
ptrace: No such process
ऐसा क्यों है? मैंने जवाब खोजने की कोशिश की लेकिन मुझे ऐसा कुछ नहीं मिला। मैंने पाया कि ptrace
बच्चे की प्रक्रिया द्वारा शुरू किए गए धागे का पता नहीं लगाएगा, लेकिन बाद में इसे एक और चीज़ से निपटने की जरूरत है। क्या एक अलग थैरड से बाल प्रक्रिया की जांच करना भी संभव है?
दूसरी अजीब चीज यह है कि मेरे असली आवेदन में मैं मूल रूप से वही बात करता हूं (लेकिन एक अधिक जटिल संदर्भ से: वर्ग, म्यूटेक्स इत्यादि), और मुझे एक अलग तरह की त्रुटि मिलती है। ptrace
त्रुटि के साथ लौटने के बजाय, wait
बच्चे की प्रक्रिया पर सिस्टम कॉल के लिए भी वापस नहीं आता है (और बाल प्रक्रिया भी रुकती नहीं है)। दूसरी ओर, wait
बच्चे की प्रक्रिया से निकलने पर अपेक्षित काम करता है।
मेरी प्रक्रिया में समर्पित थ्रेड होने में मदद मिली। – petersohn