1. binet
  2. mana-core-cxxutils

Commits

calaf  committed 844c3c3

turned procmaps into a pseudo-singleton so that maps can be read only once. At the same time
added support for rereading maps when an address can not be located in loaded entries.

  • Participants
  • Parent commits 5c98bbc
  • Branches default
  • Tags CxxUtils-00-00-14

Comments (0)

Files changed (4)

File ChangeLog

View file
  • Ignore whitespace
+2009-01-23  Paolo Calafiura
+	* Tagging CxxUtils-00-00-14
+        * turned procmaps into a "pseudo-singleton" so that maps can be read only once. At the same time
+	added support for rereading maps when an address can not be located in loaded entries.
+
 2009-01-23  Paolo Calafiura
 	* Tagging CxxUtils-00-00-13
         * new class procmaps and its test

File CxxUtils/procmaps.h

View file
  • Ignore whitespace
 #ifndef PROCMAPS_H 
 #define PROCMAPS_H 1
+#include <boost/pool/pool_alloc.hpp>
 #include <vector>
 /** @class procmaps 
  * @brief A simple API to access /proc/self/maps info
  *
  * @author Paolo Calafiura - LBNL, ATLAS Collaboration
- * $Id: procmaps.h,v 1.1 2009-01-23 23:57:27 calaf Exp $
+ * $Id: procmaps.h,v 1.2 2009-01-27 01:04:18 calaf Exp $
  **/
 class procmaps {
 public:
     bool executable;
     bool isPrivate; ///=true page is private(COW), =false page is shared
     unsigned int offset;
-    unsigned short dev[2]; /// dev[0] major, dev[1] minor
+    unsigned int dev[2]; /// dev[0] major, dev[1] minor
     unsigned int inode;
     char pathname[32];  ///truncated if needed
   };
 
-  procmaps(bool dump=false);
+  procmaps(size_t entries=1024);
   //not yet  procmaps(int pid);
 
-  typedef std::vector<Entry> procmaps_t;
+  typedef std::vector<Entry, boost::pool_allocator<Entry> > procmaps_t;
   typedef procmaps_t::const_iterator const_iterator;
   
   ///main entry point: get info for the page range containing address
-  const Entry* getEntry(const void* address) const;
+  /// by default tries to reload /proc/self/maps when address is not found
+  const Entry* getEntry(const void* address, bool tryReloadMaps=true);
 
   ///access underlying entries
-  const procmaps_t& pmaps() const { return m_pmaps; }
+  static const procmaps_t& pmaps() { return s_pmaps; }
   const_iterator begin() const { return pmaps().begin(); }
   const_iterator end() const { return pmaps().end(); }
 
   void loadMaps(bool dump=false); 
 
 private:
-  procmaps_t m_pmaps;
+  static bool s_pmapsLoaded;
+  static procmaps_t s_pmaps;
 };
 
 inline

File src/procmaps.cxx

View file
  • Ignore whitespace
 #include <cstdio>
 #include <cstdlib>
 #include "CxxUtils/procmaps.h"
-procmaps::Entry::Entry(const char* procMapsLine) 
+bool procmaps::s_pmapsLoaded(false);
+procmaps::procmaps_t procmaps::s_pmaps;
+procmaps::Entry::Entry(const char* procMapsLine) :
+  begAddress(0),endAddress(0),
+  readable(false), writable(false), executable(false), isPrivate(false),
+  offset(0), inode(0)
 {
+  dev[0]=0; dev[1]=0;
+  memset(pathname,' ',31);
   char pageProts[5];
+  memset(pageProts,' ', 4);
   sscanf(procMapsLine,
-	 "%8x-%8x %4s %x %2x:%2x %i %31s",
+	 "%8x-%8x %4s %x %2x:%2x %x %31s",
 	 &this->begAddress,
 	 &this->endAddress,
 	 &pageProts,
 	 &this->inode,
 	 &this->pathname
 	 );
+  //  printf("pageProts %s pathname <%s> \n", pageProts, pathname);
   this->readable = (pageProts[0] == 'r');
   this->writable = (pageProts[1] == 'w');
   this->executable = (pageProts[2] == 'x');
   this->isPrivate  = (pageProts[3] == 'p');
 }
 
-procmaps::procmaps(bool dump) {
-  loadMaps(dump);
+procmaps::procmaps(size_t entries) {
+  if (!s_pmapsLoaded) {
+     procmaps::s_pmaps.reserve(entries);
+     loadMaps();
+     s_pmapsLoaded=true;
+   }
 }
 
 void 
 procmaps::loadMaps(bool dump) {
+  procmaps::s_pmaps.clear();
   FILE* fp = fopen("/proc/self/maps", "r");
   if (fp) {
     char* line=0;
     size_t len=0;
     while (getline(&line, &len, fp)>0) {
       if (dump) printf("%s",line);
-      this->m_pmaps.push_back(Entry(line));
+      procmaps::s_pmaps.push_back(Entry(line));
       free(line);
       line=0;
     }
+    free(line);
     fclose(fp);
   }
 }
 
 const procmaps::Entry*
-procmaps::getEntry(const void * address) const {
+procmaps::getEntry(const void * address, bool refreshMaps) {
   //FIXME slow linear search. We'll make it faster...
   const_iterator i(this->begin()), e(this->end());
   bool found(false), done(false);
-  unsigned int toMatch((unsigned int)address);
+  long toMatch((long)address);
   while (!done && !found && i!=e) {
+    //    printf(" begAddress %x toMatch %x endAddress %x\n", i->begAddress, toMatch, i->endAddress);
     found = i->begAddress <= toMatch && toMatch <= i->endAddress; 
     done = !found && toMatch < i->begAddress; //entries sorted by begAddress
     if (!found && !done) ++i;
   }
-  return (found ? &*i : 0) ;
+  if (!found && refreshMaps) loadMaps();
+  //if ! found recurse once by calling getEntry with refreshMaps false
+  return (found ? &*i : getEntry(address,false)) ;
 }

File test/procmaps_test.cxx

View file
  • Ignore whitespace
   assert(pHeapEntry->writable);
   assert(0 == pHeapEntry->inode);
 
-
+  delete pi;
   cout << "*** procmaps_test OK ***" <<endl;
   return 0;
 }