/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- instance
- postRestart
- refresh
- getNewVirtualTid
- resetOnFork
- updateMapping
- realToVirtual
- virtualToReal
- writeVirtualTidToFileForPtrace
- 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 }