Skip to content

Commit afe8350

Browse files
committed
do not load dirty cache; prevent loading cache created on different OS; prevent loading cache for different heap dump
1 parent 893eb4e commit afe8350

File tree

4 files changed

+55
-2
lines changed

4 files changed

+55
-2
lines changed

visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/heap/CacheDirectory.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class CacheDirectory {
5151

5252
private static final String DIR_EXT = ".hwcache"; // NOI18N
5353
private static final String DUMP_AUX_FILE = "NBProfiler.nphd"; // NOI18N
54+
private static final String DIRTY_FILENAME = "dirty.lck"; // NOI18N
5455

5556
private File cacheDirectory;
5657

@@ -122,6 +123,36 @@ File getHeapFile(String fileName) throws FileNotFoundException {
122123
throw new FileNotFoundException(fileName);
123124
}
124125

126+
void deleteAllCachedFiles() {
127+
assert !isTemporary();
128+
for (File f : cacheDirectory.listFiles()) {
129+
f.delete();
130+
}
131+
}
132+
133+
boolean isDirty() {
134+
if (isTemporary()) return true;
135+
File dirtyFile = new File(cacheDirectory,DIRTY_FILENAME);
136+
return isFileR(dirtyFile);
137+
}
138+
139+
void setDirty(boolean dirty) {
140+
if (!isTemporary()) {
141+
File dirtyFile = new File(cacheDirectory, DIRTY_FILENAME);
142+
try {
143+
if (dirty) {
144+
assert !isFileR(dirtyFile);
145+
dirtyFile.createNewFile();
146+
} else {
147+
assert isFileRW(dirtyFile);
148+
dirtyFile.delete();
149+
}
150+
} catch (IOException ex) {
151+
ex.printStackTrace();
152+
}
153+
}
154+
}
155+
125156
private static boolean isFileR(File f) {
126157
return f.exists() && f.isFile() && f.canRead();
127158
}

visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/heap/HeapFactory.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ public static Heap createHeap(File heapDump, int segment)
9898
} catch (IOException ex) {
9999
System.err.println("Loading heap dump "+heapDump+" from cache failed.");
100100
ex.printStackTrace(System.err);
101+
cacheDir.deleteAllCachedFiles();
101102
}
102103
}
103104
}

visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/heap/HprofHeap.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ class HprofHeap implements Heap {
121121
private static final boolean DEBUG = false;
122122

123123
private static final String SNAPSHOT_ID = "NBPHD";
124-
private static final int SNAPSHOT_VERSION = 2;
124+
private static final int SNAPSHOT_VERSION = 3;
125+
private static final String OS_PROP = "os.name";
125126

126127
//~ Instance fields ----------------------------------------------------------------------------------------------------------
127128

@@ -347,6 +348,7 @@ void writeToFile() {
347348
out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(outFile), 32768));
348349
writeToStream(out);
349350
out.close();
351+
cacheDirectory.setDirty(false);
350352
} catch (IOException ex) {
351353
ex.printStackTrace(System.err);
352354
}
@@ -357,6 +359,8 @@ void writeToStream(DataOutputStream out) throws IOException {
357359
out.writeUTF(SNAPSHOT_ID);
358360
out.writeInt(SNAPSHOT_VERSION);
359361
out.writeUTF(heapDumpFile.getAbsolutePath());
362+
out.writeLong(dumpBuffer.getTime());
363+
out.writeUTF(System.getProperty(OS_PROP));
360364
nearestGCRoot.writeToStream(out);
361365
allInstanceDumpBounds.writeToStream(out);
362366
heapDumpSegment.writeToStream(out);
@@ -376,6 +380,9 @@ void writeToStream(DataOutputStream out) throws IOException {
376380
}
377381

378382
HprofHeap(DataInputStream dis, CacheDirectory cacheDir) throws IOException {
383+
if (cacheDir.isDirty()) {
384+
throw new IOException("Dirty cache "+cacheDir);
385+
}
379386
String id = dis.readUTF();
380387
if (!SNAPSHOT_ID.equals(id)) {
381388
throw new IOException("Invalid HPROF dump id "+id);
@@ -387,6 +394,14 @@ void writeToStream(DataOutputStream out) throws IOException {
387394
heapDumpFile = cacheDir.getHeapFile(dis.readUTF());
388395
cacheDirectory = cacheDir;
389396
dumpBuffer = HprofByteBuffer.createHprofByteBuffer(heapDumpFile);
397+
long time = dis.readLong();
398+
if (time != dumpBuffer.getTime()) {
399+
throw new IOException("HPROF time mismatch. Cached "+time+" from heap dump "+dumpBuffer.getTime());
400+
}
401+
String os = dis.readUTF();
402+
if (!os.equals(System.getProperty(OS_PROP))) {
403+
throw new IOException("HPROF OS mismatch. Cached "+os+" current OS "+System.getProperty(OS_PROP));
404+
}
390405
nearestGCRoot = new NearestGCRoot(this, dis);
391406
allInstanceDumpBounds = new TagBounds(dis);
392407
heapDumpSegment = new TagBounds(dis);
@@ -523,6 +538,7 @@ void computeInstances() {
523538
}
524539

525540
HeapProgress.progressStart();
541+
cacheDirectory.setDirty(true);
526542
ClassDumpSegment classDumpBounds = getClassDumpSegment();
527543
int idSize = dumpBuffer.getIDSize();
528544
long[] offset = new long[] { allInstanceDumpBounds.startOffset };
@@ -646,6 +662,7 @@ void computeReferences() {
646662
Map classIdToClassMap = classDumpBounds.getClassIdToClassMap();
647663

648664
computeInstances();
665+
cacheDirectory.setDirty(true);
649666
for (long counter=0; offset[0] < allInstanceDumpBounds.endOffset; counter++) {
650667
long start = offset[0];
651668
int tag = readDumpTag(offset);
@@ -729,7 +746,9 @@ void computeRetainedSize() {
729746
if (retainedSizeComputed) {
730747
return;
731748
}
732-
new TreeObject(this,nearestGCRoot.getLeaves()).computeTrees();
749+
LongBuffer leaves = nearestGCRoot.getLeaves();
750+
cacheDirectory.setDirty(true);
751+
new TreeObject(this,leaves).computeTrees();
733752
domTree = new DominatorTree(this,nearestGCRoot.getMultipleParents());
734753
domTree.computeDominators();
735754
long[] offset = new long[] { allInstanceDumpBounds.startOffset };
@@ -793,6 +812,7 @@ void computeRetainedSizeByClass() {
793812
return;
794813
}
795814
computeRetainedSize();
815+
cacheDirectory.setDirty(true);
796816
long[] offset = new long[] { allInstanceDumpBounds.startOffset };
797817

798818
while (offset[0] < allInstanceDumpBounds.endOffset) {

visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/heap/NearestGCRoot.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ private synchronized void computeGCRoots() {
122122
}
123123
}
124124
heap.computeReferences(); // make sure references are computed first
125+
heap.cacheDirectory.setDirty(true);
125126
allInstances = heap.getSummary().getTotalLiveInstances();
126127
Set processedClasses = new HashSet(heap.getAllClasses().size()*4/3);
127128

0 commit comments

Comments
 (0)