Skip to content

Commit fe45835

Browse files
author
Alexey Semenyuk
committedNov 15, 2021
8274856: Failing jpackage tests with fastdebug/release build
Reviewed-by: almatvee, herrick
1 parent 9046077 commit fe45835

File tree

8 files changed

+258
-46
lines changed

8 files changed

+258
-46
lines changed
 

‎src/jdk.jpackage/linux/native/applauncher/LinuxLauncher.c

+119-6
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929
#include <dlfcn.h>
3030
#include <errno.h>
3131
#include <linux/limits.h>
32+
#include <sys/wait.h>
3233
#include <unistd.h>
34+
#include <stddef.h>
3335
#include <libgen.h>
3436
#include "JvmLauncher.h"
3537
#include "LinuxPackage.h"
@@ -43,7 +45,7 @@ static int appArgc;
4345
static char **appArgv;
4446

4547

46-
static JvmlLauncherData* initJvmlLauncherData(void) {
48+
static JvmlLauncherData* initJvmlLauncherData(int* size) {
4749
char* launcherLibPath = 0;
4850
void* jvmLauncherLibHandle = 0;
4951
JvmlLauncherAPI_GetAPIFunc getApi = 0;
@@ -86,7 +88,7 @@ static JvmlLauncherData* initJvmlLauncherData(void) {
8688
goto cleanup;
8789
}
8890

89-
result = jvmLauncherCreateJvmlLauncherData(api, jvmLauncherHandle);
91+
result = jvmLauncherCreateJvmlLauncherData(api, jvmLauncherHandle, size);
9092
/* Handle released in jvmLauncherCreateJvmlLauncherData() */
9193
jvmLauncherHandle = 0;
9294

@@ -131,18 +133,129 @@ static int launchJvm(JvmlLauncherData* cfg) {
131133
}
132134

133135

136+
static void closePipeEnd(int* pipefd, int idx) {
137+
if (pipefd[idx] >= 0) {
138+
close(pipefd[idx]);
139+
pipefd[idx] = -1;
140+
}
141+
}
142+
143+
144+
static void initJvmlLauncherDataPointers(void* baseAddress,
145+
JvmlLauncherData* jvmLauncherData) {
146+
ptrdiff_t offset = (char*)jvmLauncherData - (char*)baseAddress;
147+
int i;
148+
149+
jvmLauncherData->jliLibPath += offset;
150+
jvmLauncherData->jliLaunchArgv =
151+
(char**)((char*)jvmLauncherData->jliLaunchArgv + offset);
152+
jvmLauncherData->envVarNames =
153+
(char**)((char*)jvmLauncherData->envVarNames + offset);
154+
jvmLauncherData->envVarValues =
155+
(char**)((char*)jvmLauncherData->envVarValues + offset);
156+
157+
for (i = 0; i != jvmLauncherData->jliLaunchArgc; i++) {
158+
jvmLauncherData->jliLaunchArgv[i] += offset;
159+
}
160+
161+
for (i = 0; i != jvmLauncherData->envVarCount; i++) {
162+
jvmLauncherData->envVarNames[i] += offset;
163+
jvmLauncherData->envVarValues[i] += offset;
164+
}
165+
}
166+
167+
134168
int main(int argc, char *argv[]) {
169+
int pipefd[2];
170+
pid_t cpid;
135171
int exitCode = STATUS_FAILURE;
136-
JvmlLauncherData* jvmLauncherData;
172+
JvmlLauncherData* jvmLauncherData = 0;
173+
int jvmLauncherDataBufferSize = 0;
137174

138175
appArgc = argc;
139176
appArgv = argv;
140177

141-
jvmLauncherData = initJvmlLauncherData();
142-
if (jvmLauncherData) {
178+
if (pipe(pipefd) == -1) {
179+
JP_LOG_ERRNO;
180+
return exitCode;
181+
}
182+
183+
cpid = fork();
184+
if (cpid == -1) {
185+
JP_LOG_ERRNO;
186+
} else if (cpid == 0) /* Child process */ {
187+
/* Close unused read end */
188+
closePipeEnd(pipefd, 0);
189+
190+
jvmLauncherData = initJvmlLauncherData(&jvmLauncherDataBufferSize);
191+
if (jvmLauncherData) {
192+
/* Buffer size */
193+
if (write(pipefd[1], &jvmLauncherDataBufferSize,
194+
sizeof(jvmLauncherDataBufferSize)) == -1) {
195+
JP_LOG_ERRNO;
196+
goto cleanup;
197+
}
198+
if (jvmLauncherDataBufferSize) {
199+
/* Buffer address */
200+
if (write(pipefd[1], &jvmLauncherData,
201+
sizeof(jvmLauncherData)) == -1) {
202+
JP_LOG_ERRNO;
203+
goto cleanup;
204+
}
205+
/* Buffer data */
206+
if (write(pipefd[1], jvmLauncherData,
207+
jvmLauncherDataBufferSize) == -1) {
208+
JP_LOG_ERRNO;
209+
goto cleanup;
210+
}
211+
}
212+
}
213+
214+
exitCode = 0;
215+
} else if (cpid > 0) {
216+
void* baseAddress = 0;
217+
218+
/* Close unused write end */
219+
closePipeEnd(pipefd, 1);
220+
221+
if (read(pipefd[0], &jvmLauncherDataBufferSize,
222+
sizeof(jvmLauncherDataBufferSize)) == -1) {
223+
JP_LOG_ERRNO;
224+
goto cleanup;
225+
}
226+
227+
if (jvmLauncherDataBufferSize == 0) {
228+
JP_LOG_ERRNO;
229+
goto cleanup;
230+
}
231+
232+
if (read(pipefd[0], &baseAddress, sizeof(baseAddress)) == -1) {
233+
JP_LOG_ERRNO;
234+
goto cleanup;
235+
}
236+
237+
jvmLauncherData = malloc(jvmLauncherDataBufferSize);
238+
if (!jvmLauncherData) {
239+
JP_LOG_ERRNO;
240+
goto cleanup;
241+
}
242+
243+
if (read(pipefd[0], jvmLauncherData,
244+
jvmLauncherDataBufferSize) == -1) {
245+
JP_LOG_ERRNO;
246+
goto cleanup;
247+
}
248+
249+
closePipeEnd(pipefd, 0);
250+
wait(NULL); /* Wait child process to terminate */
251+
252+
initJvmlLauncherDataPointers(baseAddress, jvmLauncherData);
143253
exitCode = launchJvm(jvmLauncherData);
144-
free(jvmLauncherData);
145254
}
146255

256+
cleanup:
257+
closePipeEnd(pipefd, 0);
258+
closePipeEnd(pipefd, 1);
259+
free(jvmLauncherData);
147260
return exitCode;
148261
}

‎src/jdk.jpackage/linux/native/libapplauncher/LinuxLauncherLib.cpp

+2-10
Original file line numberDiff line numberDiff line change
@@ -113,17 +113,9 @@ void launchApp() {
113113
launchInfo = (tstrings::any() << thisHash).str();
114114
}
115115

116-
JP_TRY;
117-
if (0 != setenv(_JPACKAGE_LAUNCHER.c_str(), launchInfo.c_str(), 1)) {
118-
JP_THROW(tstrings::any() << "setenv(" << _JPACKAGE_LAUNCHER
119-
<< ", " << launchInfo << ") failed. Error: " << lastCRTError());
120-
} else {
121-
LOG_TRACE(tstrings::any() << "Set "
122-
<< _JPACKAGE_LAUNCHER << "=[" << launchInfo << "]");
123-
}
124-
JP_CATCH_ALL;
125-
126116
jvmLauncher = appLauncher.createJvmLauncher();
117+
118+
jvmLauncher->addEnvVariable(_JPACKAGE_LAUNCHER, launchInfo);
127119
}
128120

129121
} // namespace

‎src/jdk.jpackage/share/native/applauncher/AppLauncher.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -130,15 +130,15 @@ Jvm* AppLauncher::createJvmLauncher() const {
130130
PropertyName::arguments, args);
131131
}
132132

133+
std::unique_ptr<Jvm> jvm(new Jvm());
134+
133135
if (!libEnvVariableContainsAppDir()) {
134-
SysInfo::setEnvVariable(libEnvVarName, SysInfo::getEnvVariable(
136+
(*jvm).addEnvVariable(libEnvVarName, SysInfo::getEnvVariable(
135137
std::nothrow, libEnvVarName)
136138
+ FileUtils::pathSeparator
137139
+ appDirPath);
138140
}
139141

140-
std::unique_ptr<Jvm> jvm(new Jvm());
141-
142142
(*jvm)
143143
.setPath(findJvmLib(cfgFile, defaultRuntimePath, jvmLibNames))
144144
.addArgument(launcherPath);

‎src/jdk.jpackage/share/native/applauncher/JvmLauncher.cpp

+75-24
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ void Jvm::launch() {
201201
JvmlLauncherAPI* api = jvmLauncherGetAPI();
202202

203203
AutoJvmlLauncherData jld(jvmLauncherCreateJvmlLauncherData(api,
204-
jlh.release()));
204+
jlh.release(), 0));
205205

206206
LOG_TRACE(tstrings::any() << "JVM library: \"" << jvmPath << "\"");
207207

@@ -215,11 +215,20 @@ void Jvm::launch() {
215215
}
216216

217217

218+
void Jvm::setEnvVariables() {
219+
for (size_t i = 0; i != envVarNames.size(); i++) {
220+
SysInfo::setEnvVariable(envVarNames.at(i), envVarValues.at(i));
221+
}
222+
}
223+
224+
218225
namespace {
219226

220227
struct JliLaunchData {
221228
std::string jliLibPath;
222229
std::vector<std::string> args;
230+
tstring_array envVarNames;
231+
tstring_array envVarValues;
223232

224233
int initJvmlLauncherData(JvmlLauncherData* ptr, int bufferSize) const {
225234
int minimalBufferSize = initJvmlLauncherData(0);
@@ -230,6 +239,29 @@ struct JliLaunchData {
230239
}
231240

232241
private:
242+
template <class T>
243+
static char* copyStrings(const std::vector<T>& src,
244+
JvmlLauncherData* ptr, const size_t offset, char* curPtr) {
245+
char** strArray = 0;
246+
if (ptr) {
247+
strArray = *reinterpret_cast<char***>(
248+
reinterpret_cast<char*>(ptr) + offset);
249+
}
250+
251+
for (size_t i = 0; i != src.size(); i++) {
252+
const size_t count = (src[i].size() + 1 /* trailing zero */)
253+
* sizeof(typename T::value_type);
254+
if (ptr) {
255+
std::memcpy(curPtr, src[i].c_str(), count);
256+
strArray[i] = curPtr;
257+
}
258+
259+
curPtr += count;
260+
};
261+
262+
return curPtr;
263+
}
264+
233265
int initJvmlLauncherData(JvmlLauncherData* ptr) const {
234266
// Store path to JLI library just behind JvmlLauncherData header.
235267
char* curPtr = reinterpret_cast<char*>(ptr + 1);
@@ -243,26 +275,39 @@ struct JliLaunchData {
243275
curPtr += count;
244276
}
245277

246-
// Next write array of char* pointing to JLI lib arg strings.
278+
// Write array of char* pointing to JLI lib arg strings.
247279
if (ptr) {
248280
ptr->jliLaunchArgv = reinterpret_cast<char**>(curPtr);
249281
ptr->jliLaunchArgc = (int)args.size();
250282
// Add terminal '0' arg.
251283
ptr->jliLaunchArgv[ptr->jliLaunchArgc] = 0;
252284
}
253-
254-
// Skip memory occupied by char* array.
285+
// Skip memory occupied by JvmlLauncherData::jliLaunchArgv array.
255286
curPtr += sizeof(char*) * (args.size() + 1 /* terminal '0' arg */);
287+
// Store JLI lib arg strings.
288+
curPtr = copyStrings(args, ptr,
289+
offsetof(JvmlLauncherData, jliLaunchArgv), curPtr);
256290

257-
// Store array of strings.
258-
for (size_t i = 0; i != args.size(); i++) {
259-
const size_t count = (args[i].size() + 1 /* trailing zero */);
260-
if (ptr) {
261-
std::memcpy(curPtr, args[i].c_str(), count);
262-
ptr->jliLaunchArgv[i] = curPtr;
263-
}
264-
curPtr += count;
265-
};
291+
// Write array of char* pointing to env variable name strings.
292+
if (ptr) {
293+
ptr->envVarNames = reinterpret_cast<TCHAR**>(curPtr);
294+
ptr->envVarCount = (int)envVarNames.size();
295+
}
296+
// Skip memory occupied by JvmlLauncherData::envVarNames array.
297+
curPtr += sizeof(TCHAR*) * envVarNames.size();
298+
// Store env variable names.
299+
curPtr = copyStrings(envVarNames, ptr,
300+
offsetof(JvmlLauncherData, envVarNames), curPtr);
301+
302+
// Write array of char* pointing to env variable value strings.
303+
if (ptr) {
304+
ptr->envVarValues = reinterpret_cast<TCHAR**>(curPtr);
305+
}
306+
// Skip memory occupied by JvmlLauncherData::envVarValues array.
307+
curPtr += sizeof(TCHAR*) * envVarValues.size();
308+
// Store env variable values.
309+
curPtr = copyStrings(envVarValues, ptr,
310+
offsetof(JvmlLauncherData, envVarValues), curPtr);
266311

267312
const size_t bufferSize = curPtr - reinterpret_cast<char*>(ptr);
268313
if (ptr) {
@@ -276,24 +321,30 @@ struct JliLaunchData {
276321
}
277322
};
278323

279-
} // namespace
280-
281-
JvmlLauncherHandle Jvm::exportLauncher() const {
282-
std::unique_ptr<JliLaunchData> result(new JliLaunchData());
283-
284-
result->jliLibPath = tstrings::toUtf8(jvmPath);
285-
324+
void copyStringArray(const tstring_array& src, std::vector<std::string>& dst) {
286325
#ifdef TSTRINGS_WITH_WCHAR
287326
{
288-
tstring_array::const_iterator it = args.begin();
289-
const tstring_array::const_iterator end = args.end();
327+
tstring_array::const_iterator it = src.begin();
328+
const tstring_array::const_iterator end = src.end();
290329
for (; it != end; ++it) {
291-
result->args.push_back(tstrings::toACP(*it));
330+
dst.push_back(tstrings::toACP(*it));
292331
}
293332
}
294333
#else
295-
result->args = args;
334+
dst = src;
296335
#endif
336+
}
337+
338+
} // namespace
339+
340+
JvmlLauncherHandle Jvm::exportLauncher() const {
341+
std::unique_ptr<JliLaunchData> result(new JliLaunchData());
342+
343+
result->jliLibPath = tstrings::toUtf8(jvmPath);
344+
345+
copyStringArray(args, result->args);
346+
result->envVarNames = envVarNames;
347+
result->envVarValues = envVarValues;
297348

298349
return result.release();
299350
}

0 commit comments

Comments
 (0)
Please sign in to comment.