diff --git a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracemgr/DebuggerCoordinates.java b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracemgr/DebuggerCoordinates.java
index 89ef6ef085..0ac6647f16 100644
--- a/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracemgr/DebuggerCoordinates.java
+++ b/Ghidra/Debug/Debugger-api/src/main/java/ghidra/debug/api/tracemgr/DebuggerCoordinates.java
@@ -66,7 +66,7 @@ public class DebuggerCoordinates {
private static final String KEY_FRAME = "Frame";
private static final String KEY_OBJ_PATH = "ObjectPath";
- public static boolean equalsIgnoreRecorderAndView(DebuggerCoordinates a,
+ public static boolean equalsIgnoreTargetAndView(DebuggerCoordinates a,
DebuggerCoordinates b) {
if (!Objects.equals(a.trace, b.trace)) {
return false;
@@ -417,6 +417,36 @@ public class DebuggerCoordinates {
newFrame, newPath);
}
+ /**
+ * Checks if the given coordinates are the same as this but with an extra or differing patch.
+ *
+ * @param that the other coordinates
+ * @return true if the difference is only in the final patch step
+ */
+ public boolean differsOnlyByPatch(DebuggerCoordinates that) {
+ if (!Objects.equals(this.trace, that.trace)) {
+ return false;
+ }
+
+ if (!Objects.equals(this.platform, that.platform)) {
+ return false;
+ }
+ if (!Objects.equals(this.thread, that.thread)) {
+ return false;
+ }
+ // Consider defaults
+ if (!Objects.equals(this.getFrame(), that.getFrame())) {
+ return false;
+ }
+ if (!Objects.equals(this.getObject(), that.getObject())) {
+ return false;
+ }
+ if (!this.getTime().differsOnlyByPatch(that.getTime())) {
+ return false;
+ }
+ return true;
+ }
+
public DebuggerCoordinates frame(int newFrame) {
if (trace == null) {
return NOWHERE;
@@ -621,7 +651,11 @@ public class DebuggerCoordinates {
if (registerContainer != null) {
return registerContainer;
}
- return registerContainer = getObject().findRegisterContainer(getFrame());
+ TraceObject object = getObject();
+ if (object == null) {
+ return null;
+ }
+ return registerContainer = object.findRegisterContainer(getFrame());
}
public synchronized long getViewSnap() {
diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerTrackLocationTrait.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerTrackLocationTrait.java
index 35ff2c3d27..f31c3b4a1b 100644
--- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerTrackLocationTrait.java
+++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerTrackLocationTrait.java
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -52,6 +52,10 @@ public class DebuggerTrackLocationTrait {
protected static final AutoConfigState.ClassHandler CONFIG_STATE_HANDLER =
AutoConfigState.wireHandler(DebuggerTrackLocationTrait.class, MethodHandles.lookup());
+ public enum TrackCause {
+ USER, DB_CHANGE, NAVIGATION, EMU_PATCH, SPEC_CHANGE_API;
+ }
+
protected class ForTrackingListener extends TraceDomainObjectListener {
public ForTrackingListener() {
@@ -68,7 +72,7 @@ public class DebuggerTrackLocationTrait {
if (!tracker.affectedByBytesChange(space, range, current)) {
return;
}
- doTrack();
+ doTrack(TrackCause.DB_CHANGE);
}
private void stackChanged(TraceStack stack) {
@@ -79,7 +83,7 @@ public class DebuggerTrackLocationTrait {
if (!tracker.affectedByStackChange(stack, current)) {
return;
}
- doTrack();
+ doTrack(TrackCause.DB_CHANGE);
}
}
@@ -188,11 +192,11 @@ public class DebuggerTrackLocationTrait {
public void setSpec(LocationTrackingSpec spec) {
if (action == null) {
// It might if the client doesn't need a new button, e.g., TraceDiff
- doSetSpec(spec);
+ doSetSpec(spec, TrackCause.SPEC_CHANGE_API);
}
else if (!hasSpec(spec)) {
Msg.warn(this, "No action state for given tracking spec: " + spec);
- doSetSpec(spec);
+ doSetSpec(spec, TrackCause.SPEC_CHANGE_API);
}
else {
action.setCurrentActionStateByUserData(spec);
@@ -234,21 +238,21 @@ public class DebuggerTrackLocationTrait {
}
protected void clickedSpecButton(ActionContext ctx) {
- doTrack();
+ doTrack(TrackCause.USER);
}
protected void clickedSpecMenu(ActionState newState,
EventTrigger trigger) {
- doSetSpec(newState.getUserData());
+ doSetSpec(newState.getUserData(), TrackCause.USER);
}
- protected void doSetSpec(LocationTrackingSpec spec) {
+ protected void doSetSpec(LocationTrackingSpec spec, TrackCause cause) {
if (this.spec != spec) {
this.spec = spec;
this.tracker = spec.getTracker();
specChanged(spec);
}
- doTrack();
+ doTrack(cause);
}
protected ProgramLocation computeTrackedLocation() {
@@ -282,9 +286,15 @@ public class DebuggerTrackLocationTrait {
return spec.getLocationLabel() + " = " + trackedLocation.getByteAddress();
}
- protected void doTrack() {
+ protected void doTrack(TrackCause cause) {
try {
- trackedLocation = computeTrackedLocation();
+ ProgramLocation newLocation = computeTrackedLocation();
+ if (Objects.equals(newLocation, trackedLocation)) {
+ if (cause == TrackCause.DB_CHANGE || cause == TrackCause.EMU_PATCH) {
+ return;
+ }
+ }
+ trackedLocation = newLocation;
locationTracked();
}
catch (Throwable ex) {
@@ -315,11 +325,12 @@ public class DebuggerTrackLocationTrait {
if (doListeners) {
removeOldListeners();
}
+ boolean isPatch = current.differsOnlyByPatch(coordinates);
current = coordinates;
if (doListeners) {
addNewListeners();
}
- doTrack();
+ doTrack(isPatch ? TrackCause.EMU_PATCH : TrackCause.NAVIGATION);
}
public void writeConfigState(SaveState saveState) {
diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProvider.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProvider.java
index 1341fe7b7c..c2c8e4a842 100644
--- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProvider.java
+++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/listing/DebuggerListingProvider.java
@@ -235,7 +235,7 @@ public class DebuggerListingProvider extends CodeViewerProvider {
super(DebuggerListingProvider.this.tool, DebuggerListingProvider.this.plugin,
DebuggerListingProvider.this);
- getListingPanel().addIndexMapChangeListener(e -> this.doTrack());
+ getListingPanel().addIndexMapChangeListener(e -> this.doTrack(TrackCause.DB_CHANGE));
}
@Override
diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/AbstractQueryTablePanel.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/AbstractQueryTablePanel.java
index 249aab470a..8130d5a884 100644
--- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/AbstractQueryTablePanel.java
+++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/model/AbstractQueryTablePanel.java
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -90,7 +90,7 @@ public abstract class AbstractQueryTablePanel {
}
return result;
}
+
+ public boolean differsOnlyByPatch(Sequence that) {
+ int size = this.steps.size();
+ if (size == that.steps.size()) {
+ if (size == 0) {
+ return true;
+ }
+ if (!this.steps.subList(0, size - 1).equals(that.steps.subList(0, size - 1))) {
+ return false;
+ }
+ Step thisLast = this.steps.getLast();
+ Step thatLast = that.steps.getLast();
+ return thisLast.equals(thatLast) ||
+ thisLast instanceof PatchStep && thatLast instanceof PatchStep;
+ }
+ if (size == that.steps.size() - 1) {
+ Step thatLast = that.steps.getLast();
+ return thatLast instanceof PatchStep;
+ }
+ return false;
+ }
}
diff --git a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/schedule/TraceSchedule.java b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/schedule/TraceSchedule.java
index ea703ad8ea..02c8b3a49a 100644
--- a/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/schedule/TraceSchedule.java
+++ b/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/model/time/schedule/TraceSchedule.java
@@ -673,4 +673,20 @@ public class TraceSchedule implements Comparable {
public TraceSchedule assumeRecorded() {
return new TraceSchedule(snap, steps, pSteps, Source.RECORD);
}
+
+ public boolean differsOnlyByPatch(TraceSchedule that) {
+ if (this.snap != that.snap) {
+ return false;
+ }
+ if (this.pSteps.isNop() != that.pSteps.isNop()) {
+ return false;
+ }
+ if (this.pSteps.isNop()) {
+ return this.steps.differsOnlyByPatch(that.steps);
+ }
+ if (!this.steps.equals(that.steps)) {
+ return false;
+ }
+ return this.pSteps.differsOnlyByPatch(that.pSteps);
+ }
}
diff --git a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/model/time/schedule/TraceScheduleTest.java b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/model/time/schedule/TraceScheduleTest.java
index a0eb1fbe85..721308b212 100644
--- a/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/model/time/schedule/TraceScheduleTest.java
+++ b/Ghidra/Debug/Framework-TraceModeling/src/test/java/ghidra/trace/model/time/schedule/TraceScheduleTest.java
@@ -470,4 +470,37 @@ public class TraceScheduleTest extends AbstractGhidraHeadlessIntegrationTest {
"t0-{r0=0x200000001};t0-{r1l=0x3}", time.toString());
}
}
+
+ @Test
+ public void testDiffersOnlyByPatch() throws Exception {
+ assertTrue(TraceSchedule.parse("1").differsOnlyByPatch(TraceSchedule.parse("1")));
+ assertTrue(TraceSchedule.parse("1:1").differsOnlyByPatch(TraceSchedule.parse("1:1")));
+ assertTrue(TraceSchedule.parse("1:1.1").differsOnlyByPatch(TraceSchedule.parse("1:1.1")));
+ assertTrue(TraceSchedule.parse("1:1;{r0=1}")
+ .differsOnlyByPatch(TraceSchedule.parse("1:1;{r0=1}")));
+ assertTrue(TraceSchedule.parse("1:1.1;{r0=1}")
+ .differsOnlyByPatch(TraceSchedule.parse("1:1.1;{r0=1}")));
+
+ assertFalse(TraceSchedule.parse("1").differsOnlyByPatch(TraceSchedule.parse("1:1")));
+ assertFalse(TraceSchedule.parse("1:1").differsOnlyByPatch(TraceSchedule.parse("1")));
+
+ assertFalse(TraceSchedule.parse("1:1").differsOnlyByPatch(TraceSchedule.parse("1:2")));
+ assertFalse(TraceSchedule.parse("1:2").differsOnlyByPatch(TraceSchedule.parse("1:1")));
+
+ assertFalse(TraceSchedule.parse("1:1").differsOnlyByPatch(TraceSchedule.parse("1:1.1")));
+ assertFalse(TraceSchedule.parse("1:1.1").differsOnlyByPatch(TraceSchedule.parse("1:1")));
+
+ assertTrue(TraceSchedule.parse("1").differsOnlyByPatch(TraceSchedule.parse("1:{r0=1}")));
+ assertFalse(TraceSchedule.parse("1:{r0=1}").differsOnlyByPatch(TraceSchedule.parse("1")));
+
+ assertTrue(
+ TraceSchedule.parse("1:1").differsOnlyByPatch(TraceSchedule.parse("1:1;{r0=1}")));
+ assertFalse(
+ TraceSchedule.parse("1:1;{r0=1}").differsOnlyByPatch(TraceSchedule.parse("1:1")));
+
+ assertTrue(
+ TraceSchedule.parse("1:1.1").differsOnlyByPatch(TraceSchedule.parse("1:1.1;{r0=1}")));
+ assertFalse(
+ TraceSchedule.parse("1:1.1;{r0=1}").differsOnlyByPatch(TraceSchedule.parse("1:1.1")));
+ }
}
diff --git a/Ghidra/Test/DebuggerIntegrationTest/src/screen/java/ghidraclass/debugger/screenshot/TutorialDebuggerScreenShots.java b/Ghidra/Test/DebuggerIntegrationTest/src/screen/java/ghidraclass/debugger/screenshot/TutorialDebuggerScreenShots.java
index 3afc608b8d..b978acc640 100644
--- a/Ghidra/Test/DebuggerIntegrationTest/src/screen/java/ghidraclass/debugger/screenshot/TutorialDebuggerScreenShots.java
+++ b/Ghidra/Test/DebuggerIntegrationTest/src/screen/java/ghidraclass/debugger/screenshot/TutorialDebuggerScreenShots.java
@@ -34,6 +34,7 @@ import docking.action.DockingActionIf;
import docking.widgets.fieldpanel.FieldPanel;
import generic.Unique;
import generic.jar.ResourceFile;
+import ghidra.GhidraTestApplicationLayout;
import ghidra.app.cmd.disassemble.DisassembleCommand;
import ghidra.app.context.ProgramLocationActionContext;
import ghidra.app.decompiler.component.DecompilerPanel;
@@ -109,6 +110,7 @@ import ghidra.util.Msg;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.ConsoleTaskMonitor;
import help.screenshot.GhidraScreenShotGenerator;
+import utility.application.ApplicationLayout;
public class TutorialDebuggerScreenShots extends GhidraScreenShotGenerator
implements AsyncTestUtils {
@@ -145,6 +147,18 @@ public class TutorialDebuggerScreenShots extends GhidraScreenShotGenerator
}
};
+ @Override
+ protected ApplicationLayout createApplicationLayout() throws IOException {
+ return new GhidraTestApplicationLayout(new File(getTestDirectoryPath())) {
+ @Override
+ protected Set getDependentModulePatterns() {
+ Set patterns = super.getDependentModulePatterns();
+ patterns.add("Debugger-agent");
+ return patterns;
+ }
+ };
+ }
+
@Override
protected TestEnv newTestEnv() throws Exception {
return env = new MyTestEnv("DebuggerCourse");
@@ -734,7 +748,7 @@ public class TutorialDebuggerScreenShots extends GhidraScreenShotGenerator
mappings.addModuleMappings(proposal.computeMap().values(), monitor, true);
}
- waitForCondition(() -> flatDbg.translateDynamicToStatic(dynAddr) != null);
+ //waitForCondition(() -> flatDbg.translateDynamicToStatic(dynAddr) != null);
runSwing(() -> tool.setSize(1920, 1080));
captureProvider(DebuggerStaticMappingProvider.class);
diff --git a/GhidraDocs/GhidraClass/Debugger/A1-GettingStarted.html b/GhidraDocs/GhidraClass/Debugger/A1-GettingStarted.html
index 10ce5c8023..ebb31ae6ed 100644
--- a/GhidraDocs/GhidraClass/Debugger/A1-GettingStarted.html
+++ b/GhidraDocs/GhidraClass/Debugger/A1-GettingStarted.html
@@ -152,12 +152,16 @@ id="toc-customized-launching">Customized Launching
Exercise: Launch with
Command-line Help
-Attaching
-Exercise:
-Attach
+Attaching
+
+Exercise:
+Attach
+Troubleshooting
+
@@ -453,13 +457,14 @@ target waits for input.
Run termmines in a terminal outside of Ghidra with the
desired command-line parameters.
In the Ghidra Debugger, use the Launch button
-drop-down and select Configured and Launch termmines using… →
-raw gdb. The “raw” connector will give us a GDB session without
-a target.
+drop-down and select Configure and Launch termmines using… →
+gdb.
+Clear the Image field to configure a GDB session
+without a target.
Ghidra needs to know the location of gdb and the architecture of the
intended target. The defaults are correct for 64-bit x86 targets using
-the system’s copy of GDB. Probably, you can just click
-Launch.
+the system’s copy of GDB.
+Click Launch.
In the Model window (to the left), expand the
Available node.
In the filter box, type termmines.
@@ -467,6 +472,17 @@ the system’s copy of GDB. Probably, you can just click
you prefer, note the PID, e.g. 1234, then in the
Terminal type, e.g., attach 1234.
+TIP: In later exercises, you may use the
+Reset button to re-populate the default value for the
+Image field. Be sure to change Run
+Command back to “start”, though.
+
+Troubleshooting
+If the Model window is blank, check for a “noname”
+tab in the Dynamic Listing, and click it.
+If the Model window seems incomplete after
+attaching, check that its Filter box is cleared.
+
Exercise: Attach
@@ -476,7 +492,7 @@ in read you have completed this exercise. Quit GDB from the
Terminal before proceeding to the next module: A Tour of the UI
-
+
Troubleshooting
If you get Operation not permitted or similar when
trying to attach, it is likely your Linux system is configured with
diff --git a/GhidraDocs/GhidraClass/Debugger/A1-GettingStarted.md b/GhidraDocs/GhidraClass/Debugger/A1-GettingStarted.md
index 47c6dbfb15..3d2968c1a1 100644
--- a/GhidraDocs/GhidraClass/Debugger/A1-GettingStarted.md
+++ b/GhidraDocs/GhidraClass/Debugger/A1-GettingStarted.md
@@ -219,15 +219,24 @@ when using Trace RMI.
Note this technique is only possible because the target waits for input.
1. Run `termmines` in a terminal outside of Ghidra with the desired command-line parameters.
-1. In the Ghidra Debugger, use the **Launch** button drop-down and select **Configured and Launch termmines using... → raw gdb**.
- The "raw" connector will give us a GDB session without a target.
+1. In the Ghidra Debugger, use the **Launch** button drop-down and select **Configure and Launch termmines using... → gdb**.
+1. Clear the **Image** field to configure a GDB session without a target.
1. Ghidra needs to know the location of gdb and the architecture of the intended target.
The defaults are correct for 64-bit x86 targets using the system's copy of GDB.
- Probably, you can just click **Launch**.
+1. Click **Launch**.
1. In the **Model** window (to the left), expand the *Available* node.
1. In the filter box, type `termmines`.
1. Right click on the node and select **Attach**, or, if you prefer, note the PID, e.g. 1234, then in the **Terminal** type, e.g., `attach 1234`.
+**TIP**: In later exercises, you may use the **Reset** button to re-populate the default value for the **Image** field.
+Be sure to change **Run Command** back to "start", though.
+
+### Troubleshooting
+
+If the **Model** window is blank, check for a "noname" tab in the Dynamic Listing, and click it.
+
+If the **Model** window seems incomplete after attaching, check that its Filter box is cleared.
+
## Exercise: Attach
Try attaching on your own, if you have not already.
diff --git a/GhidraDocs/GhidraClass/Debugger/A2-UITour.html b/GhidraDocs/GhidraClass/Debugger/A2-UITour.html
index 797c932b50..4835a64152 100644
--- a/GhidraDocs/GhidraClass/Debugger/A2-UITour.html
+++ b/GhidraDocs/GhidraClass/Debugger/A2-UITour.html
@@ -312,7 +312,10 @@ forward a single instruction each time you press it. Also notice that
the Static Listing moves with the Dynamic Listing. You may navigate in
either listing, and so long as there is a corresponding location in the
other, the two will stay synchronized. You may also open the Decompiler
-just as you would in the CodeBrowser, and it will stay in sync too.
+just as you would in the CodeBrowser, and it will stay in sync too.
+TIP: If you get lost in memory, you can seek back to
+the program counter by double-clicking “pc = …” in the top right of the
+listing.
When you have clicked
Step Into a sufficient number of
times, you should end up in a subroutine. You can click ![]()
K on the keyboard, or
double-click its icon in the margin.
From the Model window, expand the Breakpoints node and
double-click a breakpoint, or select one with the keyboard and press
-ENTER.
+ENTER. For GDB, this must be done from the
+top-level Breakpoints node, not the one subordinate to the
+inferior.
From the Breakpoints window, single-click the breakpoint’s status
icon, right-click an entry and select a toggle action, or create a
selection and use a toggling action from the local toolbar. Either panel
@@ -340,7 +342,8 @@ synchronized after importing libc
Troubleshooting
If it seems nothing has changed, except now you have a second program
-database open, then the new module may not be successfully mapped.
+database open, then the new module may not be successfully mapped. Try
+one or more of the following:
- Re-check the Debug Console window and verify the note has been
removed.
@@ -349,6 +352,9 @@ system, so the name of the module and the name of the program database
do not match.
Ensure that libc is the current program (tab) in the
Static Listing.
+Wait for auto-analysis of libc to complete. Yeah, it
+may take a moment, but auto-mapping is queued as a background task, and
+so it cannot map things until auto-analysis is done.
In the Modules window, right-click on libc, and select
Map Module to libc. (Names and titles will likely
differ.)
@@ -446,7 +452,7 @@ boards for any termmines session.
Write a program that takes a seed from the user and prints a diagram
of the first game board with the mines indicated. Optionally, have it
print each subsequent game board when the user presses
-ENTER. Check your work by re-launching
+ENTER. Check your work by re-launching
termmines, capturing its seed, inputting it into your
program, and then winning the game. Optionally, win 2 more games in the
same session.
diff --git a/GhidraDocs/GhidraClass/Debugger/A3-Breakpoints.md b/GhidraDocs/GhidraClass/Debugger/A3-Breakpoints.md
index d3d1750c82..ebf3c86fbd 100644
--- a/GhidraDocs/GhidraClass/Debugger/A3-Breakpoints.md
+++ b/GhidraDocs/GhidraClass/Debugger/A3-Breakpoints.md
@@ -96,6 +96,7 @@ There are several ways to toggle a breakpoint:
1. In any listing, as in setting a breakpoint, right-click and select a toggle action, press **`K`** on the keyboard, or double-click its icon in the margin.
1. From the Model window, expand the *Breakpoints* node and double-click a breakpoint, or select one with the keyboard and press **`ENTER`**.
+ For GDB, this must be done from the top-level *Breakpoints* node, not the one subordinate to the *inferior*.
1. From the Breakpoints window, single-click the breakpoint's status icon, right-click an entry and select a toggle action, or create a selection and use a toggling action from the local toolbar.
Either panel works, but the top panel is preferred to keep the breakpoints consistent.
The local toolbar also has actions for toggling all breakpoints in the session.
@@ -138,10 +139,13 @@ Once imported, the Breakpoints window should update to reflect the static addres
#### Troubleshooting
If it seems nothing has changed, except now you have a second program database open, then the new module may not be successfully mapped.
+Try one or more of the following:
1. Re-check the Debug Console window and verify the note has been removed.
1. If not, it might be because the module is symlinked in the file system, so the name of the module and the name of the program database do not match.
1. Ensure that `libc` is the current program (tab) in the Static Listing.
+1. Wait for auto-analysis of `libc` to complete.
+ Yeah, it may take a moment, but auto-mapping is queued as a background task, and so it cannot map things until auto-analysis is done.
1. In the Modules window, right-click on `libc`, and select **Map Module to libc**. (Names and titles will likely differ.)
### Capturing the Random Seed
@@ -214,6 +218,6 @@ Because, as we have now confirmed, `termmines` is importing its random number ge
Further, because we can capture the seed, and we know the placement algorithm, we can perfectly replicate the sequence of game boards for any `termmines` session.
Write a program that takes a seed from the user and prints a diagram of the first game board with the mines indicated.
-Optionally, have it print each subsequent game board when the user presses **ENTER**.
+Optionally, have it print each subsequent game board when the user presses **`ENTER`**.
Check your work by re-launching `termmines`, capturing its seed, inputting it into your program, and then winning the game.
Optionally, win 2 more games in the same session.
diff --git a/GhidraDocs/GhidraClass/Debugger/A4-MachineState.html b/GhidraDocs/GhidraClass/Debugger/A4-MachineState.html
index 31bd698081..6fc4a3ca2a 100644
--- a/GhidraDocs/GhidraClass/Debugger/A4-MachineState.html
+++ b/GhidraDocs/GhidraClass/Debugger/A4-MachineState.html
@@ -195,8 +195,8 @@ pointer there, just like you would in the Static Listing. You can now
navigate to that address by double-clicking it. To return to the stack
pointer, you can use the back arrow in the global toolbar, you can click
the
Track
-Location button, or you can double-click the sp = [Address]
-label in the top right of the Dynamic Listing.
+Location button, or you can double-click the “sp = …” label in the top
+right of the Dynamic Listing.
To examine a more complicated stack segment, we will break at
rand. Ensure your breakpoint at rand is
enabled and press
Resume.
@@ -450,7 +450,7 @@ address is into main, you could use
href="../../../Ghidra/Features/Decompiler/src/main/doc/sleigh.xml">Sleigh
documentation.
Sleigh is a bit unconventional in that its operators are typed rather
-than its variables. All variables are fix-length bit vectors. Their
+than its variables. All variables are fixed-length bit vectors. Their
sizes are specified in bytes, but they have no other type
information.
diff --git a/GhidraDocs/GhidraClass/Debugger/A4-MachineState.md b/GhidraDocs/GhidraClass/Debugger/A4-MachineState.md
index 05341d1a11..0ae58a637e 100644
--- a/GhidraDocs/GhidraClass/Debugger/A4-MachineState.md
+++ b/GhidraDocs/GhidraClass/Debugger/A4-MachineState.md
@@ -68,7 +68,7 @@ Since the target has just entered `main`, we should expect a return address at t
With your cursor at the stack pointer, press **`P`** to place a pointer there, just like
you would in the Static Listing.
You can now navigate to that address by double-clicking it.
-To return to the stack pointer, you can use the back arrow in the global toolbar, you can click the  Track Location button, or you can double-click the `sp = [Address]` label in the top right of the Dynamic Listing.
+To return to the stack pointer, you can use the back arrow in the global toolbar, you can click the  Track Location button, or you can double-click the "sp = ..." label in the top right of the Dynamic Listing.
To examine a more complicated stack segment, we will break at `rand`.
Ensure your breakpoint at `rand` is enabled and press  Resume.
@@ -244,7 +244,7 @@ For example, to see how far a return address is into `main`, you could use `*:8
For the complete specification, see the Semantic Section in the [Sleigh documentation](../../../Ghidra/Features/Decompiler/src/main/doc/sleigh.xml).
Sleigh is a bit unconventional in that its operators are typed rather than its variables.
-All variables are fix-length bit vectors.
+All variables are fixed-length bit vectors.
Their sizes are specified in bytes, but they have no other type information.
### Variables and Constants
diff --git a/GhidraDocs/GhidraClass/Debugger/B2-Emulation.html b/GhidraDocs/GhidraClass/Debugger/B2-Emulation.html
index 10d18388af..0d95b521f4 100644
--- a/GhidraDocs/GhidraClass/Debugger/B2-Emulation.html
+++ b/GhidraDocs/GhidraClass/Debugger/B2-Emulation.html
@@ -676,8 +676,7 @@ Invalidate Emulator Cache.
Resume.
Stubbing any remaining external calls is left as an exercise. You are
-successful when the emulator crashes with
-pc = 00000000.
+successful when the emulator crashes with “pc = 00000000”.
Clear or disable your breakpoint and invalidate the emulator cache
again before proceeding to the next technique.
@@ -718,7 +717,7 @@ write the Sleigh code to mimic a RET. As with the
CALL override technique, you must now invalidate the
emulator cache and resume. Stubbing any remaining external functions is
left as an exercise. You are successful when the emulator crashes with
-pc = 00000000.
+“pc = 00000000”.
diff --git a/GhidraDocs/GhidraClass/Debugger/B2-Emulation.md b/GhidraDocs/GhidraClass/Debugger/B2-Emulation.md
index d6f7bc924c..f44332df2b 100644
--- a/GhidraDocs/GhidraClass/Debugger/B2-Emulation.md
+++ b/GhidraDocs/GhidraClass/Debugger/B2-Emulation.md
@@ -377,7 +377,7 @@ After you have written your Sleigh code:
1. Click  **Resume**.
Stubbing any remaining external calls is left as an exercise.
-You are successful when the emulator crashes with `pc = 00000000`.
+You are successful when the emulator crashes with "pc = 00000000".
Clear or disable your breakpoint and invalidate the emulator cache again before proceeding to the next technique.
@@ -412,7 +412,7 @@ return [RIP];
Notice that we cannot just write `RET`, but instead must write the Sleigh code to mimic a `RET`.
As with the `CALL` override technique, you must now invalidate the emulator cache and resume.
Stubbing any remaining external functions is left as an exercise.
-You are successful when the emulator crashes with `pc = 00000000`.
+You are successful when the emulator crashes with "pc = 00000000".
### Wrapping Up
diff --git a/GhidraDocs/GhidraClass/Debugger/B3-Scripting.html b/GhidraDocs/GhidraClass/Debugger/B3-Scripting.html
index 963c84a982..d382eea0da 100644
--- a/GhidraDocs/GhidraClass/Debugger/B3-Scripting.html
+++ b/GhidraDocs/GhidraClass/Debugger/B3-Scripting.html
@@ -168,17 +168,14 @@ class="sourceCode numberSource java numberLines"><
protected void run() throws Exception {
}
}
-NOTE: The scripting API has been refactored a little
-since the transition from Recorder-based to TraceRmi-based targets.
-Parts of the API that are back-end agnostic are accessible from the
+
NOTE: The scripting API has been refactored since
+the transition from Recorder-based to TraceRmi-based targets. Parts of
+the API that are back-end agnostic are accessible from the
FlatDebuggerAPI interface. Parts of the API that require a
-specific back end are in FlatDebuggerRmiAPI and
-FlatDebuggerRecorderAPI, the latter of which is deprecated.
-If a script written for version 11.0.2 or prior is not compiling, it can
-most likely be patched up by changing
-implements FlatDebuggerAPI to
-implements FlatDebuggerRecorderAPI, but we recommend
-porting it to use implements FlatDebuggerRmiAPI.
+specific back end are in FlatDebuggerRmiAPI. The old
+FlatDebuggerRecorderAPI was removed in Ghidra 11.3, and
+scripts needing it should be ported to
+FlatDebuggerRmiAPI.
Technically, the Debugger’s “deep” API is accessible to scripts;
however, the flat API is preferred for scripting. Also, the flat API is
usually more stable than the deep API. However, because the dynamic
diff --git a/GhidraDocs/GhidraClass/Debugger/B3-Scripting.md b/GhidraDocs/GhidraClass/Debugger/B3-Scripting.md
index 1cc75193e3..bd54ccfbcc 100644
--- a/GhidraDocs/GhidraClass/Debugger/B3-Scripting.md
+++ b/GhidraDocs/GhidraClass/Debugger/B3-Scripting.md
@@ -24,10 +24,10 @@ public class DemoDebuggerScript extends GhidraScript implements FlatDebuggerAPI
}
```
-**NOTE**: The scripting API has been refactored a little since the transition from Recorder-based to TraceRmi-based targets.
+**NOTE**: The scripting API has been refactored since the transition from Recorder-based to TraceRmi-based targets.
Parts of the API that are back-end agnostic are accessible from the `FlatDebuggerAPI` interface.
-Parts of the API that require a specific back end are in `FlatDebuggerRmiAPI` and `FlatDebuggerRecorderAPI`, the latter of which is deprecated.
-If a script written for version 11.0.2 or prior is not compiling, it can most likely be patched up by changing `implements FlatDebuggerAPI` to `implements FlatDebuggerRecorderAPI`, but we recommend porting it to use `implements FlatDebuggerRmiAPI`.
+Parts of the API that require a specific back end are in `FlatDebuggerRmiAPI`.
+The old `FlatDebuggerRecorderAPI` was removed in Ghidra 11.3, and scripts needing it should be ported to `FlatDebuggerRmiAPI`.
Technically, the Debugger's "deep" API is accessible to scripts; however, the flat API is preferred for scripting.
Also, the flat API is usually more stable than the deep API.
diff --git a/GhidraDocs/GhidraClass/Debugger/images/GettingStarted_LaunchGDBDialog.png b/GhidraDocs/GhidraClass/Debugger/images/GettingStarted_LaunchGDBDialog.png
index cb344c8936..2d4dbd089d 100644
Binary files a/GhidraDocs/GhidraClass/Debugger/images/GettingStarted_LaunchGDBDialog.png and b/GhidraDocs/GhidraClass/Debugger/images/GettingStarted_LaunchGDBDialog.png differ
diff --git a/GhidraDocs/GhidraClass/Debugger/images/MemoryMap_StaticMappingAfterLaunch.png b/GhidraDocs/GhidraClass/Debugger/images/MemoryMap_StaticMappingAfterLaunch.png
index c42a096910..3ad54df2ab 100644
Binary files a/GhidraDocs/GhidraClass/Debugger/images/MemoryMap_StaticMappingAfterLaunch.png and b/GhidraDocs/GhidraClass/Debugger/images/MemoryMap_StaticMappingAfterLaunch.png differ
diff --git a/GhidraDocs/GhidraClass/Debugger/images/RemoteTargets_GdbPlusGdbserverViaSsh.png b/GhidraDocs/GhidraClass/Debugger/images/RemoteTargets_GdbPlusGdbserverViaSsh.png
index a2a6719379..9245b8aa28 100644
Binary files a/GhidraDocs/GhidraClass/Debugger/images/RemoteTargets_GdbPlusGdbserverViaSsh.png and b/GhidraDocs/GhidraClass/Debugger/images/RemoteTargets_GdbPlusGdbserverViaSsh.png differ
diff --git a/GhidraDocs/GhidraClass/Debugger/images/RemoteTargets_GdbViaSsh.png b/GhidraDocs/GhidraClass/Debugger/images/RemoteTargets_GdbViaSsh.png
index 5ced77f1c2..fa4f9c36ef 100644
Binary files a/GhidraDocs/GhidraClass/Debugger/images/RemoteTargets_GdbViaSsh.png and b/GhidraDocs/GhidraClass/Debugger/images/RemoteTargets_GdbViaSsh.png differ