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

Function restoreUserLDPRELOAD

src/dmtcpworker.cpp:60–116  ·  view source on GitHub ↗

NOTE: Please keep this function in sync with its copy at: * dmtcp_nocheckpoint.cpp:restoreUserLDPRELOAD() */

Source from the content-addressed store, hash-verified

58 * dmtcp_nocheckpoint.cpp:restoreUserLDPRELOAD()
59 */
60void
61restoreUserLDPRELOAD()
62{
63 /* A call to setenv() can result in a call to malloc(). The setenv() call may
64 * also grab a low-level libc lock before calling malloc. The malloc()
65 * wrapper, if present, will try to acquire the wrapper lock. This can lead
66 * to a deadlock in the following scenario:
67 *
68 * T1 (main thread): fork() -> acquire exclusive lock
69 * T2 (ckpt thread): setenv() -> acquire low-level libc lock ->
70 * malloc -> wait for wrapper-exec lock.
71 * T1: setenv() -> block on low-level libc lock (held by T2).
72 *
73 * The simpler solution would have been to not call setenv from DMTCP, and
74 * use putenv instead. This would require larger change.
75 *
76 * The solution used here is to set LD_PRELOAD to "" before * user main().
77 * This is as good as unsetting it. Later, the ckpt-thread * can unset it
78 * if it is still NULL, but then there is a possibility of a race between
79 * user code and ckpt-thread.
80 */
81
82 // We have now successfully used LD_PRELOAD to execute prior to main()
83 // Next, hide our value of LD_PRELOAD, in a global variable.
84 // At checkpoint and restart time, we will no longer need our LD_PRELOAD.
85 // We will need it in only one place:
86 // when the user application makes an exec call:
87 // If anybody calls our execwrapper, we will reset LD_PRELOAD then.
88 // EXCEPTION: If anybody directly calls _real_execve with env arg of NULL,
89 // they will not be part of DMTCP computation.
90 // This has the advantage that our value of LD_PRELOAD will always come
91 // before any paths set by user application.
92 // Also, bash likes to keep its own envp, but we will interact with bash only
93 // within the exec wrapper.
94 // NOTE: If the user called exec("ssh ..."), we currently catch this in
95 // src/pugin/dmtcp_ssh.cp:main(), and edit this into
96 // exec("dmtcp_launch ... dmtcp_ssh ..."), and re-execute.
97 // NOTE: If the user called exec("dmtcp_nocheckpoint ..."), we will
98 // reset LD_PRELOAD back to ENV_VAR_ORIG_LD_PRELOAD in dmtcp_nocheckpoint
99 char *preload = getenv("LD_PRELOAD");
100 char *userPreload = getenv(ENV_VAR_ORIG_LD_PRELOAD);
101
102 JASSERT(userPreload == NULL || strlen(userPreload) <= strlen(preload))
103 (preload)(userPreload);
104
105 // Destructively modify environment variable "LD_PRELOAD" in place:
106 preload[0] = '\0';
107 if (userPreload == NULL) {
108 // _dmtcp_unsetenv("LD_PRELOAD");
109 } else {
110 strcat(preload, userPreload);
111
112 // setenv("LD_PRELOAD", userPreload, 1);
113 }
114 JTRACE("LD_PRELOAD") (preload) (userPreload) (getenv(ENV_VAR_HIJACK_LIBS))
115 (getenv(ENV_VAR_HIJACK_LIBS_M32)) (getenv("LD_PRELOAD"));
116}
117

Callers 1

Calls

no outgoing calls

Tested by

no test coverage detected