title: what's the getpid work procedure in glibc?
body: <p>The situation is as below:</p>
  
  <p>I am trying to do the <a href="https://github.com/jserv/kernel-in-kernel" rel="nofollow noreferrer">project</a> which hacks the kernel in github. Kernel version is linux-3.18.6.</p>
  
  <p>QEMU is used to simulate the environment.</p>
  
  <p>In my application, I try to understand the syscall procedure by follow them.The way to complete my aim is just like the shell program. I just create some commands to run the relative syscall. Maybe it's simple through the picture.
  <a href="https://i.stack.imgur.com/QtVeF.png" rel="nofollow noreferrer">some commands</a></p>
  
  <p>Code is simple as follows:</p>
  
  <p>1 Use API getpid.</p>
  
  <pre><code>int Getpid(int argc, char **argv)
  {
      pid_t pid;
      pid = getpid();
      printf("current process's pid:%d\n",pid);
      return 0;
  }
  </code></pre>
  
  <p>2 Use int $0x80 directly.</p>
  
  <pre><code>int GetpidAsm(int argc, char **argv)
  {
      pid_t pid;
      asm volatile(
      "mov $20, %%eax\n\t"
      "int $0x80\n\t"
      "mov %%eax, %0\n\t"
      :"=m"(pid)
      );
      printf("current process's pid(ASM):%d\n",pid);
      return 0;
  }
  </code></pre>
  
  <p>Because my application just run in the process with pid 1, so every time I type command getpid, it returns 1. Of course that's true.</p>
  
  <p>The weird thing is that when I use gdb to debug the syscall process, it stops at the berakpoint sys_getpid only once when I type getpid to execute. When I do it again and again, it just outputs without stopping.</p>
  
  <p>Obviously, the use of int $0x80 is absolutely correct as I understand.</p>
  
  <p>To fix the problem, I did some research.
  I download the glibc source(glibc-2.25) code to see how the api getpid wraps int $0x80. Unfortunately, it wasn't there or I just didn't find the right position.</p>
  
  <p>some code in glibc.</p>
  
  <pre><code>pid_t getpid(void)
  {
    pid_t (*f)(void);
    f = (pid_t (*)(void)) dlsym (RTLD_NEXT, "getpid");
    if (f == NULL)
      error (EXIT_FAILURE, 0, "dlsym (RTLD_NEXT, \"getpid\"): %s", dlerror ());
    return (pid2 = f()) + 26;
  }
  </code></pre>
  
  <p>If I got the wrong code, please tell me,tks.</p>
  
  <p>As the code indicates, the definition of getpid is not contained in glibc. After read some data, someone said <a href="https://stackoverflow.com/a/12806838/6936134">the VDSO...</a>.</p>
  
  <blockquote>
    <p>Notice that, AFAIK, a significant part of the cost of simple syscalls
    is going from user-space to kernel and back. Hence, for some syscalls
    (probably gettimeofday, getpid ...) the VDSO might avoid even that
    (and technically might avoid doing a real syscall).</p>
  </blockquote>
  
  <p>In the man getpid pgae:</p>
  
  <blockquote>
    <p>C library/kernel differences
           Since  glibc  version  2.3.4,  the  glibc wrapper function for getpid()
           caches PIDs, so as to avoid additional  system  calls  when  a  process
           calls getpid() repeatedly.  Normally this caching is invisible, but its
           correct operation relies  on  support  in  the  wrapper  functions  for
           fork(2),  vfork(2),  and clone(2): if an application bypasses the glibc
           wrappers for these system calls by using syscall(2),  then  a  call  to
           getpid()  in  the  child will return the wrong value (to be precise: it
           will return the PID of the parent process).  See also clone(2) for dis‐
           cussion  of  a case where getpid() may return the wrong value even when
           invoking clone(2) via the glibc wrapper function.</p>
  </blockquote>
  
  <p>Though there exit so many explain, I can't figure out the work procedure of API getpid.</p>
  
  <p>As a contrast, API time is easy to understand.
  The definition of time:</p>
  
  <pre><code>time_t
  time (time_t *t)
  {
    INTERNAL_SYSCALL_DECL (err);
    time_t res = INTERNAL_SYSCALL (time, err, 1, NULL);
    /* There cannot be any error.  */
    if (t != NULL)
      *t = res;
    return res;
  }
  </code></pre>
  
  <p>then,</p>
  
  <pre><code>#define INTERNAL_SYSCALL(name, err, nr, args...)            \
      internal_syscall##nr ("li\t%0, %2\t\t\t# " #name "\n\t",    \
                    "IK" (SYS_ify (name)),            \
                    0, err, args)
  </code></pre>
  
  <p>Finally, it's embedded asm, the normal way to use kernel source.</p>
  
  <pre><code>#define internal_syscall1(v0_init, input, number, err, arg1)        \
  ({                                  \
      long _sys_result;                       \
                                      \
      {                               \
      register long __s0 asm ("$16") __attribute__ ((unused))     \
        = (number);                           \
      register long __v0 asm ("$2");                  \
      register long __a0 asm ("$4") = (long) (arg1);          \
      register long __a3 asm ("$7");                  \
      __asm__ volatile (                      \
      ".set\tnoreorder\n\t"                       \
      v0_init                             \
      "syscall\n\t"                           \
      ".set reorder"                          \
      : "=r" (__v0), "=r" (__a3)                  \
      : input, "r" (__a0)                     \
      : __SYSCALL_CLOBBERS);                      \
      err = __a3;                         \
      _sys_result = __v0;                     \
      }                               \
      _sys_result;                            \
  })
  </code></pre>
  
  <p>Can somebody explain clearly how the API getpid works? Why the getpid just trap into the syscall sys_getpid only once? Some references is admired if possible.</p>
  
  <p>Thanks for your help.</p>