Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2006, Google Inc.
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions are
      6 // met:
      7 //
      8 //     * Redistributions of source code must retain the above copyright
      9 // notice, this list of conditions and the following disclaimer.
     10 //     * Redistributions in binary form must reproduce the above
     11 // copyright notice, this list of conditions and the following disclaimer
     12 // in the documentation and/or other materials provided with the
     13 // distribution.
     14 //     * Neither the name of Google Inc. nor the names of its
     15 // contributors may be used to endorse or promote products derived from
     16 // this software without specific prior written permission.
     17 //
     18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 
     30 // All functions here are thread-hostile due to file caching unless
     31 // commented otherwise.
     32 
     33 #ifndef _SYSINFO_H_
     34 #define _SYSINFO_H_
     35 
     36 #include <config.h>
     37 
     38 #include <time.h>
     39 #if (defined(_WIN32) || defined(__MINGW32__)) && (!defined(__CYGWIN__) && !defined(__CYGWIN32__))
     40 #include <windows.h>   // for DWORD
     41 #include <TlHelp32.h>  // for CreateToolhelp32Snapshot
     42 #endif
     43 #ifdef HAVE_UNISTD_H
     44 #include <unistd.h>    // for pid_t
     45 #endif
     46 #include <stddef.h>    // for size_t
     47 #include <limits.h>    // for PATH_MAX
     48 #include "base/basictypes.h"
     49 #include "base/logging.h"   // for RawFD
     50 
     51 // This getenv function is safe to call before the C runtime is initialized.
     52 // On Windows, it utilizes GetEnvironmentVariable() and on unix it uses
     53 // /proc/self/environ instead calling getenv().  It's intended to be used in
     54 // routines that run before main(), when the state required for getenv() may
     55 // not be set up yet.  In particular, errno isn't set up until relatively late
     56 // (after the pthreads library has a chance to make it threadsafe), and
     57 // getenv() doesn't work until then.
     58 // On some platforms, this call will utilize the same, static buffer for
     59 // repeated GetenvBeforeMain() calls. Callers should not expect pointers from
     60 // this routine to be long lived.
     61 // Note that on unix, /proc only has the environment at the time the
     62 // application was started, so this routine ignores setenv() calls/etc.  Also
     63 // note it only reads the first 16K of the environment.
     64 extern const char* GetenvBeforeMain(const char* name);
     65 
     66 // This takes as an argument an environment-variable name (like
     67 // CPUPROFILE) whose value is supposed to be a file-path, and sets
     68 // path to that path, and returns true.  Non-trivial for surprising
     69 // reasons, as documented in sysinfo.cc.  path must have space PATH_MAX.
     70 extern bool GetUniquePathFromEnv(const char* env_name, char* path);
     71 
     72 extern int NumCPUs();
     73 
     74 void SleepForMilliseconds(int milliseconds);
     75 
     76 // processor cycles per second of each processor.  Thread-safe.
     77 extern double CyclesPerSecond(void);
     78 
     79 
     80 //  Return true if we're running POSIX (e.g., NPTL on Linux) threads,
     81 //  as opposed to a non-POSIX thread libary.  The thing that we care
     82 //  about is whether a thread's pid is the same as the thread that
     83 //  spawned it.  If so, this function returns true.
     84 //  Thread-safe.
     85 //  Note: We consider false negatives to be OK.
     86 bool HasPosixThreads();
     87 
     88 #ifndef SWIG  // SWIG doesn't like struct Buffer and variable arguments.
     89 
     90 // A ProcMapsIterator abstracts access to /proc/maps for a given
     91 // process. Needs to be stack-allocatable and avoid using stdio/malloc
     92 // so it can be used in the google stack dumper, heap-profiler, etc.
     93 //
     94 // On Windows and Mac OS X, this iterator iterates *only* over DLLs
     95 // mapped into this process space.  For Linux, FreeBSD, and Solaris,
     96 // it iterates over *all* mapped memory regions, including anonymous
     97 // mmaps.  For other O/Ss, it is unlikely to work at all, and Valid()
     98 // will always return false.  Also note: this routine only works on
     99 // FreeBSD if procfs is mounted: make sure this is in your /etc/fstab:
    100 //    proc            /proc   procfs  rw 0 0
    101 class ProcMapsIterator {
    102  public:
    103   struct Buffer {
    104 #ifdef __FreeBSD__
    105     // FreeBSD requires us to read all of the maps file at once, so
    106     // we have to make a buffer that's "always" big enough
    107     static const size_t kBufSize = 102400;
    108 #else   // a one-line buffer is good enough
    109     static const size_t kBufSize = PATH_MAX + 1024;
    110 #endif
    111     char buf_[kBufSize];
    112   };
    113 
    114 
    115   // Create a new iterator for the specified pid.  pid can be 0 for "self".
    116   explicit ProcMapsIterator(pid_t pid);
    117 
    118   // Create an iterator with specified storage (for use in signal
    119   // handler). "buffer" should point to a ProcMapsIterator::Buffer
    120   // buffer can be NULL in which case a bufer will be allocated.
    121   ProcMapsIterator(pid_t pid, Buffer *buffer);
    122 
    123   // Iterate through maps_backing instead of maps if use_maps_backing
    124   // is true.  Otherwise the same as above.  buffer can be NULL and
    125   // it will allocate a buffer itself.
    126   ProcMapsIterator(pid_t pid, Buffer *buffer,
    127                    bool use_maps_backing);
    128 
    129   // Returns true if the iterator successfully initialized;
    130   bool Valid() const;
    131 
    132   // Returns a pointer to the most recently parsed line. Only valid
    133   // after Next() returns true, and until the iterator is destroyed or
    134   // Next() is called again.  This may give strange results on non-Linux
    135   // systems.  Prefer FormatLine() if that may be a concern.
    136   const char *CurrentLine() const { return stext_; }
    137 
    138   // Writes the "canonical" form of the /proc/xxx/maps info for a single
    139   // line to the passed-in buffer. Returns the number of bytes written,
    140   // or 0 if it was not able to write the complete line.  (To guarantee
    141   // success, buffer should have size at least Buffer::kBufSize.)
    142   // Takes as arguments values set via a call to Next().  The
    143   // "canonical" form of the line (taken from linux's /proc/xxx/maps):
    144   //    <start_addr(hex)>-<end_addr(hex)> <perms(rwxp)> <offset(hex)>   +
    145   //    <major_dev(hex)>:<minor_dev(hex)> <inode> <filename> Note: the
    146   // eg
    147   //    08048000-0804c000 r-xp 00000000 03:01 3793678    /bin/cat
    148   // If you don't have the dev_t (dev), feel free to pass in 0.
    149   // (Next() doesn't return a dev_t, though NextExt does.)
    150   //
    151   // Note: if filename and flags were obtained via a call to Next(),
    152   // then the output of this function is only valid if Next() returned
    153   // true, and only until the iterator is destroyed or Next() is
    154   // called again.  (Since filename, at least, points into CurrentLine.)
    155   static int FormatLine(char* buffer, int bufsize,
    156                         uint64 start, uint64 end, const char *flags,
    157                         uint64 offset, int64 inode, const char *filename,
    158                         dev_t dev);
    159 
    160   // Find the next entry in /proc/maps; return true if found or false
    161   // if at the end of the file.
    162   //
    163   // Any of the result pointers can be NULL if you're not interested
    164   // in those values.
    165   //
    166   // If "flags" and "filename" are passed, they end up pointing to
    167   // storage within the ProcMapsIterator that is valid only until the
    168   // iterator is destroyed or Next() is called again. The caller may
    169   // modify the contents of these strings (up as far as the first NUL,
    170   // and only until the subsequent call to Next()) if desired.
    171 
    172   // The offsets are all uint64 in order to handle the case of a
    173   // 32-bit process running on a 64-bit kernel
    174   //
    175   // IMPORTANT NOTE: see top-of-class notes for details about what
    176   // mapped regions Next() iterates over, depending on O/S.
    177   // TODO(csilvers): make flags and filename const.
    178   bool Next(uint64 *start, uint64 *end, char **flags,
    179             uint64 *offset, int64 *inode, char **filename);
    180 
    181   bool NextExt(uint64 *start, uint64 *end, char **flags,
    182                uint64 *offset, int64 *inode, char **filename,
    183                uint64 *file_mapping, uint64 *file_pages,
    184                uint64 *anon_mapping, uint64 *anon_pages,
    185                dev_t *dev);
    186 
    187   ~ProcMapsIterator();
    188 
    189  private:
    190   void Init(pid_t pid, Buffer *buffer, bool use_maps_backing);
    191 
    192   char *ibuf_;        // input buffer
    193   char *stext_;       // start of text
    194   char *etext_;       // end of text
    195   char *nextline_;    // start of next line
    196   char *ebuf_;        // end of buffer (1 char for a nul)
    197 #if (defined(_WIN32) || defined(__MINGW32__)) && (!defined(__CYGWIN__) && !defined(__CYGWIN32__))
    198   HANDLE snapshot_;   // filehandle on dll info
    199   // In a change from the usual W-A pattern, there is no A variant of
    200   // MODULEENTRY32.  Tlhelp32.h #defines the W variant, but not the A.
    201   // We want the original A variants, and this #undef is the only
    202   // way I see to get them.  Redefining it when we're done prevents us
    203   // from affecting other .cc files.
    204 # ifdef MODULEENTRY32  // Alias of W
    205 #   undef MODULEENTRY32
    206   MODULEENTRY32 module_;   // info about current dll (and dll iterator)
    207 #   define MODULEENTRY32 MODULEENTRY32W
    208 # else  // It's the ascii, the one we want.
    209   MODULEENTRY32 module_;   // info about current dll (and dll iterator)
    210 # endif
    211 #elif defined(__MACH__)
    212   int current_image_; // dll's are called "images" in macos parlance
    213   int current_load_cmd_;   // the segment of this dll we're examining
    214 #elif defined(__sun__)     // Solaris
    215   int fd_;
    216   char current_filename_[PATH_MAX];
    217 #else
    218   int fd_;            // filehandle on /proc/*/maps
    219 #endif
    220   pid_t pid_;
    221   char flags_[10];
    222   Buffer* dynamic_buffer_;  // dynamically-allocated Buffer
    223   bool using_maps_backing_; // true if we are looking at maps_backing instead of maps.
    224 };
    225 
    226 #endif  /* #ifndef SWIG */
    227 
    228 // Helper routines
    229 
    230 namespace tcmalloc {
    231 int FillProcSelfMaps(char buf[], int size, bool* wrote_all);
    232 void DumpProcSelfMaps(RawFD fd);
    233 }
    234 
    235 #endif   /* #ifndef _SYSINFO_H_ */
    236