mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
GP-6392: Fix a deadlock when saving a live trace as prompted upon exiting Ghidra.
This commit is contained in:
@@ -634,7 +634,7 @@ public class DebuggerTraceManagerServicePlugin extends Plugin
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Collection<Trace> getOpenTraces() {
|
||||
public Collection<Trace> getOpenTraces() {
|
||||
synchronized (listenersByTrace) {
|
||||
return Set.copyOf(tracesView);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package ghidra.trace.database;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
@@ -876,16 +875,10 @@ public class DBTrace extends DBCachedDomainObjectAdapter implements Trace, Trace
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(String comment, TaskMonitor monitor) throws IOException, CancelledException {
|
||||
objectManager.flushWbCaches();
|
||||
super.save(comment, monitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveToPackedFile(File outputFile, TaskMonitor monitor)
|
||||
throws IOException, CancelledException {
|
||||
objectManager.flushWbCaches();
|
||||
super.saveToPackedFile(outputFile, monitor);
|
||||
protected void prepareToSave() {
|
||||
try (Transaction tx = openForcedTransaction("flush for save")) {
|
||||
objectManager.flushWbCaches();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isClosing() {
|
||||
@@ -895,9 +888,9 @@ public class DBTrace extends DBCachedDomainObjectAdapter implements Trace, Trace
|
||||
@Override
|
||||
protected void close() {
|
||||
closing = true;
|
||||
objectManager.flushWbCaches();
|
||||
super.close();
|
||||
// NOTE: Any unsaved changes in the write-back cache are unrecoverable
|
||||
objectManager.waitWbWorkers();
|
||||
super.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -41,16 +41,16 @@ public class DBTraceContentHandler extends DBWithUserDataContentHandler<DBTrace>
|
||||
static final Class<DBTrace> TRACE_DOMAIN_OBJECT_CLASS = DBTrace.class;
|
||||
static final String TRACE_CONTENT_DEFAULT_TOOL = "Debugger";
|
||||
|
||||
private static final DBTraceLinkContentHandler linkHandler = new DBTraceLinkContentHandler();
|
||||
private static final DBTraceLinkContentHandler LINK_HANDLER = new DBTraceLinkContentHandler();
|
||||
|
||||
@Override
|
||||
public long createFile(FileSystem fs, FileSystem userfs, String path, String name,
|
||||
DomainObject obj, TaskMonitor monitor)
|
||||
throws IOException, InvalidNameException, CancelledException {
|
||||
if (!(obj instanceof DBTrace)) {
|
||||
if (!(obj instanceof DBTrace trace)) {
|
||||
throw new IOException("Unsupported domain object: " + obj.getClass().getName());
|
||||
}
|
||||
return createFile((DBTrace) obj, TRACE_CONTENT_TYPE, fs, path, name, monitor);
|
||||
return createFile(trace, TRACE_CONTENT_TYPE, fs, path, name, monitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -340,6 +340,6 @@ public class DBTraceContentHandler extends DBWithUserDataContentHandler<DBTrace>
|
||||
|
||||
@Override
|
||||
public DBTraceLinkContentHandler getLinkHandler() {
|
||||
return linkHandler;
|
||||
return LINK_HANDLER;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,8 +40,9 @@ class DBTraceObjectValueWriteBehindCache {
|
||||
private final AsyncReference<Boolean, Void> busy = new AsyncReference<>(false);
|
||||
private volatile boolean flushing = false;
|
||||
|
||||
private final Map<DBTraceObject, Map<String, NavigableMap<Long, DBTraceObjectValueBehind>>> cachedValues =
|
||||
new HashMap<>();
|
||||
private final Map<DBTraceObject,
|
||||
Map<String, NavigableMap<Long, DBTraceObjectValueBehind>>> cachedValues =
|
||||
new HashMap<>();
|
||||
|
||||
public DBTraceObjectValueWriteBehindCache(DBTraceObjectManager manager) {
|
||||
this.manager = manager;
|
||||
@@ -51,7 +52,7 @@ class DBTraceObjectValueWriteBehindCache {
|
||||
}
|
||||
|
||||
private void workLoop() {
|
||||
while (!manager.trace.isClosed()) {
|
||||
while (!manager.trace.isClosing()) {
|
||||
try {
|
||||
synchronized (cachedValues) {
|
||||
if (cachedValues.isEmpty()) {
|
||||
@@ -69,7 +70,7 @@ class DBTraceObjectValueWriteBehindCache {
|
||||
cachedValues.wait(left);
|
||||
}
|
||||
}
|
||||
if (manager.trace.isClosed()) {
|
||||
if (manager.trace.isClosing()) {
|
||||
break;
|
||||
}
|
||||
writeBatch();
|
||||
|
||||
Reference in New Issue
Block a user