52 * @modules java.base/jdk.internal.misc
53 * java.management
54 * @run driver TestInheritFD
55 */
56
57 /**
58 * Test that HotSpot does not leak logging file descriptors.
59 *
60 * This test is performed in three steps. The first VM starts a second VM with
61 * gc logging enabled. The second VM starts a third VM and redirects the third
62 * VMs output to the first VM, it then exits and hopefully closes its log file.
63 *
64 * The third VM waits for the second to exit and close its log file. After that,
65 * the third VM tries to rename the log file of the second VM. If it succeeds in
66 * doing so it means that the third VM did not inherit the open log file
67 * (windows can not rename opened files easily)
68 *
69 * The third VM communicates the success to rename the file by printing "CLOSED
70 * FD". The first VM checks that the string was printed by the third VM.
71 *
72 * On unix like systems "lsof" or "pfiles" is used.
73 */
74
75 public class TestInheritFD {
76
77 public static final String LEAKS_FD = "VM RESULT => LEAKS FD";
78 public static final String RETAINS_FD = "VM RESULT => RETAINS FD";
79 public static final String EXIT = "VM RESULT => VM EXIT";
80 public static final String LOG_SUFFIX = ".strangelogsuffixthatcanbecheckedfor";
81
82 // first VM
83 public static void main(String[] args) throws Exception {
84 String logPath = Utils.createTempFile("logging", LOG_SUFFIX).toFile().getName();
85 File commFile = Utils.createTempFile("communication", ".txt").toFile();
86
87 if (!isWindows() && !lsofCommand().isPresent()) {
88 throw new SkippedException("Could not find lsof like command");
89 }
90
91 ProcessBuilder pb = createJavaProcessBuilder(
92 "-Xlog:gc:\"" + logPath + "\"",
159 try {
160 new FileOutputStream("fakeLeakyJVM" + LOG_SUFFIX, false);
161 } catch (FileNotFoundException e) {
162 }
163 }
164 }
165
166 static Stream<String> run(String... args){
167 try {
168 return new BufferedReader(new InputStreamReader(new ProcessBuilder(args).start().getInputStream())).lines();
169 } catch (IOException e) {
170 throw new RuntimeException(e);
171 }
172 }
173
174 static Optional<String[]> lsofCommandCache = stream(new String[][]{
175 {"/usr/bin/lsof", "-p"},
176 {"/usr/sbin/lsof", "-p"},
177 {"/bin/lsof", "-p"},
178 {"/sbin/lsof", "-p"},
179 {"/usr/local/bin/lsof", "-p"},
180 {"/usr/bin/pfiles", "-F"}}) // Solaris
181 .filter(args -> new File(args[0]).exists())
182 .findFirst();
183
184 static Optional<String[]> lsofCommand() {
185 return lsofCommandCache;
186 }
187
188 static Collection<String> outputContainingFilenames() {
189 long pid = ProcessHandle.current().pid();
190
191 String[] command = lsofCommand().orElseThrow(() -> new RuntimeException("lsof like command not found"));
192 System.out.println("using command: " + command[0] + " " + command[1]);
193 return run(command[0], command[1], "" + pid).collect(toList());
194 }
195
196 static boolean findOpenLogFile(Collection<String> fileNames) {
197 return fileNames.stream()
198 .filter(fileName -> fileName.contains(LOG_SUFFIX))
199 .findAny()
200 .isPresent();
|
52 * @modules java.base/jdk.internal.misc
53 * java.management
54 * @run driver TestInheritFD
55 */
56
57 /**
58 * Test that HotSpot does not leak logging file descriptors.
59 *
60 * This test is performed in three steps. The first VM starts a second VM with
61 * gc logging enabled. The second VM starts a third VM and redirects the third
62 * VMs output to the first VM, it then exits and hopefully closes its log file.
63 *
64 * The third VM waits for the second to exit and close its log file. After that,
65 * the third VM tries to rename the log file of the second VM. If it succeeds in
66 * doing so it means that the third VM did not inherit the open log file
67 * (windows can not rename opened files easily)
68 *
69 * The third VM communicates the success to rename the file by printing "CLOSED
70 * FD". The first VM checks that the string was printed by the third VM.
71 *
72 * On unix like systems "lsof" is used.
73 */
74
75 public class TestInheritFD {
76
77 public static final String LEAKS_FD = "VM RESULT => LEAKS FD";
78 public static final String RETAINS_FD = "VM RESULT => RETAINS FD";
79 public static final String EXIT = "VM RESULT => VM EXIT";
80 public static final String LOG_SUFFIX = ".strangelogsuffixthatcanbecheckedfor";
81
82 // first VM
83 public static void main(String[] args) throws Exception {
84 String logPath = Utils.createTempFile("logging", LOG_SUFFIX).toFile().getName();
85 File commFile = Utils.createTempFile("communication", ".txt").toFile();
86
87 if (!isWindows() && !lsofCommand().isPresent()) {
88 throw new SkippedException("Could not find lsof like command");
89 }
90
91 ProcessBuilder pb = createJavaProcessBuilder(
92 "-Xlog:gc:\"" + logPath + "\"",
159 try {
160 new FileOutputStream("fakeLeakyJVM" + LOG_SUFFIX, false);
161 } catch (FileNotFoundException e) {
162 }
163 }
164 }
165
166 static Stream<String> run(String... args){
167 try {
168 return new BufferedReader(new InputStreamReader(new ProcessBuilder(args).start().getInputStream())).lines();
169 } catch (IOException e) {
170 throw new RuntimeException(e);
171 }
172 }
173
174 static Optional<String[]> lsofCommandCache = stream(new String[][]{
175 {"/usr/bin/lsof", "-p"},
176 {"/usr/sbin/lsof", "-p"},
177 {"/bin/lsof", "-p"},
178 {"/sbin/lsof", "-p"},
179 {"/usr/local/bin/lsof", "-p"}})
180 .filter(args -> new File(args[0]).exists())
181 .findFirst();
182
183 static Optional<String[]> lsofCommand() {
184 return lsofCommandCache;
185 }
186
187 static Collection<String> outputContainingFilenames() {
188 long pid = ProcessHandle.current().pid();
189
190 String[] command = lsofCommand().orElseThrow(() -> new RuntimeException("lsof like command not found"));
191 System.out.println("using command: " + command[0] + " " + command[1]);
192 return run(command[0], command[1], "" + pid).collect(toList());
193 }
194
195 static boolean findOpenLogFile(Collection<String> fileNames) {
196 return fileNames.stream()
197 .filter(fileName -> fileName.contains(LOG_SUFFIX))
198 .findAny()
199 .isPresent();
|