root/plugin/pid/virtualpidtable.cpp

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

DEFINITIONS

This source file includes following definitions.
  1. instance
  2. postRestart
  3. refresh
  4. getNewVirtualTid
  5. resetOnFork
  6. updateMapping
  7. realToVirtual
  8. virtualToReal
  9. writeVirtualTidToFileForPtrace
  10. readVirtualTidFromFileForPtrace

   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 the dmtcp/src module of DMTCP (DMTCP:dmtcp/src).  *
   6  *                                                                          *
   7  *  DMTCP:dmtcp/src 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:dmtcp/src 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 <stdlib.h>
  23 #include <string.h>
  24 #include <string>
  25 #include <sstream>
  26 #include <fcntl.h>
  27 #include <sys/syscall.h>
  28 #include "util.h"
  29 #include "pidwrappers.h"
  30 #include "../jalib/jconvert.h"
  31 #include "../jalib/jfilesystem.h"
  32 #include "virtualpidtable.h"
  33 #include "dmtcp.h"
  34 #include "shareddata.h"
  35 
  36 using namespace dmtcp;
  37 
  38 static int _numTids = 1;
  39 
  40 VirtualPidTable::VirtualPidTable()
  41   : VirtualIdTable<pid_t> ("Pid", getpid())
  42 {
  43   //_do_lock_tbl();
  44   //_idMapTable[getpid()] = _real_getpid();
  45   //_idMapTable[getppid()] = _real_getppid();
  46   //_do_unlock_tbl();
  47 }
  48 
  49 static VirtualPidTable *virtPidTableInst = NULL;
  50 VirtualPidTable& VirtualPidTable::instance()
  51 {
  52   if (virtPidTableInst == NULL) {
  53     virtPidTableInst = new VirtualPidTable();
  54   }
  55   return *virtPidTableInst;
  56 }
  57 
  58 void VirtualPidTable::postRestart()
  59 {
  60   VirtualIdTable<pid_t>::postRestart();
  61   _do_lock_tbl();
  62   _idMapTable[getpid()] = _real_getpid();
  63   _do_unlock_tbl();
  64 }
  65 
  66 void VirtualPidTable::refresh()
  67 {
  68   id_iterator i;
  69   id_iterator next;
  70   pid_t _real_pid = _real_getpid();
  71 
  72   JASSERT(getpid() != -1);
  73 
  74   _do_lock_tbl();
  75   for (i = _idMapTable.begin(), next = i; i != _idMapTable.end(); i = next) {
  76     next++;
  77     if (isIdCreatedByCurrentProcess(i->second)
  78         && _real_tgkill(_real_pid, i->second, 0) == -1) {
  79       _idMapTable.erase(i);
  80     }
  81   }
  82   _do_unlock_tbl();
  83   printMaps();
  84 }
  85 
  86 pid_t VirtualPidTable::getNewVirtualTid()
  87 {
  88   pid_t tid;
  89   if (VirtualIdTable<pid_t>::getNewVirtualId(&tid) == false) {
  90     refresh();
  91   }
  92 
  93   JASSERT(VirtualIdTable<pid_t>::getNewVirtualId(&tid))
  94     (_idMapTable.size()) .Text("Exceeded maximum number of threads allowed");
  95 
  96   return tid;
  97 }
  98 
  99 void VirtualPidTable::resetOnFork()
 100 {
 101   VirtualIdTable<pid_t>::resetOnFork(getpid());
 102   _numTids = 1;
 103   _idMapTable[getpid()] = _real_getpid();
 104   refresh();
 105   printMaps();
 106 }
 107 
 108 void VirtualPidTable::updateMapping(pid_t virtualId, pid_t realId)
 109 {
 110   if (virtualId > 0 && realId > 0) {
 111     _do_lock_tbl();
 112     _idMapTable[virtualId] = realId;
 113     _do_unlock_tbl();
 114   }
 115 }
 116 
 117 //to allow linking without ptrace plugin
 118 extern "C" int dmtcp_is_ptracing() __attribute__ ((weak));
 119 
 120 pid_t VirtualPidTable::realToVirtual(pid_t realPid)
 121 {
 122   if (realIdExists(realPid)) {
 123     return VirtualIdTable<pid_t>::realToVirtual(realPid);
 124   }
 125 
 126   _do_lock_tbl();
 127   if (dmtcp_is_ptracing != 0 && dmtcp_is_ptracing() && realPid > 0) {
 128     pid_t virtualPid = readVirtualTidFromFileForPtrace(dmtcp_gettid());
 129     if (virtualPid != -1) {
 130       _do_unlock_tbl();
 131       updateMapping(virtualPid, realPid);
 132       return virtualPid;
 133     }
 134   }
 135 
 136   //JWARNING(false) (realPid)
 137     //.Text("No virtual pid/tid found for the given real pid");
 138   _do_unlock_tbl();
 139   return realPid;
 140 }
 141 
 142 pid_t VirtualPidTable::virtualToReal(pid_t virtualId)
 143 {
 144   if (virtualId == -1) {
 145     return virtualId;
 146   }
 147   pid_t id = (virtualId < -1 ? abs(virtualId) : virtualId);
 148   pid_t retVal = VirtualIdTable<pid_t>::virtualToReal(id);
 149   if (retVal == id) {
 150     retVal = SharedData::getRealPid(id);
 151     if (retVal == -1) {
 152       retVal = id;
 153     }
 154   }
 155   retVal = virtualId < -1 ? -retVal : retVal;
 156   return retVal;
 157 }
 158 
 159 void VirtualPidTable::writeVirtualTidToFileForPtrace(pid_t pid)
 160 {
 161   if (!dmtcp_is_ptracing || !dmtcp_is_ptracing()) {
 162     return;
 163   }
 164   pid_t tracerPid = Util::getTracerPid();
 165   if (tracerPid != 0) {
 166     SharedData::setPtraceVirtualId(tracerPid, pid);
 167   }
 168 }
 169 
 170 pid_t VirtualPidTable::readVirtualTidFromFileForPtrace(pid_t tid)
 171 {
 172   pid_t pid;
 173 
 174   if (!dmtcp_is_ptracing || !dmtcp_is_ptracing()) {
 175     return -1;
 176   }
 177   if (tid == -1) {
 178     tid = Util::getTracerPid();
 179     if (tid == 0) {
 180       return -1;
 181     }
 182   }
 183 
 184   pid = SharedData::getPtraceVirtualId(tid);
 185 
 186   JTRACE("Read virtual Pid/Tid from shared-area") (pid);
 187   return pid;
 188 }

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