【问题标题】:No such process - ptrace没有这样的过程 - ptrace
【发布时间】:2014-12-13 11:29:28
【问题描述】:

问题陈述:一个程序C由一个循环组成。该程序的执行必须由另一个进程控制,该进程将定期显示受控进程的进度。在kill(pid, SIGSTOP), 之后,函数ptrace(PTRACE_PEEKTEXT,pid,...) 不再找到C 进程。根据我的阅读,ptrace(PTRACE_PEEKTEXT,pid,...) 应该在pid 标识的进程停止时工作。

我不知道我到底错过了什么,所以任何帮助将不胜感激。以下是我到目前为止所做的:

有两个进程,PC

第一个进程 (P) 通过 fork() 创建第二个进程 (C)。

C的代码是这样的:

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

P的代码如下:

{...}
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;        
} 
{...}

输出是:

  1. 来自 C:内存地址 = 0x60104c
  2. 来自 P:孩子被打断了。插入内存地址(接下来我插入C打印的)

地址 = 0x60104c

错误是:

PEEKTEXT 出错

没有这个过程

ESRCH 错误

***检索到的数据是:-1

【问题讨论】:

  • 为我工作。我添加了必要的包含并定义了所有变量,编译了 P 和 C 并且它起作用了。您可以发布可以编译的完整代码吗?任何可能在... 的某个地方出现错误的机会,例如某些变量的类型不正确等?另外,尝试运行strace -f -o strace.log ./p 并检查strace.log 中打印的内容。
  • 你说得对,正如@roxana_roman 提到的,问题出在...

标签: c linux process fork ptrace


【解决方案1】:

确保地址变量的类型正确。我试过void * address,它也对我有用。我使用int 作为地址变量得到了你的错误

【讨论】:

  • 这就是问题所在。我正在使用unsigned int :)。谢谢!
  • 考虑过这种可能性,但不确定——很酷,你猜对了。会给你的答案增加一点:地址的大小(对于%p)在x86_64上是8个字节,所以当scanf试图将一个值读入unsigned int(而不是int *)时,它只会给一些垃圾内存中的其他值,在您的情况下,它是 pid 变量 - 因此出现错误。如果它们的分配方式不同,它可能是其他一些变量,或者它甚至可以在没有任何错误的情况下工作。如果作者在调用ptrace 之前打印了pid 的值,他会看到一些垃圾并发现错误。
【解决方案2】:

waitpid 与以下选项一起使用:

waitpid(pid, &status, WUNTRACED | WCONTINUED)

【讨论】:

    猜你喜欢
    • 2014-04-12
    • 1970-01-01
    • 1970-01-01
    • 2020-02-01
    • 2019-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-12
    相关资源
    最近更新 更多