diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/marker/MarkerManager.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/marker/MarkerManager.java index 48c6f85b2c..8f82f1b75a 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/marker/MarkerManager.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/marker/MarkerManager.java @@ -189,6 +189,9 @@ public class MarkerManager implements MarkerService { // per-program list MarkerSetCacheEntry entry = markerSetCache.get(program); + if (entry == null) { + return; + } entry.removeSet(markers); // per-group list @@ -301,7 +304,8 @@ public class MarkerManager implements MarkerService { } List copyMarkerSets(Program program) { - return markerSetCache.get(program).copyList(); + MarkerSetCacheEntry entry = markerSetCache.get(program); + return entry == null ? List.of() : entry.copyList(); } /** @@ -311,7 +315,10 @@ public class MarkerManager implements MarkerService { * @param p the program associated with the markers */ void markersChanged(Program p) { - markerSetCache.get(p).colorCache.clear(); + MarkerSetCacheEntry entry = markerSetCache.get(p); + if (entry != null) { + entry.colorCache.clear(); + } updater.update(); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/marker/MarkerOverviewProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/marker/MarkerOverviewProvider.java index 5a42cd243d..5c248d7deb 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/marker/MarkerOverviewProvider.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/marker/MarkerOverviewProvider.java @@ -149,15 +149,15 @@ public class MarkerOverviewProvider implements OverviewProvider { } private void doRefresh() { - if (program == null) { - return; - } - for (DockingAction action : actions) { tool.removeAction(action); } actions.clear(); + if (program == null || program.isClosed()) { + return; + } + List list = markerManager.copyMarkerSets(program); // separate the marker sets into grouped and non-grouped diff --git a/Ghidra/Features/ProgramDiff/src/main/java/ghidra/app/plugin/core/diff/ProgramDiffPlugin.java b/Ghidra/Features/ProgramDiff/src/main/java/ghidra/app/plugin/core/diff/ProgramDiffPlugin.java index 1afe027395..eba347d6c4 100644 --- a/Ghidra/Features/ProgramDiff/src/main/java/ghidra/app/plugin/core/diff/ProgramDiffPlugin.java +++ b/Ghidra/Features/ProgramDiff/src/main/java/ghidra/app/plugin/core/diff/ProgramDiffPlugin.java @@ -1598,7 +1598,8 @@ public class ProgramDiffPlugin extends ProgramPlugin showSecondView(); AddressIndexMap indexMap = diffListingPanel.getAddressIndexMap(); fp.setBackgroundColorModel( - new MarkerServiceBackgroundColorModel(markerManager, indexMap)); + new MarkerServiceBackgroundColorModel(markerManager, secondaryDiffProgram, + indexMap)); } finally { settingLocation = false; diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/DomainObjectAdapter.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/DomainObjectAdapter.java index 2f0b50141e..2e792b4fdc 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/DomainObjectAdapter.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/DomainObjectAdapter.java @@ -18,6 +18,7 @@ package ghidra.framework.data; import java.io.IOException; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArraySet; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; @@ -29,10 +30,8 @@ import ghidra.util.Lock; import ghidra.util.classfinder.ClassSearcher; /** - * An abstract class that provides default behavior for - * DomainObject(s), specifically it handles listeners and - * change status; the derived class must provide the - * getDescription() method. + * An abstract class that provides default behavior for DomainObject(s), specifically it handles + * listeners and change status; the derived class must provide the getDescription() method. */ public abstract class DomainObjectAdapter implements DomainObject { @@ -56,7 +55,7 @@ public abstract class DomainObjectAdapter implements DomainObject { new ConcurrentHashMap(); private volatile boolean eventsEnabled = true; private Set closeListeners = - new HashSet(); + new CopyOnWriteArraySet(); private ArrayList consumers; protected Map metadata = new LinkedHashMap(); @@ -72,12 +71,12 @@ public abstract class DomainObjectAdapter implements DomainObject { private long modificationNumber = 1; /** - * Construct a new DomainObjectAdapter. - * If construction of this object fails, be sure to release with consumer. + * Construct a new DomainObjectAdapter. If construction of this object fails, be sure to release + * with consumer. + * * @param name name of the object - * @param timeInterval the time (in milliseconds) to wait before the - * event queue is flushed. If a new event comes in before the time expires, - * the timer is reset. + * @param timeInterval the time (in milliseconds) to wait before the event queue is flushed. If + * a new event comes in before the time expires, the timer is reset. * @param bufsize initial size of event buffer * @param consumer the object that created this domain object */ @@ -125,8 +124,9 @@ public abstract class DomainObjectAdapter implements DomainObject { } /** - * Returns the hidden user-filesystem associated with - * this objects domain file, or null if unknown. + * Returns the hidden user-filesystem associated with this objects domain file, or null if + * unknown. + * * @return user data file system */ protected FileSystem getAssociatedUserFilesystem() { @@ -250,6 +250,7 @@ public abstract class DomainObjectAdapter implements DomainObject { /** * Return "changed" status + * * @return true if this object has changed */ public boolean getChangeStatus() { @@ -316,9 +317,10 @@ public abstract class DomainObjectAdapter implements DomainObject { public abstract String getDescription(); /** - * Fires the specified event. - * @param ev event to fire - */ + * Fires the specified event. + * + * @param ev event to fire + */ public void fireEvent(DomainObjectChangeRecord ev) { modificationNumber++; if (eventsEnabled) { @@ -428,6 +430,7 @@ public abstract class DomainObjectAdapter implements DomainObject { /** * Set default content type + * * @param doClass default domain object implementation */ public static synchronized void setDefaultContentClass(Class doClass) { @@ -447,6 +450,7 @@ public abstract class DomainObjectAdapter implements DomainObject { /** * Get the ContentHandler associated with the specified content-type. + * * @param contentType domain object content type * @return content handler */ @@ -461,6 +465,7 @@ public abstract class DomainObjectAdapter implements DomainObject { /** * Get the ContentHandler associated with the specified domain object + * * @param dobj domain object * @return content handler */