(linenum→info "unix/slp.c:2238")

glibc/2.7/debug/pcprofile.c

    1: /* Profile PC and write result to FIFO.
    2:    Copyright (C) 1999, 2000 Free Software Foundation, Inc.
    3:    This file is part of the GNU C Library.
    4:    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
    5: 
    6:    The GNU C Library is free software; you can redistribute it and/or
    7:    modify it under the terms of the GNU Lesser General Public
    8:    License as published by the Free Software Foundation; either
    9:    version 2.1 of the License, or (at your option) any later version.
   10: 
   11:    The GNU C Library is distributed in the hope that it will be useful,
   12:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   13:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14:    Lesser General Public License for more details.
   15: 
   16:    You should have received a copy of the GNU Lesser General Public
   17:    License along with the GNU C Library; if not, write to the Free
   18:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   19:    02111-1307 USA.  */
   20: 
   21: #include <errno.h>
   22: #include <fcntl.h>
   23: #include <stdint.h>
   24: #include <stdlib.h>
   25: #include <unistd.h>
   26: #include <libc-internal.h>
   27: 
   28: /* Nonzero if we are actually doing something.  */
   29: static int active;
   30: 
   31: /* The file descriptor of the FIFO.  */
   32: static int fd;
   33: 
   34: 
   35: static void
   36: __attribute__ ((constructor))
   37: install (void)
   38: {
   39:   /* See whether the environment variable `PCPROFILE_OUTPUT' is defined.
   40:      If yes, it should name a FIFO.  We open it and mark ourself as active.  */
   41:   const char *outfile = getenv ("PCPROFILE_OUTPUT");
   42: 
   43:   if (outfile != NULL && *outfile != '\0')
   44:     {
   45:       fd = open (outfile, O_RDWR | O_CREAT, 0666);
   46: 
   47:       if (fd != -1)
   48:         {
   49:           uint32_t word;
   50: 
   51:           active = 1;
   52: 
   53:           /* Write a magic word which tells the reader about the byte
   54:              order and the size of the following entries.  */
   55:           word = 0xdeb00000 | sizeof (void *);
   56:           if (TEMP_FAILURE_RETRY (write (fd, &word, 4)) != 4)
   57:             {
   58:               /* If even this fails we shouldn't try further.  */
   59:               close (fd);
   60:               fd = -1;
   61:               active = 0;
   62:             }
   63:         }
   64:     }
   65: }
   66: 
   67: 
   68: static void
   69: __attribute__ ((destructor))
   70: uninstall (void)
   71: {
   72:   if (active)
   73:     close (fd);
   74: }
   75: 
   76: 
   77: void
   78: __cyg_profile_func_enter (void *this_fn, void *call_site)
   79: {
   80:   void *buf[2];
   81: 
   82:   if (! active)
   83:     return;
   84: 
   85:   /* Now write out the current position and that of the caller.  We do
   86:      this now, and don't cache the because we want real-time output.  */
   87:   buf[0] = this_fn;
   88:   buf[1] = call_site;
   89: 
   90:   write (fd, buf, sizeof buf);
   91: }
   92: /* We don't handle entry and exit differently here.  */
   93: strong_alias (__cyg_profile_func_enter, __cyg_profile_func_exit)
Syntax (Markdown)