From 5baaa82016deca4aa317f4234160e0d2f6df3997 Mon Sep 17 00:00:00 2001 From: dragonmacher <48328597+dragonmacher@users.noreply.github.com> Date: Thu, 13 Jun 2024 12:03:32 -0400 Subject: [PATCH 1/3] Test fixes --- .../ghidra/util/bean/opteditor/OptionsDialogTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/util/bean/opteditor/OptionsDialogTest.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/util/bean/opteditor/OptionsDialogTest.java index d73843a786..153e181534 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/util/bean/opteditor/OptionsDialogTest.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/util/bean/opteditor/OptionsDialogTest.java @@ -434,7 +434,7 @@ public class OptionsDialogTest extends AbstractGhidraHeadedIntegrationTest { MouseBinding defaultMouseBinding = getMouseBindingFromTable(actionName, actionOwner); assertNull(defaultMouseBinding); - int button = 1; + int button = 4; int modifiers = 0; MouseBinding newMouseBinding = setMouseBinding(actionName, actionOwner, modifiers, button); @@ -462,7 +462,7 @@ public class OptionsDialogTest extends AbstractGhidraHeadedIntegrationTest { MouseBinding defaultMouseBinding = getMouseBindingFromTable(actionName, actionOwner); assertNull(defaultMouseBinding); - int button = 1; + int button = 4; int modifiers = 0; MouseBinding newMouseBinding = setMouseBinding(actionName, actionOwner, modifiers, button); @@ -500,7 +500,7 @@ public class OptionsDialogTest extends AbstractGhidraHeadedIntegrationTest { int modifiers = InputEvent.CTRL_DOWN_MASK | InputEvent.ALT_DOWN_MASK; KeyStroke newKeyStroke = setKeyBinding(actionName, actionOwner, modifiers, keyCode, 'Q'); - int button = 1; + int button = 4; modifiers = 0; MouseBinding newMouseBinding = setMouseBinding(actionName, actionOwner, modifiers, button); @@ -533,7 +533,7 @@ public class OptionsDialogTest extends AbstractGhidraHeadedIntegrationTest { MouseBinding defaultMouseBinding = getMouseBindingFromTable(actionName, actionOwner); assertNull(defaultMouseBinding); - int button = 1; + int button = 4; int modifiers = 0; MouseBinding newMouseBinding = setMouseBinding(actionName, actionOwner, modifiers, button); From bac18feabfe8d842defcce218cacad0963b5ce4f Mon Sep 17 00:00:00 2001 From: ghidra1 Date: Wed, 12 Jun 2024 17:31:22 -0400 Subject: [PATCH 2/3] GP-4692 Corrected post-checkin/merge update of open database/domain-object --- .../src/main/java/db/buffers/BufferMgr.java | 15 ++++- .../ghidra/framework/data/GhidraFileData.java | 34 +++++------ .../datatree/VersionControlAction2Test.java | 56 ++++++++++++++++++- 3 files changed, 85 insertions(+), 20 deletions(-) diff --git a/Ghidra/Framework/DB/src/main/java/db/buffers/BufferMgr.java b/Ghidra/Framework/DB/src/main/java/db/buffers/BufferMgr.java index 88eda4b1ba..ade2f55f36 100644 --- a/Ghidra/Framework/DB/src/main/java/db/buffers/BufferMgr.java +++ b/Ghidra/Framework/DB/src/main/java/db/buffers/BufferMgr.java @@ -78,8 +78,8 @@ public class BufferMgr { */ private BufferNode cacheHead; private BufferNode cacheTail; - private int cacheSize = 0; - private int buffersOnHand = 0; + private int cacheSize; + private int buffersOnHand; private int lockCount = 0; /** @@ -235,6 +235,10 @@ public class BufferMgr { private void initializeCache() throws IOException { + if (lockCount != 0) { + throw new IOException("Unable to re-initialize buffer cache while in-use"); + } + if (cacheFile != null) { cacheFile.delete(); } @@ -244,6 +248,9 @@ public class BufferMgr { cacheTail = new BufferNode(TAIL, -1); cacheHead.nextCached = cacheTail; cacheTail.prevCached = cacheHead; + + cacheSize = 0; + buffersOnHand = 0; // Create disk cache file cacheFile = new LocalBufferFile(bufferSize, CACHE_FILE_PREFIX, CACHE_FILE_EXT); @@ -257,6 +264,8 @@ public class BufferMgr { cacheFile.setParameter(name, sourceFile.getParameter(name)); } } + + resetCacheStatistics(); if (alwaysPreCache) { startPreCacheIfNeeded(); @@ -2058,7 +2067,7 @@ public class BufferMgr { public void resetCacheStatistics() { cacheHits = 0; cacheMisses = 0; - lowWaterMark = cacheSize; + lowWaterMark = cacheSize - 1; } public String getStatusInfo() { diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/GhidraFileData.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/GhidraFileData.java index dda4f1e667..120f59174b 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/GhidraFileData.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/GhidraFileData.java @@ -1149,7 +1149,7 @@ public class GhidraFileData { if (keepCheckedOut) { - // Maintain exclusive chekout if private repository or file is open for update + // Maintain exclusive checkout if private repository or file is open for update boolean exclusive = !versionedFileSystem.isShared() || (inUseDomainObj != null); ProjectLocator projectLocator = parent.getProjectLocator(); @@ -1169,6 +1169,11 @@ public class GhidraFileData { projectLocator.isTransient())); folderItem.setCheckout(checkout.getCheckoutId(), exclusive, checkout.getCheckoutVersion(), folderItem.getCurrentVersion()); + + if (inUseDomainObj != null) { + // Reset source file and change-sets for open database + getContentHandler().resetDBSourceFile(folderItem, inUseDomainObj); + } } else { // NOTE: file open read-only may prevent removal and result in hijack @@ -1180,10 +1185,7 @@ public class GhidraFileData { // Ignore - should result in Hijacked file } } - - if (inUseDomainObj != null) { - getContentHandler().resetDBSourceFile(folderItem, inUseDomainObj); - } + } // end of synchronized block if (inUseDomainObj != null) { @@ -1535,15 +1537,16 @@ public class GhidraFileData { } } } + + if (inUseDomainObj != null) { + // Reset source file and change-sets for open database + contentHandler.resetDBSourceFile(folderItem, inUseDomainObj); + } } else { undoCheckout(false, true); } - if (inUseDomainObj != null) { - contentHandler.resetDBSourceFile(folderItem, inUseDomainObj); - } - } // end of synchronized block if (inUseDomainObj != null) { @@ -1915,6 +1918,8 @@ public class GhidraFileData { try { inUseDomainObj = getAndLockInUseDomainObjectForMergeUpdate("merge"); + ContentHandler contentHandler = getContentHandler(); + if (!modifiedSinceCheckout()) { // Quick merge folderItem.updateCheckout(versionedFolderItem, true, monitor); @@ -1925,8 +1930,6 @@ public class GhidraFileData { throw new IOException("Merge failed, merge is not supported in headless mode"); } - ContentHandler contentHandler = getContentHandler(); - // Test versioned file for VersionException int mergeVer = versionedFolderItem.getCurrentVersion(); if (!okToUpgrade) { @@ -1995,14 +1998,13 @@ public class GhidraFileData { versionedFolderItem.updateCheckoutVersion(checkoutId, mergeVer, ClientUtil.getUserName()); tmpItem = null; - Msg.info(this, "Merge completed for " + name); - - if (inUseDomainObj != null) { - contentHandler.resetDBSourceFile(folderItem, inUseDomainObj); - } } + + Msg.info(this, "Updated checkout completed for " + name); if (inUseDomainObj != null) { + // Reset source file and change-sets for open database + contentHandler.resetDBSourceFile(folderItem, inUseDomainObj); inUseDomainObj.invalidate(); } } diff --git a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/datatree/VersionControlAction2Test.java b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/datatree/VersionControlAction2Test.java index 7c83d21ea2..32f289971b 100644 --- a/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/datatree/VersionControlAction2Test.java +++ b/Ghidra/Test/IntegrationTest/src/test.slow/java/ghidra/framework/main/datatree/VersionControlAction2Test.java @@ -36,6 +36,8 @@ import generic.theme.GIcon; import ghidra.framework.main.projectdata.actions.VersionControlAction; import ghidra.framework.model.DomainFile; import ghidra.framework.model.DomainFolder; +import ghidra.program.database.ProgramDB; +import ghidra.program.model.address.AddressSpace; import ghidra.program.model.listing.CodeUnit; import ghidra.program.model.listing.Program; import ghidra.program.model.symbol.SourceType; @@ -219,7 +221,7 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest waitForSwing(); waitForTasks(); - Program program = (Program) ((DomainFileNode) node).getDomainFile() + ProgramDB program = (ProgramDB) ((DomainFileNode) node).getDomainFile() .getDomainObject(this, true, false, TaskMonitor.DUMMY); int transactionID = program.startTransaction("test"); @@ -253,6 +255,58 @@ public class VersionControlAction2Test extends AbstractVersionControlActionTest assertTrue(!df.isCheckedOut()); } + + @Test + public void testCheckInWhileOpen() throws Exception { + GTreeNode node = getNode(PROGRAM_A); + addToVersionControl(node, false); + + selectNode(node); + DockingActionIf action = getAction("CheckOut"); + runSwing(() -> action.actionPerformed(getDomainFileActionContext(node)), false); + waitForSwing(); + waitForTasks(); + + ProgramDB program = (ProgramDB) ((DomainFileNode) node).getDomainFile() + .getDomainObject(this, + true, false, TaskMonitor.DUMMY); + int transactionID = program.startTransaction("test"); + try { + // Ensure that buffer memory cache has been completely consumed + // Max BufferMgr cache size is 256*16KByte=4MByte + AddressSpace space = program.getAddressFactory().getDefaultAddressSpace(); + program.getMemory().createInitializedBlock("BigBlock", space.getAddress(0x80000000L), + 4*1024*1024, (byte)0xff, TaskMonitor.DUMMY, false); + } + finally { + program.endTransaction(transactionID, true); + program.save(null, TaskMonitor.DUMMY); + } + + try { + DockingActionIf checkInAction = getAction("CheckIn"); + runSwing(() -> checkInAction.actionPerformed(getDomainFileActionContext(node)), false); + waitForSwing(); + VersionControlDialog dialog = waitForDialogComponent(VersionControlDialog.class); + assertNotNull(dialog); + JTextArea textArea = findComponent(dialog, JTextArea.class); + assertNotNull(textArea); + JCheckBox cb = findComponent(dialog, JCheckBox.class); + assertNotNull(cb); + runSwing(() -> { + textArea.setText("This is a test"); + cb.setSelected(false); + }); + pressButtonByText(dialog, "OK"); + waitForTasks(); + DomainFile df = ((DomainFileNode) node).getDomainFile(); + assertTrue(df.isCheckedOut()); + } + finally { + program.release(this); + } + + } @Test public void testDeleteVersionCheckedOut() throws Exception { From febbeb447af1f059d583b11d7cefc8758b99f887 Mon Sep 17 00:00:00 2001 From: ghidra1 Date: Fri, 14 Jun 2024 10:18:58 -0400 Subject: [PATCH 3/3] GP-0 Updated Change History for Ghidra 11.1.1 release --- .../src/global/docs/ChangeHistory.html | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Ghidra/Configurations/Public_Release/src/global/docs/ChangeHistory.html b/Ghidra/Configurations/Public_Release/src/global/docs/ChangeHistory.html index 78d2a36c85..102d4b1aab 100644 --- a/Ghidra/Configurations/Public_Release/src/global/docs/ChangeHistory.html +++ b/Ghidra/Configurations/Public_Release/src/global/docs/ChangeHistory.html @@ -22,6 +22,21 @@ +

Ghidra 11.1.1 Change History (June 2024)

+

Bugs

+
    +
  • Debugger. Fixes an error in dbgeng launcher. (GP-4674)
  • +
  • Debugger:GDB. Fixed issue with using QEMU launchers in Trace RMI (ClassCastException from String to PathIsFile) (GP-4690, Issue #6634)
  • +
  • Decompiler. Fixed a bug in the Decompiler that could cause it to drop a control-flow edge from a switch's case statement that looped back to the switch. (GP-4582, Issue #6282)
  • +
  • Decompiler. Fixed bug causing "Undefined Pullsub" exceptions. (GP-4672, Issue #6614)
  • +
  • Decompiler. Corrected Decompiler process issue which can occur when analysis is cancelled. Issue would incorrectly popup error indicating "Decompiler executable may not be compatible with your system...". (GP-4689)
  • +
  • GUI. Fixed mouse button 4/5 processing failure that caused the left-click to stop working. (GP-4681, Issue #6624)
  • +
  • Processors. Added support for the Z80 processor undocumented registers. (GP-2881, Issue #4485)
  • +
  • Processors. Fixed 6805 branch conditional instruction semantics. (GP-4585, Issue #6482)
  • +
  • Project. Fixed a severe regression bug introduced with Ghidra 11.1 which could prevent a user from completing a project file add-to-version-control, checkin or merge when they currently have the file open in a tool. The corresponding open project file would remain in a bad state following the operation. (GP-4692)
  • +
+
+

Ghidra 11.1 Change History (June 2024)

New Features