title: Why is my ptrace failing?
body: <p>I am playing with ptrace. I have one simple program that loads up a shared library I built and then calls two functions in it. Both the shared library and the main program have a few calls to sleep() to give me time to attach.</p>
  
  <p>When the program runs, I cat /proc/[pid]/maps to figure out where the shared object's memory is. I want to dump the contents of the loaded text section (or any other section of my choosing.</p>
  
  <p>In the ptrace program, I attach, wait for a stop, and then attempt to PTRACE_PEEKDATA to read the memory. [Fixed by update below] The problem is, I am always getting an EIO error. Why is this happening? The process clearly exists, and if I ps it, I can see it in a 't' state-- being stopped by the trace.</p>
  
  <p>Update: ESRCH error fixed (was missing parameters in ptrace call). I am now getting an EIO error instead whenever it tries to read. Why is this happening? The call to ptrace(PTRACE_PEEKDATA...) seems correct and the memory addresses are on page aligned boundaries. </p>
  
  <p>Main program (to be traced). Compile with -ldl</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;dlfcn.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;unistd.h&gt;
  
  typedef int (*Add_t)(int, int);
  typedef int (*Mul_t)(int, int);
  
  #define LIB_PATH "./libmylib.so"
  
  int main()
  {
      void *pHandle = NULL;
      Mul_t pfnMultiply = NULL;
      Add_t pfnAdd = NULL;
      int a = 5, b = 10;
      int i=0;
  
      printf("My pid: %u\n", getpid());
  
      pHandle = dlopen(LIB_PATH, RTLD_NOW);
  
      if (pHandle == NULL)
      {
          printf("Did not find library!\n");
          return -1;
      }
  
      pfnMultiply = dlsym(pHandle, "Mul");
      if (pfnMultiply == NULL)
      {
          printf("Could not find multiply symbol");
          return -1;
      }
  
      pfnAdd = dlsym(pHandle, "Add");
      if (pfnAdd == NULL)
      {
          printf("Could not find add symbol");
          return -1;
      }
  
      printf("add function address: %p, function pointer address: %x\n", pfnAdd, &amp;pfnAdd);
      printf("mul function address: %p, function pointer address: %x\n", pfnMultiply, &amp;pfnMultiply);
  
      printf("a + b = %d\n", pfnAdd(a, b));
      printf("a * b = %d\n", pfnMultiply(a, b));
  
      fflush(stdout);
  
      for (i=0; i &lt; 120; i++)
      {
          if (i % 10 == 0) { printf("sleeping: %d of %d\n", i, 120); }
          fflush(stdout);
          sleep(1);
      }
  
      printf("done!\n");
      return 0;
  }
  </code></pre>
  
  <p>Library. Compile with -shared -fPIC </p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;dlfcn.h&gt;
  #include &lt;unistd.h&gt;
  
  volatile void *pFunc = 0xAAAAAAAA;
  volatile void *pFunc2 = 0xBBBBBBBB;
  
  int Add(int a, int b)
  {
      printf("sleeping 200...\n");
      sleep(200);
      return a + b;
  }
  
  int Mul(int a, int b)
  {
      return a*b;
  }
  </code></pre>
  
  <p>Tracer</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;sys/ptrace.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;string.h&gt;
  #include &lt;errno.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;sys/wait.h&gt;
  
  int main(int argc, char **argv)
  {
      unsigned int pid = (unsigned int)atoi(argv[1]);
      unsigned long long searchStart = strtoull(argv[2], NULL, 16);
      long long searchEnd = strtoull(argv[3], NULL, 16);
      long long pos = searchStart;
      int status = 0;
  
  
  
      printf("Attaching to pid: %d\n", pid);
  
      if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1)
      {
          printf("Ptrace attach failed. Error: %s\n", strerror(errno));
          return -1;
      }
      printf("Attached\n");
  
      printf("Waiting for pid to stop\n");
      while (1)
      {
          if (waitpid(pid, &amp;status, 0) == -1)
          {
              printf("Waitpid failed. Error: %s\n", strerror(errno));
              return -1;
          }
  
          if (WIFSTOPPED(status))
          {
              printf("stopped...\n");
              if (WSTOPSIG(status) == SIGSTOP)
              {
                  printf("Got SIGSTOP\n");
                  break;
              }
              else
              {
                  printf("Did not get SIGSTOP");
                  ptrace(PTRACE_CONT, pid, 0, WSTOPSIG(status));
              }
          }
      }
  
      printf("Process stopped\n");
  
      unsigned long long value = 0;
  
      printf("Looking at pos: %llx\n", pos);
      value = ptrace(PTRACE_PEEKDATA, pid, (void *)&amp;pos, NULL);
      if (value = -1)
      { 
          printf("Error reading data\n"); 
      }
      else
      {
          printf("Value: %llu\n", value);
      }
  
      for (pos; pos &lt; searchEnd; pos++) 
      {
          long value = 0;
          errno = 0;
          value = ptrace(PTRACE_PEEKDATA, pid, (void *)&amp;pos, NULL);
  
          if (errno != 0 &amp;&amp; value == -1)
          {
              switch(errno)
              {
                  case EBUSY:
                      printf("EBUSY\n");
                      break;
                  case EFAULT:
                      printf("EFAULT\n");
                      break;
                  case EINVAL:
                      printf("EINVAL\n");
                      break;
                  case EIO:
                      printf("EIO\n");
                      break;
                  case EPERM:
                      printf("EPERM\n");
                      break;
                  case ESRCH:
                      printf("ESRCH\n");
                      break;
              }
              printf("Error: %s\n", strerror(errno));
              break;
          }
  
          if (value != 0 &amp;&amp; value != 0xffffffffffffffff)
          {
              printf("%llx: %llx\n", pos, value);
          }
      }
  
      printf("done\n");
  
      sleep(800);
      return 0;
  }
  </code></pre>
  
  <p>Output</p>
  
  <pre><code>user@machine:~/projects/scratch/x86$ ./call
  My pid: 30776
  add function address: 0x7f371292a805, function pointer address: e87569e8
  mul function address: 0x7f371292a862, function pointer address: e87569e0
  Me: 0x7f371292a805
  sleeping 200...
  a + b = 15
  a * b = 50
  sleeping: 0 of 120
  sleeping: 10 of 120
  sleeping: 20 of 120
  sleeping: 30 of 120
  sleeping: 40 of 120
  sleeping: 50 of 120
  sleeping: 60 of 120
  sleeping: 70 of 120
  sleeping: 80 of 120
  sleeping: 90 of 120
  sleeping: 100 of 120
  sleeping: 110 of 120
  done!
  
  While that program is running...
  
  user@machine:~/projects/scratch$ cat /proc/30776/maps | grep lib
  7f371292a000-7f371292b000 r-xp 00000000 00:5c 14136507                   /home/user/projects/scratch/x86/libmylib.so
  7f371292b000-7f3712b2a000 ---p 00001000 00:5c 14136507                   /home/user/projects/scratch/x86/libmylib.so
  7f3712b2a000-7f3712b2b000 r--p 00000000 00:5c 14136507                   /home/user/projects/scratch/x86/libmylib.so
  7f3712b2b000-7f3712b2c000 rw-p 00001000 00:5c 14136507                   /home/user/projects/scratch/x86/libmylib.so
  7f3712b2c000-7f3712ce7000 r-xp 00000000 08:01 4200143                    /lib/x86_64-linux-gnu/libc-2.19.so
  7f3712ce7000-7f3712ee7000 ---p 001bb000 08:01 4200143                    /lib/x86_64-linux-gnu/libc-2.19.so
  7f3712ee7000-7f3712eeb000 r--p 001bb000 08:01 4200143                    /lib/x86_64-linux-gnu/libc-2.19.so
  7f3712eeb000-7f3712eed000 rw-p 001bf000 08:01 4200143                    /lib/x86_64-linux-gnu/libc-2.19.so
  7f3712ef2000-7f3712ef5000 r-xp 00000000 08:01 4200131                    /lib/x86_64-linux-gnu/libdl-2.19.so
  7f3712ef5000-7f37130f4000 ---p 00003000 08:01 4200131                    /lib/x86_64-linux-gnu/libdl-2.19.so
  7f37130f4000-7f37130f5000 r--p 00002000 08:01 4200131                    /lib/x86_64-linux-gnu/libdl-2.19.so
  7f37130f5000-7f37130f6000 rw-p 00003000 08:01 4200131                    /lib/x86_64-linux-gnu/libdl-2.19.so
  7f37130f6000-7f3713119000 r-xp 00000000 08:01 4200137                    /lib/x86_64-linux-gnu/ld-2.19.so
  7f3713318000-7f3713319000 r--p 00022000 08:01 4200137                    /lib/x86_64-linux-gnu/ld-2.19.so
  7f3713319000-7f371331a000 rw-p 00023000 08:01 4200137                    /lib/x86_64-linux-gnu/ld-2.19.so
  
  
  user@machine:~/projects/scratch$ ./trace 30776 0x7f371292a000 0x7f371292b000
  Attaching to pid: 30776
  Ptrace attach failed. Error: Operation not permitted
  user@machine:~/projects/scratch$ sudo bash
  root@machine:~/projects/scratch# ./trace 30776 0x7f371292a000 0x7f371292b000
  Attaching to pid: 30776
  Attached
  Waiting for pid to stop
  stopped...
  Got SIGSTOP
  Process stopped
  Looking at pos: 7f371292a000
  Value: 0
  ESRCH
  Error: No such process
  done
  </code></pre>