2014-10-17 26 views
5

Sorun bildirimi: bir program C bir döngüden oluşur. Bu programın yürütülmesi, kontrollü sürecin ilerleyişini periyodik olarak gösteren başka bir süreç tarafından kontrol edilmelidir. kill(pid, SIGSTOP),'dan sonra ptrace(PTRACE_PEEKTEXT,pid,...) işlevi C işlemini bulamaz. Okuduklarımdan, pid tarafından tanımlanan işlem durdurulduğunda, ptrace(PTRACE_PEEKTEXT,pid,...) çalışması gerekiyordu.Böyle bir işlem yok - ptrace

Tam olarak neyim eksik olduğumu bilmiyorum, bu nedenle herhangi bir yardım çok takdir edilecektir. Aşağıda şimdiye kadar yapmış budur:

iki süreç, P ve C vardır.

birinci işlem (P) çatal() yoluyla ikinci bir (Cı) oluşturur.

C'nin kod şu şekildedir:

int i = 0; 
int main() { 
    ptrace(PTRACE_TRACEME, 0, NULL, NULL); 
    printf("Memory address = %p", (void *)&i); 
    while(1) { i++;} 
} 

P'nin kod aşağıda:

{...} 
switch (pid = fork()) { 
case 0: /* the child */   
     if (execl("C", "", (char *) NULL) == -1) { 
     perror("execl"); 
    } 
    break; 

case -1: /* Error */ 
    perror("fork"); 
    exit(EXIT_FAILURE); 

default: /* the parent */ 
     sleep(1); 
     kill(pid, SIGSTOP); 
     wait(&status);    
     if (WSTOPSIG(status)==SIGSTOP) { 
       printf("%s","Child was interrupted. Insert memory address\n"); 

      scanf("%p",&address); 
      printf("Address = %p", address);    

      data = ptrace(PTRACE_PEEKTEXT, pid, address,NULL);   
      if(data==-1){ 
       if(errno){ 
       printf("%s\n","Error at PEEKTEXT\n");  
       printf("%s\n",strerror(errno));  
       } 
       if(errno ==  ESRCH){ 
       printf("%s\n","ESRCH error\n");  
       } 
       if(errno == EIO){ 
       printf("%s\n","EIO error\n");  
       } 
      } 
      printf("***Data retrieved is: %ld\n",data); 
      data = ptrace(PTRACE_CONT, pid, 0, 0); 

     }  
     if(WIFEXITED(status)){ 
      printf("[Parent] - Child's exit status is: %d \n", WEXITSTATUS(status)); 
      break; 
     } 
    break;   
} 
{...} 

çıktısı:

C itibaren
  1. : Bellek Adresi = 0x60104c
  2. itibaren P: Çocuk kesildi. Bellek adresi (sonraki C baskılı neyi eklemek)

Adres = 0x60104c

yerleştirin Ve hata geçerli:

Hata PEEKTEXT

Böyle süreç

ESRCH de HATA

*** VERİ alındı s: -1

+2

Benim için Works değişkeni için int kullanarak aldım. Gerekli olanları ekledim ve hem P hem de C'yi derleyen tüm değişkenleri tanımladım ve çalıştı. Komple kod yazılabilir mi? '...' gibi bir yerde bir hatanın olması ihtimali varsa, ör. Bazı değişkenler için yanlış tip, vb? Ayrıca, strace -f -o strace.log./P 'yi çalıştırmayı deneyin ve strace.log'da neyin yazdırıldığını kontrol edin. – afenster

+0

Haklıydınız, konu "..." olarak belirtilmişti. –

cevap

5

Adres değişkeninin doğru türde olduğundan emin olun. void * address ile denedim ve benim için de çalıştı. Hatanı

+0

Sorun bu olmuştu. İmzasız int kullanıyorum :). Teşekkürler! –

+1

Bu olasılık hakkında düşündüm ama emin değildi - doğru tahmin ettiniz. Cevabınıza bir miktar ekleyelim: adresin boyutu (''% p' için '' x86_64 'de 8 bayt'tır, bu yüzden' scanf' bir unsuru 'unsigned int' ('int * 'yerine) yerine okumaya çalıştığında belleğe başka bir değere çöp, ve sizin durumunuzda 'pid' değişkeni - dolayısıyla hata oldu. Farklı bir şekilde tahsis edilmişlerse, ya da herhangi bir hata olmadan bile çalışabilirlerse başka bir değişken olabilir.Yazar ptrace'i çağırmadan önce pid'in değerini yazdıysa, bir çöp bulmuş olurdu ve bir hata bulmuş olurdu. – afenster

+0

Tam açıklamayı bilmiyordum, çok teşekkürler! –