69 * @returns the directory or {@code null} if the could not be created or has been deleted
70 */
71 public String getPath() {
72 return getPath(true);
73 }
74
75 private synchronized String getPath(boolean createIfNull) {
76 if (path == null && createIfNull) {
77 path = createPath();
78 File dir = new File(path).getAbsoluteFile();
79 if (!dir.exists()) {
80 dir.mkdirs();
81 if (!dir.exists()) {
82 TTY.println("Warning: could not create Graal diagnostic directory " + dir);
83 return null;
84 }
85 }
86 }
87 if (CLOSED.equals(path)) {
88 TTY.println("Warning: Graal diagnostic directory already closed");
89 }
90 return path;
91 }
92
93 /**
94 * Gets the path of the directory to be created.
95 *
96 * Subclasses can override this to determine how the path name is created.
97 *
98 * @return the path to be created
99 */
100 protected String createPath() {
101 Path baseDir;
102 try {
103 baseDir = DebugOptions.getDumpDirectory(options);
104 } catch (IOException e) {
105 // Default to current directory if there was a problem creating the
106 // directory specified by the DumpPath option.
107 baseDir = Paths.get(".");
108 }
112 /**
113 * Archives and deletes this directory if it exists.
114 */
115 public void close() {
116 archiveAndDelete();
117 }
118
119 /**
120 * Archives and deletes the {@linkplain #getPath() output directory} if it exists.
121 */
122 private synchronized void archiveAndDelete() {
123 String outDir = getPath(false);
124 if (outDir != null) {
125 // Notify other threads calling getPath() that the directory is deleted.
126 // This attempts to mitigate other threads writing to the directory
127 // while it is being archived and deleted.
128 path = CLOSED;
129
130 Path dir = Paths.get(outDir);
131 if (dir.toFile().exists()) {
132 File zip = new File(outDir + ".zip").getAbsoluteFile();
133 List<Path> toDelete = new ArrayList<>();
134 try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zip))) {
135 zos.setLevel(Deflater.BEST_COMPRESSION);
136 Files.walkFileTree(dir, Collections.emptySet(), Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
137 @Override
138 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
139 if (attrs.isRegularFile()) {
140 String name = dir.relativize(file).toString();
141 ZipEntry ze = new ZipEntry(name);
142 zos.putNextEntry(ze);
143 Files.copy(file, zos);
144 zos.closeEntry();
145 }
146 toDelete.add(file);
147 return FileVisitResult.CONTINUE;
148 }
149
150 @Override
151 public FileVisitResult postVisitDirectory(Path d, IOException exc) throws IOException {
152 toDelete.add(d);
153 return FileVisitResult.CONTINUE;
154 }
155 });
156 // Keep this in sync with the catch_files in common.hocon
157 TTY.println("Graal diagnostic output saved in %s", zip);
158 } catch (IOException e) {
159 TTY.printf("IO error archiving %s:%n%s. The directory will not be deleted and must be " +
160 "manually removed once the VM exits.%n", dir, e);
|
69 * @returns the directory or {@code null} if the could not be created or has been deleted
70 */
71 public String getPath() {
72 return getPath(true);
73 }
74
75 private synchronized String getPath(boolean createIfNull) {
76 if (path == null && createIfNull) {
77 path = createPath();
78 File dir = new File(path).getAbsoluteFile();
79 if (!dir.exists()) {
80 dir.mkdirs();
81 if (!dir.exists()) {
82 TTY.println("Warning: could not create Graal diagnostic directory " + dir);
83 return null;
84 }
85 }
86 }
87 if (CLOSED.equals(path)) {
88 TTY.println("Warning: Graal diagnostic directory already closed");
89 return null;
90 }
91 return path;
92 }
93
94 /**
95 * Gets the path of the directory to be created.
96 *
97 * Subclasses can override this to determine how the path name is created.
98 *
99 * @return the path to be created
100 */
101 protected String createPath() {
102 Path baseDir;
103 try {
104 baseDir = DebugOptions.getDumpDirectory(options);
105 } catch (IOException e) {
106 // Default to current directory if there was a problem creating the
107 // directory specified by the DumpPath option.
108 baseDir = Paths.get(".");
109 }
113 /**
114 * Archives and deletes this directory if it exists.
115 */
116 public void close() {
117 archiveAndDelete();
118 }
119
120 /**
121 * Archives and deletes the {@linkplain #getPath() output directory} if it exists.
122 */
123 private synchronized void archiveAndDelete() {
124 String outDir = getPath(false);
125 if (outDir != null) {
126 // Notify other threads calling getPath() that the directory is deleted.
127 // This attempts to mitigate other threads writing to the directory
128 // while it is being archived and deleted.
129 path = CLOSED;
130
131 Path dir = Paths.get(outDir);
132 if (dir.toFile().exists()) {
133 String prefix = new File(outDir).getName() + "/";
134 File zip = new File(outDir + ".zip").getAbsoluteFile();
135 List<Path> toDelete = new ArrayList<>();
136 try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zip))) {
137 zos.setLevel(Deflater.BEST_COMPRESSION);
138 Files.walkFileTree(dir, Collections.emptySet(), Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
139 @Override
140 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
141 if (attrs.isRegularFile()) {
142 String name = prefix + dir.relativize(file).toString();
143 ZipEntry ze = new ZipEntry(name);
144 zos.putNextEntry(ze);
145 Files.copy(file, zos);
146 zos.closeEntry();
147 }
148 toDelete.add(file);
149 return FileVisitResult.CONTINUE;
150 }
151
152 @Override
153 public FileVisitResult postVisitDirectory(Path d, IOException exc) throws IOException {
154 toDelete.add(d);
155 return FileVisitResult.CONTINUE;
156 }
157 });
158 // Keep this in sync with the catch_files in common.hocon
159 TTY.println("Graal diagnostic output saved in %s", zip);
160 } catch (IOException e) {
161 TTY.printf("IO error archiving %s:%n%s. The directory will not be deleted and must be " +
162 "manually removed once the VM exits.%n", dir, e);
|