root/procselfmaps.cpp

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fd
  2. isValidData
  3. readDec
  4. readHex
  5. getNextArea

   1 /****************************************************************************
   2  *   Copyright (C) 2006-2013 by Jason Ansel, Kapil Arya, and Gene Cooperman *
   3  *   jansel@csail.mit.edu, kapil@ccs.neu.edu, gene@ccs.neu.edu              *
   4  *                                                                          *
   5  *  This file is part of DMTCP.                                             *
   6  *                                                                          *
   7  *  DMTCP is free software: you can redistribute it and/or                  *
   8  *  modify it under the terms of the GNU Lesser General Public License as   *
   9  *  published by the Free Software Foundation, either version 3 of the      *
  10  *  License, or (at your option) any later version.                         *
  11  *                                                                          *
  12  *  DMTCP is distributed in the hope that it will be useful,                *
  13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of          *
  14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
  15  *  GNU Lesser General Public License for more details.                     *
  16  *                                                                          *
  17  *  You should have received a copy of the GNU Lesser General Public        *
  18  *  License along with DMTCP:dmtcp/src.  If not, see                        *
  19  *  <http://www.gnu.org/licenses/>.                                         *
  20  ****************************************************************************/
  21 
  22 #include <fcntl.h>
  23 #include "util.h"
  24 #include "procselfmaps.h"
  25 #include "syscallwrappers.h"
  26 #include "jassert.h"
  27 
  28 using namespace dmtcp;
  29 
  30 
  31 ProcSelfMaps::ProcSelfMaps()
  32   : dataIdx(0),
  33     numAreas(0),
  34     numBytes(0),
  35     fd(-1)
  36 {
  37   char buf[4096];
  38   fd = _real_open("/proc/self/maps", O_RDONLY);
  39   JASSERT(fd != -1) (JASSERT_ERRNO);
  40   ssize_t numRead = 0;
  41 
  42   // Get an approximation of the required buffer size.
  43   do {
  44     numRead = Util::readAll(fd, buf, sizeof(buf));
  45     if (numRead > 0) {
  46       numBytes += numRead;
  47     }
  48   } while (numRead > 0);
  49 
  50   // Now allocate a buffer. Note that this will most likely change the layout
  51   // of /proc/self/maps, so we need to recalculate numBytes.
  52   size_t size = numBytes + 4096; // Add a one page buffer.
  53   data = (char*) JALLOC_HELPER_MALLOC(size);
  54   JASSERT(lseek(fd, 0, SEEK_SET) == 0);
  55 
  56   numBytes = Util::readAll(fd, data, size);
  57   JASSERT(numBytes > 0) (numBytes);
  58 
  59   // TODO(kapil): Replace this assert with more robust code that would
  60   // reallocate the buffer with an extended size.
  61   JASSERT(numBytes < size) (numBytes) (size);
  62 
  63   // TODO(kapil): Validate the read data.
  64   JASSERT(isValidData());
  65 
  66   _real_close(fd);
  67 
  68   for (size_t i = 0; i < numBytes; i++) {
  69     if (data[i] == '\n') {
  70       numAreas++;
  71     }
  72   }
  73 }
  74 
  75 ProcSelfMaps::~ProcSelfMaps()
  76 {
  77   JALLOC_HELPER_FREE(data);
  78   fd = -1;
  79   dataIdx = 0;
  80   numAreas = 0;
  81   numBytes = 0;
  82 }
  83 
  84 bool ProcSelfMaps::isValidData()
  85 {
  86   // TODO(kapil): Add validation check.
  87   return true;
  88 }
  89 
  90 unsigned long int ProcSelfMaps::readDec()
  91 {
  92   unsigned long int v = 0;
  93 
  94   while (1) {
  95     char c = data[dataIdx];
  96     if ((c >= '0') && (c <= '9')) {
  97       c -= '0';
  98     } else {
  99       break;
 100     }
 101     v = v * 10 + c;
 102     dataIdx++;
 103   }
 104   return v;
 105 }
 106 
 107 unsigned long int ProcSelfMaps::readHex()
 108 {
 109   unsigned long int v = 0;
 110 
 111   while (1) {
 112     char c = data[dataIdx];
 113     if ((c >= '0') && (c <= '9')) {
 114       c -= '0';
 115     } else if ((c >= 'a') && (c <= 'f')) {
 116       c -= 'a' - 10;
 117     } else if ((c >= 'A') && (c <= 'F')) {
 118       c -= 'A' - 10;
 119     } else {
 120       break;
 121     }
 122     v = v * 16 + c;
 123     dataIdx++;
 124   }
 125   return v;
 126 }
 127 
 128 int ProcSelfMaps::getNextArea(ProcMapsArea* area)
 129 {
 130   char rflag, sflag, wflag, xflag;
 131 
 132   if (dataIdx >= numBytes || data[dataIdx] == 0) {
 133     return 0;
 134   }
 135 
 136   area->addr = (VA) readHex();
 137   JASSERT(area->addr != NULL);
 138 
 139   JASSERT(data[dataIdx++] == '-');
 140 
 141   area->endAddr = (VA) readHex();
 142   JASSERT(area->endAddr != NULL);
 143 
 144   JASSERT(data[dataIdx++] == ' ');
 145 
 146   JASSERT(area->endAddr >= area->addr);
 147   area->size = area->endAddr - area->addr;
 148 
 149   rflag = data[dataIdx++];
 150   JASSERT((rflag == 'r') || (rflag == '-'));
 151 
 152   wflag = data[dataIdx++];
 153   JASSERT((wflag == 'w') || (wflag == '-'));
 154 
 155   xflag = data[dataIdx++];
 156   JASSERT((xflag == 'x') || (xflag == '-'));
 157 
 158   sflag = data[dataIdx++];
 159   JASSERT((sflag == 's') || (sflag == 'p'));
 160 
 161   JASSERT(data[dataIdx++] == ' ');
 162 
 163   area->offset = readHex();
 164   JASSERT(data[dataIdx++] == ' ');
 165 
 166   area->devmajor = readHex();
 167   JASSERT(data[dataIdx++] == ':');
 168 
 169   area->devminor = readHex();
 170   JASSERT(data[dataIdx++] == ' ');
 171 
 172   area->inodenum = readDec();
 173 
 174   while (data[dataIdx] == ' ') {
 175     dataIdx++;
 176   }
 177 
 178   area -> name[0] = '\0';
 179   if (data[dataIdx] == '/' || data[dataIdx] == '[' || data[dataIdx] == '(') {
 180     // absolute pathname, or [stack], [vdso], etc.
 181     // On some machines, deleted files have a " (deleted)" prefix to the
 182     // filename.
 183     size_t i = 0;
 184     while (data[dataIdx] != '\n') {
 185       area->name[i++] = data[dataIdx++];
 186       JASSERT(i < sizeof(area->name));
 187     }
 188     area -> name[i] = '\0';
 189   }
 190 
 191   JASSERT(data[dataIdx++] == '\n');
 192 
 193   area -> prot = 0;
 194   if (rflag == 'r') {
 195     area -> prot |= PROT_READ;
 196   }
 197   if (wflag == 'w') {
 198     area -> prot |= PROT_WRITE;
 199   }
 200   if (xflag == 'x') {
 201     area -> prot |= PROT_EXEC;
 202   }
 203 
 204   area -> flags = MAP_FIXED;
 205   if (sflag == 's') {
 206     area -> flags |= MAP_SHARED;
 207   }
 208   if (sflag == 'p') {
 209     area -> flags |= MAP_PRIVATE;
 210   }
 211   if (area -> name[0] == '\0') {
 212     area -> flags |= MAP_ANONYMOUS;
 213   }
 214 
 215   return 1;
 216 }

/* [<][>][^][v][top][bottom][index][help] */