2012-11-14 9 views
5

मैं 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 बच्चे की प्रक्रिया से निकलने पर अपेक्षित काम करता है।

उत्तर

1

जहाँ तक मैं कह सकता हूं, ptrace प्रति प्रक्रिया केवल एक ट्रैसर की अनुमति देता है। इसका अर्थ यह है कि यदि आप संलग्न करने का प्रयास करते हैं, तो आप PTRACE_ATTACH के साथ इसे आजमा सकते हैं और मजबूर कर सकते हैं, आपको एक त्रुटि प्राप्त होगी, यह बताते हुए कि ptrace निर्दिष्ट प्रक्रिया से अटैच करने में सक्षम नहीं था।

इस प्रकार, आपकी त्रुटि प्रकट होती है क्योंकि आपका धागा बाल प्रक्रिया से जुड़ा नहीं है, और इस तरह, जब आप ptrace पर प्रयास करते हैं, तो यह -ESRCH कोड भेजने में विफल रहता है।

इसके अलावा, आप this post here पर एक नज़र डाल सकते हैं, यह किसी अन्य प्रश्न का उत्तर दे सकता है जो आप इससे अलग हो सकते हैं।

+0

मेरी प्रक्रिया में समर्पित थ्रेड होने में मदद मिली। – petersohn

संबंधित मुद्दे