MCPcopy Create free account
hub / github.com/dmtcp/dmtcp / vfork

Function vfork

src/execwrappers.cpp:233–308  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

231static void* newStackAddr;
232
233extern "C" pid_t
234vfork()
235{
236 JTRACE("Simulating vfork with fork");
237 return fork();
238
239 char dummy;
240 static __typeof__(&vfork) vforkPtr =
241 (__typeof__(&vfork)) dmtcp_dlsym(RTLD_NEXT, "vfork");
242
243 JASSERT (!isPerformingCkptRestart());
244
245 ThreadSync::presuspendEventHookLockLock();
246
247 /* Acquire all locks here. */
248 ThreadSync::acquireLocks();
249
250 ThreadList::vforkSuspendThreads();
251
252 PluginManager::eventHook(DMTCP_EVENT_VFORK_PREPARE, NULL);
253
254 // Save the contents of the current call frame before calling libc:vfork. The
255 // vfork syscall won't return in the parent until the child process has either
256 // exited or exec'd. In both cases, the current call frame on stack will
257 // most-likely get overwritten by the child process. (The call frames below
258 // the current call-frame are expected to be safe as the child process is not
259 // expected to return from the current call frame).
260 // Failure to restore the current call frame in the parent might result in
261 // lost $RBP data that include the return address.
262 //
263 // NOTE: The vfork wrapper in pid_miscwrappers.cpp performs similar
264 // save/restore of the current call frame. This duplication is required in
265 // case we decide to not use the PID plugin.
266 //
267 // TODO: Deduplicate stack save/restore with similar code in
268 // execwrappers.cpp's vfork wrapper.
269 stackStart = &dummy;
270 // Return address is stored at $rbp + sizeof($rbp) + sizeof(void*)
271 stackSize =
272 (char*) __builtin_frame_address(0) + (2 * sizeof(void*)) - stackStart;
273 newStackAddr = JALLOC_MALLOC(stackSize);
274 JASSERT(newStackAddr);
275 memcpy(newStackAddr, stackStart, stackSize);
276
277 vforkPid = vforkPtr();
278
279 // Restore parent stack.
280 if (vforkPid > 0) {
281 memcpy(stackStart, newStackAddr, stackSize);
282 JALLOC_FREE(newStackAddr);
283 }
284
285 ThreadSync::resetLocks(false);
286
287 if (vforkPid == -1) {
288 PluginManager::eventHook(DMTCP_EVENT_VFORK_FAILED, NULL);
289 JTRACE("vfork failed") (vforkPid);
290 } else if (vforkPid == 0) { /* child process */

Callers 1

sn_simple_popen_rFunction · 0.50

Calls 6

dmtcp_dlsymFunction · 0.85
isPerformingCkptRestartFunction · 0.85
eventHookFunction · 0.85
memcpyFunction · 0.85
setCurrentStateFunction · 0.85
forkFunction · 0.70

Tested by

no test coverage detected