Run-tests: Fix/implement --update; avoid stdout patching.

The update has never worked reliably, but with the separation
of the `sed` and `diff` it is getting much better now.

Avoid stdout patching to improve --update mode further.
The tests still have stdout that differs based on flags.
Support those by having multiple (full) expected files.

Test: test.py -r --all-target --all-jvmti --all-prebuild \
              -t 1931 -t 1932 -t 1936 -t 1950 -t 1953 \
              -t 1954 -t 1955 -t 1956 -t 1969 -t 909
Change-Id: I070037717f9964755492b42b6efd52179deb4125
diff --git a/test/1931-monitor-events/expected-stdout.jvm.txt b/test/1931-monitor-events/expected-stdout.jvm.txt
new file mode 100644
index 0000000..e26d459
--- /dev/null
+++ b/test/1931-monitor-events/expected-stdout.jvm.txt
@@ -0,0 +1,30 @@
+Testing contended locking.
+Locker thread 1 for NamedLock[Lock testLock] contended-LOCKING NamedLock[Lock testLock]
+Locker thread 1 for NamedLock[Lock testLock] LOCKED NamedLock[Lock testLock]
+Testing park.
+Testing monitor wait.
+Locker thread 2 for NamedLock[Lock testWait] start-monitor-wait NamedLock[Lock testWait] timeout: 0
+Locker thread 2 for NamedLock[Lock testWait] monitor-waited NamedLock[Lock testWait] timed_out: false
+Testing monitor timed wait.
+Locker thread 4 for NamedLock[Lock testTimedWait] start-monitor-wait NamedLock[Lock testTimedWait] timeout: 3600000
+Locker thread 4 for NamedLock[Lock testTimedWait] monitor-waited NamedLock[Lock testTimedWait] timed_out: false
+Testing monitor timed with timeout.
+Waiting for 10 seconds.
+Locker thread 6 for NamedLock[Lock testTimedWaitTimeout] start-monitor-wait NamedLock[Lock testTimedWaitTimeout] timeout: 10000
+Locker thread 6 for NamedLock[Lock testTimedWaitTimeout] monitor-waited NamedLock[Lock testTimedWaitTimeout] timed_out: true
+Wait finished with timeout.
+Waiting on an unlocked monitor.
+Unlocked wait thread: start-monitor-wait NamedLock[Lock testUnlockedWait] timeout: 0
+Caught exception: java.lang.reflect.InvocationTargetException
+	Caused by: class java.lang.IllegalMonitorStateException
+Waiting with an illegal argument (negative timeout)
+Locker thread 7 for NamedLock[Lock testIllegalWait] start-monitor-wait NamedLock[Lock testIllegalWait] timeout: -100
+Caught exception: art.Monitors$TestException: Exception thrown by other thread!
+	Caused by: art.Monitors$TestException: Got an error while performing action TIMED_WAIT
+	Caused by: class java.lang.IllegalArgumentException
+Interrupt a monitor being waited on.
+Locker thread 8 for NamedLock[Lock testInteruptWait] start-monitor-wait NamedLock[Lock testInteruptWait] timeout: 0
+Locker thread 8 for NamedLock[Lock testInteruptWait] monitor-waited NamedLock[Lock testInteruptWait] timed_out: false
+Caught exception: art.Monitors$TestException: Exception thrown by other thread!
+	Caused by: art.Monitors$TestException: Got an error while performing action WAIT
+	Caused by: class java.lang.InterruptedException
diff --git a/test/1931-monitor-events/jvm-expected.patch b/test/1931-monitor-events/jvm-expected.patch
deleted file mode 100644
index 7595b14..0000000
--- a/test/1931-monitor-events/jvm-expected.patch
+++ /dev/null
@@ -1,3 +0,0 @@
-5,6d4
-< ParkThread start-monitor-wait NamedLock[Parking blocker object] timeout: 1
-< ParkThread monitor-waited NamedLock[Parking blocker object] timed_out: true
diff --git a/test/1931-monitor-events/run.py b/test/1931-monitor-events/run.py
index f0d101d..6c5d4ad 100644
--- a/test/1931-monitor-events/run.py
+++ b/test/1931-monitor-events/run.py
@@ -18,6 +18,6 @@
 def run(ctx, args):
   ctx.default_run(args, jvmti=True)
 
-  # Art sends events for park/unpark, and the RI doesn't. Remove it from the expected output.
+  # Art sends events for park/unpark, and the RI doesn't.
   if args.jvm:
-    ctx.run(fr"patch -p0 expected-stdout.txt < jvm-expected.patch >/dev/null")
+    ctx.expected_stdout = ctx.expected_stdout.with_suffix(".jvm.txt")
diff --git a/test/1932-monitor-events-misc/expected-stdout.jvm.txt b/test/1932-monitor-events-misc/expected-stdout.jvm.txt
new file mode 100644
index 0000000..b2b051e
--- /dev/null
+++ b/test/1932-monitor-events-misc/expected-stdout.jvm.txt
@@ -0,0 +1,105 @@
+Testing contended locking where lock is released before callback ends.
+Locker thread 1 for NamedLock[Lock testLockUncontend] contended-LOCKING NamedLock[Lock testLockUncontend]
+Releasing NamedLock[Lock testLockUncontend] during monitorEnter event.
+Locker thread 1 for NamedLock[Lock testLockUncontend] LOCKED NamedLock[Lock testLockUncontend]
+Testing throwing exceptions in monitor_enter
+Locker thread 3 for NamedLock[Lock testLockThrowEnter] contended-LOCKING NamedLock[Lock testLockThrowEnter]
+Throwing exception in MonitorEnter
+Locker thread 3 for NamedLock[Lock testLockThrowEnter] LOCKED NamedLock[Lock testLockThrowEnter]
+Caught exception: art.Monitors$TestException: Exception thrown by other thread!
+	Caused by: art.Monitors$TestException: throwing exception during monitorEnter of NamedLock[Lock testLockThrowEnter]
+lock state is: MonitorUsage{ monitor: NamedLock[Lock testLockThrowEnter], owner: <NULL>, entryCount: 0, waiters: [], notify_waiters: [] }
+Testing throwing exceptions in monitor_entered
+Locker thread 5 for NamedLock[Lock testLockThrowEntered] contended-LOCKING NamedLock[Lock testLockThrowEntered]
+Locker thread 5 for NamedLock[Lock testLockThrowEntered] LOCKED NamedLock[Lock testLockThrowEntered]
+Throwing exception in MonitorEntered
+Caught exception: art.Monitors$TestException: Exception thrown by other thread!
+	Caused by: art.Monitors$TestException: throwing exception during monitorEntered of NamedLock[Lock testLockThrowEntered]
+lock state is: MonitorUsage{ monitor: NamedLock[Lock testLockThrowEntered], owner: <NULL>, entryCount: 0, waiters: [], notify_waiters: [] }
+Testing throwing exceptions in both monitorEnter & MonitorEntered
+Locker thread 7 for NamedLock[Lock testLockThrowBoth] contended-LOCKING NamedLock[Lock testLockThrowBoth]
+Throwing exception in MonitorEnter
+Locker thread 7 for NamedLock[Lock testLockThrowBoth] LOCKED NamedLock[Lock testLockThrowBoth]
+Throwing exception in MonitorEntered
+Caught exception: art.Monitors$TestException: Exception thrown by other thread!
+	Caused by: art.Monitors$TestException: throwing exception during monitorEntered of NamedLock[Lock testLockThrowBoth]
+lock state is: MonitorUsage{ monitor: NamedLock[Lock testLockThrowBoth], owner: <NULL>, entryCount: 0, waiters: [], notify_waiters: [] }
+Testing throwing exception in MonitorWait event
+Locker thread 8 for NamedLock[Lock testThrowWait] start-monitor-wait NamedLock[Lock testThrowWait] timeout: 0
+Throwing exception in MonitorWait
+Locker thread 8 for NamedLock[Lock testThrowWait] monitor-waited NamedLock[Lock testThrowWait] timed_out: false
+Caught exception: art.Monitors$TestException: Exception thrown by other thread!
+	Caused by: art.Monitors$TestException: throwing exception during MonitorWait of NamedLock[Lock testThrowWait]
+lock state is: MonitorUsage{ monitor: NamedLock[Lock testThrowWait], owner: <NULL>, entryCount: 0, waiters: [], notify_waiters: [] }
+Testing throwing exception in MonitorWait event with illegal aruments
+Locker thread 9 for NamedLock[Lock testThrowIllegalWait] start-monitor-wait NamedLock[Lock testThrowIllegalWait] timeout: -100000
+Throwing exception in MonitorWait timeout = -100000
+Caught exception: art.Monitors$TestException: Exception thrown by other thread!
+	Caused by: art.Monitors$TestException: throwing exception during monitorWait of NamedLock[Lock testThrowIllegalWait]
+lock state is: MonitorUsage{ monitor: NamedLock[Lock testThrowIllegalWait], owner: <NULL>, entryCount: 0, waiters: [], notify_waiters: [] }
+Testing throwing exception in MonitorWaited event
+Locker thread 10 for NamedLock[Lock testThrowWaited] start-monitor-wait NamedLock[Lock testThrowWaited] timeout: 0
+Locker thread 10 for NamedLock[Lock testThrowWaited] monitor-waited NamedLock[Lock testThrowWaited] timed_out: false
+Throwing exception in MonitorWaited
+Caught exception: art.Monitors$TestException: Exception thrown by other thread!
+	Caused by: art.Monitors$TestException: throwing exception during monitorWaited of NamedLock[Lock testThrowWaited]
+lock state is: MonitorUsage{ monitor: NamedLock[Lock testThrowWaited], owner: <NULL>, entryCount: 0, waiters: [], notify_waiters: [] }
+Testing throwing exception in MonitorWaited event caused by timeout
+Locker thread 12 for NamedLock[Lock testThrowWaitedTimeout] start-monitor-wait NamedLock[Lock testThrowWaitedTimeout] timeout: 5000
+Locker thread 12 for NamedLock[Lock testThrowWaitedTimeout] monitor-waited NamedLock[Lock testThrowWaitedTimeout] timed_out: true
+Throwing exception in MonitorWaited
+Caught exception: art.Monitors$TestException: Exception thrown by other thread!
+	Caused by: art.Monitors$TestException: throwing exception during monitorWaited of NamedLock[Lock testThrowWaitedTimeout]
+lock state is: MonitorUsage{ monitor: NamedLock[Lock testThrowWaitedTimeout], owner: <NULL>, entryCount: 0, waiters: [], notify_waiters: [] }
+Testing throwing exception in MonitorWaited event caused by interrupt
+Locker thread 13 for NamedLock[Lock testThrowWaitedInterrupt] start-monitor-wait NamedLock[Lock testThrowWaitedInterrupt] timeout: 0
+Locker thread 13 for NamedLock[Lock testThrowWaitedInterrupt] monitor-waited NamedLock[Lock testThrowWaitedInterrupt] timed_out: false
+Throwing exception in MonitorWaited
+Caught exception: art.Monitors$TestException: Exception thrown by other thread!
+	Caused by: art.Monitors$TestException: throwing exception during monitorWaited of NamedLock[Lock testThrowWaitedInterrupt]
+lock state is: MonitorUsage{ monitor: NamedLock[Lock testThrowWaitedInterrupt], owner: <NULL>, entryCount: 0, waiters: [], notify_waiters: [] }
+Testing ObjectMonitorInfo inside of events
+Locker thread 15 for NamedLock[Lock testMonitorInfoInEvents] contended-LOCKING NamedLock[Lock testMonitorInfoInEvents]
+Monitor usage in MonitorEnter: MonitorUsage{ monitor: NamedLock[Lock testMonitorInfoInEvents], owner: Locker thread 14 for NamedLock[Lock testMonitorInfoInEvents], entryCount: 1, waiters: [], notify_waiters: [] }
+Locker thread 15 for NamedLock[Lock testMonitorInfoInEvents] LOCKED NamedLock[Lock testMonitorInfoInEvents]
+Monitor usage in MonitorEntered: MonitorUsage{ monitor: NamedLock[Lock testMonitorInfoInEvents], owner: Locker thread 15 for NamedLock[Lock testMonitorInfoInEvents], entryCount: 1, waiters: [], notify_waiters: [] }
+Locker thread 15 for NamedLock[Lock testMonitorInfoInEvents] start-monitor-wait NamedLock[Lock testMonitorInfoInEvents] timeout: 0
+Monitor usage in MonitorWait: MonitorUsage{ monitor: NamedLock[Lock testMonitorInfoInEvents], owner: Locker thread 15 for NamedLock[Lock testMonitorInfoInEvents], entryCount: 1, waiters: [], notify_waiters: [] }
+Locker thread 15 for NamedLock[Lock testMonitorInfoInEvents] monitor-waited NamedLock[Lock testMonitorInfoInEvents] timed_out: false
+Monitor usage in MonitorWaited: MonitorUsage{ monitor: NamedLock[Lock testMonitorInfoInEvents], owner: <NULL>, entryCount: 0, waiters: [], notify_waiters: [] }
+Testing that the monitor can be stolen during the MonitorWaited event.
+Locker thread 17 for NamedLock[test testWaitEnterInterleaving] start-monitor-wait NamedLock[test testWaitEnterInterleaving] timeout: 0
+Locker thread 17 for NamedLock[test testWaitEnterInterleaving] monitor-waited NamedLock[test testWaitEnterInterleaving] timed_out: false
+locking controller3 in controller2 MonitorWaited event
+Controller3 now holds the lock the monitor wait will try to re-acquire
+Testing that we can lock and release the monitor in the MonitorWait event
+Locker thread 20 for NamedLock[test testWaitMonitorEnter] start-monitor-wait NamedLock[test testWaitMonitorEnter] timeout: 0
+In wait monitor usage: MonitorUsage{ monitor: NamedLock[test testWaitMonitorEnter], owner: Locker thread 20 for NamedLock[test testWaitMonitorEnter], entryCount: 1, waiters: [], notify_waiters: [] }
+In wait monitor usage sync: MonitorUsage{ monitor: NamedLock[test testWaitMonitorEnter], owner: Locker thread 20 for NamedLock[test testWaitMonitorEnter], entryCount: 2, waiters: [], notify_waiters: [] }
+Locker thread 20 for NamedLock[test testWaitMonitorEnter] monitor-waited NamedLock[test testWaitMonitorEnter] timed_out: false
+Testing that we can lock and release the monitor in the MonitorWaited event
+Locker thread 22 for NamedLock[test testWaitedMonitorEnter] start-monitor-wait NamedLock[test testWaitedMonitorEnter] timeout: 0
+Locker thread 22 for NamedLock[test testWaitedMonitorEnter] monitor-waited NamedLock[test testWaitedMonitorEnter] timed_out: false
+In waited monitor usage: MonitorUsage{ monitor: NamedLock[test testWaitedMonitorEnter], owner: <NULL>, entryCount: 0, waiters: [], notify_waiters: [] }
+In waited monitor usage sync: MonitorUsage{ monitor: NamedLock[test testWaitedMonitorEnter], owner: Locker thread 22 for NamedLock[test testWaitedMonitorEnter], entryCount: 1, waiters: [], notify_waiters: [] }
+Testing we can perform recursive lock in MonitorEntered
+Locker thread 25 for NamedLock[test testRecursiveMontiorEnteredLock] contended-LOCKING NamedLock[test testRecursiveMontiorEnteredLock]
+Locker thread 25 for NamedLock[test testRecursiveMontiorEnteredLock] LOCKED NamedLock[test testRecursiveMontiorEnteredLock]
+In MonitorEntered usage: MonitorUsage{ monitor: NamedLock[test testRecursiveMontiorEnteredLock], owner: Locker thread 25 for NamedLock[test testRecursiveMontiorEnteredLock], entryCount: 1, waiters: [], notify_waiters: [] }
+In MonitorEntered sync: MonitorUsage{ monitor: NamedLock[test testRecursiveMontiorEnteredLock], owner: Locker thread 25 for NamedLock[test testRecursiveMontiorEnteredLock], entryCount: 2, waiters: [], notify_waiters: [] }
+Testing the lock state if MonitorEnter throws in a native method
+NativeLockStateThrowEnter thread contended-LOCKING NamedLock[test testNativeLockStateThrowEnter]
+Unlocking controller1 in MonitorEnter
+Throwing exception in MonitorEnter
+NativeLockStateThrowEnter thread LOCKED NamedLock[test testNativeLockStateThrowEnter]
+MonitorEnter returned: -1
+Lock state is: MonitorUsage{ monitor: NamedLock[test testNativeLockStateThrowEnter], owner: NativeLockStateThrowEnter thread, entryCount: 1, waiters: [], notify_waiters: [] }
+Caught exception: art.Monitors$TestException: throwing exception during monitorEnter of NamedLock[test testNativeLockStateThrowEnter]
+Testing the lock state if MonitorEntered throws in a native method
+NativeLockStateThrowEntered thread contended-LOCKING NamedLock[test testNativeLockStateThrowEntered]
+Unlocking controller1 in MonitorEnter
+NativeLockStateThrowEntered thread LOCKED NamedLock[test testNativeLockStateThrowEntered]
+Throwing exception in MonitorEntered
+MonitorEnter returned: -1
+Lock state is: MonitorUsage{ monitor: NamedLock[test testNativeLockStateThrowEntered], owner: NativeLockStateThrowEntered thread, entryCount: 1, waiters: [], notify_waiters: [] }
+Caught exception: art.Monitors$TestException: throwing exception during monitorEntered of NamedLock[test testNativeLockStateThrowEntered]
diff --git a/test/1932-monitor-events-misc/jvm-expected.patch b/test/1932-monitor-events-misc/jvm-expected.patch
deleted file mode 100644
index f6b2285..0000000
--- a/test/1932-monitor-events-misc/jvm-expected.patch
+++ /dev/null
@@ -1,2 +0,0 @@
-29a30
-> Locker thread 8 for NamedLock[Lock testThrowWait] monitor-waited NamedLock[Lock testThrowWait] timed_out: false
diff --git a/test/1932-monitor-events-misc/run.py b/test/1932-monitor-events-misc/run.py
index 21067d0..43e66fd 100644
--- a/test/1932-monitor-events-misc/run.py
+++ b/test/1932-monitor-events-misc/run.py
@@ -18,6 +18,6 @@
 def run(ctx, args):
   ctx.default_run(args, jvmti=True)
 
-  # The RI sends an extra event that art doesn't. Add it to the expected output.
+  # The RI sends an extra event that art doesn't.
   if args.jvm:
-    ctx.run(fr"patch -p0 expected-stdout.txt < jvm-expected.patch >/dev/null")
+    ctx.expected_stdout = ctx.expected_stdout.with_suffix(".jvm.txt")
diff --git a/test/1936-thread-end-events/expected-stdout.jvm.txt b/test/1936-thread-end-events/expected-stdout.jvm.txt
new file mode 100644
index 0000000..a8e79a4
--- /dev/null
+++ b/test/1936-thread-end-events/expected-stdout.jvm.txt
@@ -0,0 +1,49 @@
+Entered public static void art.Test1936.foo()
+Thread: test-thread
+  | alive: true
+  | interrupted: false
+  | daemon: false
+  | group: java.lang.ThreadGroup[name=main,maxpri=10]
+
+Entered private void java.lang.Thread.exit()
+Thread: test-thread
+  | alive: true
+  | interrupted: false
+  | daemon: false
+  | group: java.lang.ThreadGroup[name=main,maxpri=10]
+
+Entered void java.lang.ThreadGroup.threadTerminated(java.lang.Thread)
+Thread: test-thread
+  | alive: true
+  | interrupted: false
+  | daemon: false
+  | group: java.lang.ThreadGroup[name=main,maxpri=10]
+
+Entered private void java.lang.ThreadGroup.remove(java.lang.Thread)
+Thread: test-thread
+  | alive: true
+  | interrupted: false
+  | daemon: false
+  | group: java.lang.ThreadGroup[name=main,maxpri=10]
+
+Entered public static native void java.lang.System.arraycopy(java.lang.Object,int,java.lang.Object,int,int)
+Thread: test-thread
+  | alive: true
+  | interrupted: false
+  | daemon: false
+  | group: java.lang.ThreadGroup[name=main,maxpri=10]
+
+Entered public static void art.Test1936.NotifyThreadEnd(java.lang.Thread)
+Thread: test-thread
+  | alive: true
+  | interrupted: false
+  | daemon: false
+  | group: null
+
+Entered public static void art.Test1936.foo()
+Thread: test-thread
+  | alive: true
+  | interrupted: false
+  | daemon: false
+  | group: null
+
diff --git a/test/1936-thread-end-events/jvm-expected.patch b/test/1936-thread-end-events/jvm-expected.patch
deleted file mode 100644
index ddb30a3..0000000
--- a/test/1936-thread-end-events/jvm-expected.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-7a8,14
-> Entered private void java.lang.Thread.exit()
-> Thread: test-thread
->   | alive: true
->   | interrupted: false
->   | daemon: false
->   | group: java.lang.ThreadGroup[name=main,maxpri=10]
-> 
-34c41
-<   | group: java.lang.ThreadGroup[name=main,maxpri=10]
----
->   | group: null
-41c48
-<   | group: java.lang.ThreadGroup[name=main,maxpri=10]
----
->   | group: null
diff --git a/test/1936-thread-end-events/run.py b/test/1936-thread-end-events/run.py
index 9ac67c0..3e1a8e9 100644
--- a/test/1936-thread-end-events/run.py
+++ b/test/1936-thread-end-events/run.py
@@ -19,6 +19,6 @@
   # Ask for stack traces to be dumped to a file rather than to stdout.
   ctx.default_run(args, jvmti=True)
 
-  # The RI sends an extra event that art doesn't. Add it to the expected output.
+  # The RI sends an extra event that art doesn't.
   if args.jvm:
-    ctx.run(fr"patch -p0 expected-stdout.txt < jvm-expected.patch >/dev/null")
+    ctx.expected_stdout = ctx.expected_stdout.with_suffix(".jvm.txt")
diff --git a/test/1950-unprepared-transform/expected-stdout.jvm.txt b/test/1950-unprepared-transform/expected-stdout.jvm.txt
new file mode 100644
index 0000000..cc470e1
--- /dev/null
+++ b/test/1950-unprepared-transform/expected-stdout.jvm.txt
@@ -0,0 +1,7 @@
+Redefine in ClassLoad on current thread.
+retransformClasses on an unprepared class succeeded
+Object out is: Transformed object!
+Redefine during ClassLoad on another thread.
+retransformClasses on an unprepared class succeeded
+Object out is: Transformed object!
+Redefinition thread finished.
diff --git a/test/1950-unprepared-transform/jvm-expected.patch b/test/1950-unprepared-transform/jvm-expected.patch
deleted file mode 100644
index fd0131e..0000000
--- a/test/1950-unprepared-transform/jvm-expected.patch
+++ /dev/null
@@ -1,6 +0,0 @@
-2,3c2,3
-< Trying to redefine: class Transform. Caught error class java.lang.Exception: Failed to retransform class <LTransform;> due to JVMTI_ERROR_INTERNAL
-< Object out is: NON Transformed Object
----
-> retransformClasses on an unprepared class succeeded
-> Object out is: Transformed object!
diff --git a/test/1950-unprepared-transform/run.py b/test/1950-unprepared-transform/run.py
index 82d1a0e..995bbbd 100644
--- a/test/1950-unprepared-transform/run.py
+++ b/test/1950-unprepared-transform/run.py
@@ -18,6 +18,6 @@
 def run(ctx, args):
   ctx.default_run(args, jvmti=True, app_image=False)
 
-  # The RI sends an extra event that art doesn't. Add it to the expected output.
+  # The RI sends an extra event that art doesn't.
   if args.jvm:
-    ctx.run(fr"patch -p0 expected-stdout.txt < jvm-expected.patch >/dev/null")
+    ctx.expected_stdout = ctx.expected_stdout.with_suffix(".jvm.txt")
diff --git a/test/1953-pop-frame/class-loading-expected.patch b/test/1953-pop-frame/class-loading-expected.patch
deleted file mode 100644
index 1a5eda7..0000000
--- a/test/1953-pop-frame/class-loading-expected.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-36a37,50
-> Test stopped during notifyFramePop without exception on pop of calledFunction
-> Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
-> result is StandardTestObject { cnt: 2 } base-call count: 1
-> Test stopped during notifyFramePop without exception on pop of doNothing
-> Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
-> result is StandardTestObject { cnt: 1 } base-call count: 1
-> Test stopped during notifyFramePop with exception on pop of calledFunction
-> Single call with PopFrame on ExceptionThrowTestObject { cnt: 0 } base-call-count: 0
-> art.Test1953$ExceptionThrowTestObject$TestError thrown and caught!
-> result is ExceptionThrowTestObject { cnt: 2 } base-call count: 1
-> Test stopped during notifyFramePop with exception on pop of doThrow
-> Single call with PopFrame on ExceptionCatchTestObject { cnt: 0 } base-call-count: 0
-> art.Test1953$ExceptionCatchTestObject$TestError caught in called function.
-> result is ExceptionCatchTestObject { cnt: 1 } base-call count: 1
-60a75,94
-> Test stopped during a ClassLoad event.
-> Single call with PopFrame on ClassLoadObject { cnt: 0, curClass: 0} base-call-count: 0
-> Failed to pop frame due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
-> 	art.Test1953.popFrame(Native Method)
-> 	art.Test1953.runTestOn(Test1953.java)
-> 	art.Test1953.runTestOn(Test1953.java)
-> 	art.Test1953.runTests(Test1953.java)
-> 	<Additional frames hidden>
-> TC0.foo == 1
-> result is ClassLoadObject { cnt: 1, curClass: 1} base-call count: 1
-> Test stopped during a ClassPrepare event.
-> Single call with PopFrame on ClassLoadObject { cnt: 0, curClass: 1} base-call-count: 0
-> Failed to pop frame due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
-> 	art.Test1953.popFrame(Native Method)
-> 	art.Test1953.runTestOn(Test1953.java)
-> 	art.Test1953.runTestOn(Test1953.java)
-> 	art.Test1953.runTests(Test1953.java)
-> 	<Additional frames hidden>
-> TC1.foo == 2
-> result is ClassLoadObject { cnt: 1, curClass: 2} base-call count: 1
diff --git a/test/1953-pop-frame/expected-stdout.no-jvm.txt b/test/1953-pop-frame/expected-stdout.no-jvm.txt
new file mode 100644
index 0000000..e75ea64
--- /dev/null
+++ b/test/1953-pop-frame/expected-stdout.no-jvm.txt
@@ -0,0 +1,121 @@
+Test stopped using breakpoint
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 2 } base-call count: 1
+Test stopped using breakpoint with declared synchronized function
+Single call with PopFrame on SynchronizedFunctionTestObject { cnt: 0 } base-call-count: 0
+result is SynchronizedFunctionTestObject { cnt: 2 } base-call count: 1
+Test stopped using breakpoint with synchronized block
+Single call with PopFrame on SynchronizedTestObject { cnt: 0 } base-call-count: 0
+result is SynchronizedTestObject { cnt: 2 } base-call count: 1
+Test stopped on single step
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 2 } base-call count: 1
+Test stopped on field access
+Single call with PopFrame on FieldBasedTestObject { cnt: 0, TARGET_FIELD: 0 } base-call-count: 0
+result is FieldBasedTestObject { cnt: 2, TARGET_FIELD: 10 } base-call count: 1
+Test stopped on field modification
+Single call with PopFrame on FieldBasedTestObject { cnt: 0, TARGET_FIELD: 0 } base-call-count: 0
+result is FieldBasedTestObject { cnt: 2, TARGET_FIELD: 10 } base-call count: 1
+Test stopped during Method Exit of doNothing
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 1 } base-call count: 1
+Test stopped during Method Enter of doNothing
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 1 } base-call count: 1
+Test stopped during Method Exit of calledFunction
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 2 } base-call count: 1
+Test stopped during Method Enter of calledFunction
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 1 } base-call count: 1
+Test stopped during Method Exit due to exception thrown in same function
+Single call with PopFrame on ExceptionOnceObject { cnt: 0, throwInSub: false } base-call-count: 0
+result is ExceptionOnceObject { cnt: 2, throwInSub: false } base-call count: 1
+Test stopped during Method Exit due to exception thrown in subroutine
+Single call with PopFrame on ExceptionOnceObject { cnt: 0, throwInSub: true } base-call-count: 0
+result is ExceptionOnceObject { cnt: 2, throwInSub: true } base-call count: 1
+Test stopped during notifyFramePop without exception on pop of calledFunction
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 2 } base-call count: 1
+Test stopped during notifyFramePop without exception on pop of doNothing
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 1 } base-call count: 1
+Test stopped during notifyFramePop with exception on pop of calledFunction
+Single call with PopFrame on ExceptionThrowTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionThrowTestObject$TestError thrown and caught!
+result is ExceptionThrowTestObject { cnt: 2 } base-call count: 1
+Test stopped during notifyFramePop with exception on pop of doThrow
+Single call with PopFrame on ExceptionCatchTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionCatchTestObject$TestError caught in called function.
+result is ExceptionCatchTestObject { cnt: 1 } base-call count: 1
+Test stopped during ExceptionCatch event of calledFunction (catch in called function, throw in called function)
+Single call with PopFrame on ExceptionThrowTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionThrowTestObject$TestError caught in same function.
+result is ExceptionThrowTestObject { cnt: 2 } base-call count: 1
+Test stopped during ExceptionCatch event of calledFunction (catch in called function, throw in subroutine)
+Single call with PopFrame on ExceptionCatchTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionCatchTestObject$TestError caught in called function.
+result is ExceptionCatchTestObject { cnt: 2 } base-call count: 1
+Test stopped during Exception event of calledFunction (catch in calling function)
+Single call with PopFrame on ExceptionThrowTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionThrowTestObject$TestError thrown and caught!
+result is ExceptionThrowTestObject { cnt: 2 } base-call count: 1
+Test stopped during Exception event of calledFunction (catch in called function)
+Single call with PopFrame on ExceptionThrowTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionThrowTestObject$TestError caught in same function.
+result is ExceptionThrowTestObject { cnt: 2 } base-call count: 1
+Test stopped during Exception event of calledFunction (catch in parent of calling function)
+Single call with PopFrame on ExceptionThrowFarTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionThrowFarTestObject$TestError thrown and caught!
+result is ExceptionThrowFarTestObject { cnt: 2 } base-call count: 1
+Test stopped during Exception event of calledFunction (catch in called function)
+Single call with PopFrame on ExceptionThrowFarTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionThrowFarTestObject$TestError caught in same function.
+result is ExceptionThrowFarTestObject { cnt: 2 } base-call count: 1
+Test stopped during a ClassLoad event.
+Single call with PopFrame on ClassLoadObject { cnt: 0, curClass: 0} base-call-count: 0
+Failed to pop frame due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
+	art.Test1953.popFrame(Native Method)
+	art.Test1953.runTestOn(Test1953.java)
+	art.Test1953.runTestOn(Test1953.java)
+	art.Test1953.runTests(Test1953.java)
+	<Additional frames hidden>
+TC0.foo == 1
+result is ClassLoadObject { cnt: 1, curClass: 1} base-call count: 1
+Test stopped during a ClassPrepare event.
+Single call with PopFrame on ClassLoadObject { cnt: 0, curClass: 1} base-call-count: 0
+Failed to pop frame due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
+	art.Test1953.popFrame(Native Method)
+	art.Test1953.runTestOn(Test1953.java)
+	art.Test1953.runTestOn(Test1953.java)
+	art.Test1953.runTests(Test1953.java)
+	<Additional frames hidden>
+TC1.foo == 2
+result is ClassLoadObject { cnt: 1, curClass: 2} base-call count: 1
+Test stopped during random Suspend.
+Single call with PopFrame on SuspendSuddenlyObject { cnt: 0 } base-call-count: 0
+result is SuspendSuddenlyObject { cnt: 2 } base-call count: 1
+Test redefining frame being popped.
+Single call with PopFrame on RedefineTestObject { states: [] current: ORIGINAL } base-call-count: 0
+result is RedefineTestObject { states: [ORIGINAL, REDEFINED] current: REDEFINED } base-call count: 1
+Test stopped during a native method fails
+Single call with PopFrame on NativeCalledObject { cnt: 0 } base-call-count: 0
+Failed to pop frame due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
+	art.Test1953.popFrame(Native Method)
+	art.Test1953.runTestOn(Test1953.java)
+	art.Test1953.runTestOn(Test1953.java)
+	art.Test1953.runTests(Test1953.java)
+	<Additional frames hidden>
+result is NativeCalledObject { cnt: 1 } base-call count: 1
+Test stopped in a method called by native fails
+Single call with PopFrame on NativeCallerObject { cnt: 0 } base-call-count: 0
+Failed to pop frame due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
+	art.Test1953.popFrame(Native Method)
+	art.Test1953.runTestOn(Test1953.java)
+	art.Test1953.runTestOn(Test1953.java)
+	art.Test1953.runTests(Test1953.java)
+	<Additional frames hidden>
+result is NativeCallerObject { cnt: 1 } base-call count: 1
+Test stopped with monitor in enclosing frame.
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 2 } base-call count: 1
diff --git a/test/1953-pop-frame/run.py b/test/1953-pop-frame/run.py
index d529fb8..81e237f 100644
--- a/test/1953-pop-frame/run.py
+++ b/test/1953-pop-frame/run.py
@@ -27,4 +27,4 @@
   # quite the right way so they are disabled there too.
   if not (args.jvm or args.verify_soft_fail or not args.prebuild or
           (args.jvmti_redefine_stress and args.host)):
-    ctx.run(fr"patch -p0 expected-stdout.txt < class-loading-expected.patch")
+    ctx.expected_stdout = ctx.expected_stdout.with_suffix(".no-jvm.txt")
diff --git a/test/1954-pop-frame-jit/expected-stdout.jvm.txt b/test/1954-pop-frame-jit/expected-stdout.jvm.txt
new file mode 100644
index 0000000..dafc6b4
--- /dev/null
+++ b/test/1954-pop-frame-jit/expected-stdout.jvm.txt
@@ -0,0 +1,87 @@
+Test stopped using breakpoint
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 2 } base-call count: 1
+Test stopped using breakpoint with declared synchronized function
+Single call with PopFrame on SynchronizedFunctionTestObject { cnt: 0 } base-call-count: 0
+result is SynchronizedFunctionTestObject { cnt: 2 } base-call count: 1
+Test stopped using breakpoint with synchronized block
+Single call with PopFrame on SynchronizedTestObject { cnt: 0 } base-call-count: 0
+result is SynchronizedTestObject { cnt: 2 } base-call count: 1
+Test stopped on single step
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 2 } base-call count: 1
+Test stopped on field access
+Single call with PopFrame on FieldBasedTestObject { cnt: 0, TARGET_FIELD: 0 } base-call-count: 0
+result is FieldBasedTestObject { cnt: 2, TARGET_FIELD: 10 } base-call count: 1
+Test stopped on field modification
+Single call with PopFrame on FieldBasedTestObject { cnt: 0, TARGET_FIELD: 0 } base-call-count: 0
+result is FieldBasedTestObject { cnt: 2, TARGET_FIELD: 10 } base-call count: 1
+Test stopped during Method Exit of doNothing
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 1 } base-call count: 1
+Test stopped during Method Enter of doNothing
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 1 } base-call count: 1
+Test stopped during Method Exit of calledFunction
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 2 } base-call count: 1
+Test stopped during Method Enter of calledFunction
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 1 } base-call count: 1
+Test stopped during Method Exit due to exception thrown in same function
+Single call with PopFrame on ExceptionOnceObject { cnt: 0, throwInSub: false } base-call-count: 0
+result is ExceptionOnceObject { cnt: 2, throwInSub: false } base-call count: 1
+Test stopped during Method Exit due to exception thrown in subroutine
+Single call with PopFrame on ExceptionOnceObject { cnt: 0, throwInSub: true } base-call-count: 0
+result is ExceptionOnceObject { cnt: 2, throwInSub: true } base-call count: 1
+Test stopped during ExceptionCatch event of calledFunction (catch in called function, throw in called function)
+Single call with PopFrame on ExceptionThrowTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionThrowTestObject$TestError caught in same function.
+result is ExceptionThrowTestObject { cnt: 2 } base-call count: 1
+Test stopped during ExceptionCatch event of calledFunction (catch in called function, throw in subroutine)
+Single call with PopFrame on ExceptionCatchTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionCatchTestObject$TestError caught in called function.
+result is ExceptionCatchTestObject { cnt: 2 } base-call count: 1
+Test stopped during Exception event of calledFunction (catch in calling function)
+Single call with PopFrame on ExceptionThrowTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionThrowTestObject$TestError thrown and caught!
+result is ExceptionThrowTestObject { cnt: 2 } base-call count: 1
+Test stopped during Exception event of calledFunction (catch in called function)
+Single call with PopFrame on ExceptionThrowTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionThrowTestObject$TestError caught in same function.
+result is ExceptionThrowTestObject { cnt: 2 } base-call count: 1
+Test stopped during Exception event of calledFunction (catch in parent of calling function)
+Single call with PopFrame on ExceptionThrowFarTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionThrowFarTestObject$TestError thrown and caught!
+result is ExceptionThrowFarTestObject { cnt: 2 } base-call count: 1
+Test stopped during Exception event of calledFunction (catch in called function)
+Single call with PopFrame on ExceptionThrowFarTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionThrowFarTestObject$TestError caught in same function.
+result is ExceptionThrowFarTestObject { cnt: 2 } base-call count: 1
+Test stopped during random Suspend.
+Single call with PopFrame on SuspendSuddenlyObject { cnt: 0 } base-call-count: 0
+result is SuspendSuddenlyObject { cnt: 2 } base-call count: 1
+Test redefining frame being popped.
+Single call with PopFrame on RedefineTestObject { states: [] current: ORIGINAL } base-call-count: 0
+result is RedefineTestObject { states: [ORIGINAL, REDEFINED] current: REDEFINED } base-call count: 1
+Test stopped during a native method fails
+Single call with PopFrame on NativeCalledObject { cnt: 0 } base-call-count: 0
+Failed to pop frame due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
+	art.Test1953.popFrame(Native Method)
+	art.Test1953.runTestOn(Test1953.java)
+	art.Test1953.runTestOn(Test1953.java)
+	art.Test1953.runTests(Test1953.java)
+	<Additional frames hidden>
+result is NativeCalledObject { cnt: 1 } base-call count: 1
+Test stopped in a method called by native fails
+Single call with PopFrame on NativeCallerObject { cnt: 0 } base-call-count: 0
+Failed to pop frame due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
+	art.Test1953.popFrame(Native Method)
+	art.Test1953.runTestOn(Test1953.java)
+	art.Test1953.runTestOn(Test1953.java)
+	art.Test1953.runTests(Test1953.java)
+	<Additional frames hidden>
+result is NativeCallerObject { cnt: 1 } base-call count: 1
+Test stopped with monitor in enclosing frame.
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 2 } base-call count: 1
diff --git a/test/1954-pop-frame-jit/jvm-expected.patch b/test/1954-pop-frame-jit/jvm-expected.patch
deleted file mode 100644
index 6539d56..0000000
--- a/test/1954-pop-frame-jit/jvm-expected.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-37,50d36
-< Test stopped during notifyFramePop without exception on pop of calledFunction
-< Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
-< result is StandardTestObject { cnt: 2 } base-call count: 1
-< Test stopped during notifyFramePop without exception on pop of doNothing
-< Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
-< result is StandardTestObject { cnt: 1 } base-call count: 1
-< Test stopped during notifyFramePop with exception on pop of calledFunction
-< Single call with PopFrame on ExceptionThrowTestObject { cnt: 0 } base-call-count: 0
-< art.Test1953$ExceptionThrowTestObject$TestError thrown and caught!
-< result is ExceptionThrowTestObject { cnt: 2 } base-call count: 1
-< Test stopped during notifyFramePop with exception on pop of doThrow
-< Single call with PopFrame on ExceptionCatchTestObject { cnt: 0 } base-call-count: 0
-< art.Test1953$ExceptionCatchTestObject$TestError caught in called function.
-< result is ExceptionCatchTestObject { cnt: 1 } base-call count: 1
-75,94d60
-< Test stopped during a ClassLoad event.
-< Single call with PopFrame on ClassLoadObject { cnt: 0, curClass: 0} base-call-count: 0
-< Failed to pop frame due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
-< 	art.Test1953.popFrame(Native Method)
-< 	art.Test1953.runTestOn(Test1953.java)
-< 	art.Test1953.runTestOn(Test1953.java)
-< 	art.Test1953.runTests(Test1953.java)
-< 	<Additional frames hidden>
-< TC0.foo == 1
-< result is ClassLoadObject { cnt: 1, curClass: 1} base-call count: 1
-< Test stopped during a ClassPrepare event.
-< Single call with PopFrame on ClassLoadObject { cnt: 0, curClass: 1} base-call-count: 0
-< Failed to pop frame due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
-< 	art.Test1953.popFrame(Native Method)
-< 	art.Test1953.runTestOn(Test1953.java)
-< 	art.Test1953.runTestOn(Test1953.java)
-< 	art.Test1953.runTests(Test1953.java)
-< 	<Additional frames hidden>
-< TC1.foo == 2
-< result is ClassLoadObject { cnt: 1, curClass: 2} base-call count: 1
diff --git a/test/1954-pop-frame-jit/run.py b/test/1954-pop-frame-jit/run.py
index 4f8a0c2..459b447 100644
--- a/test/1954-pop-frame-jit/run.py
+++ b/test/1954-pop-frame-jit/run.py
@@ -27,4 +27,4 @@
   # quite the right way so they are disabled there too.
   if (args.jvm or args.verify_soft_fail or not args.prebuild or
       (args.jvmti_redefine_stress and args.host)):
-    ctx.run(fr"patch -p0 expected-stdout.txt < jvm-expected.patch")
+    ctx.expected_stdout = ctx.expected_stdout.with_suffix(".jvm.txt")
diff --git a/test/1955-pop-frame-jit-called/expected-stdout.jvm.txt b/test/1955-pop-frame-jit-called/expected-stdout.jvm.txt
new file mode 100644
index 0000000..dafc6b4
--- /dev/null
+++ b/test/1955-pop-frame-jit-called/expected-stdout.jvm.txt
@@ -0,0 +1,87 @@
+Test stopped using breakpoint
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 2 } base-call count: 1
+Test stopped using breakpoint with declared synchronized function
+Single call with PopFrame on SynchronizedFunctionTestObject { cnt: 0 } base-call-count: 0
+result is SynchronizedFunctionTestObject { cnt: 2 } base-call count: 1
+Test stopped using breakpoint with synchronized block
+Single call with PopFrame on SynchronizedTestObject { cnt: 0 } base-call-count: 0
+result is SynchronizedTestObject { cnt: 2 } base-call count: 1
+Test stopped on single step
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 2 } base-call count: 1
+Test stopped on field access
+Single call with PopFrame on FieldBasedTestObject { cnt: 0, TARGET_FIELD: 0 } base-call-count: 0
+result is FieldBasedTestObject { cnt: 2, TARGET_FIELD: 10 } base-call count: 1
+Test stopped on field modification
+Single call with PopFrame on FieldBasedTestObject { cnt: 0, TARGET_FIELD: 0 } base-call-count: 0
+result is FieldBasedTestObject { cnt: 2, TARGET_FIELD: 10 } base-call count: 1
+Test stopped during Method Exit of doNothing
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 1 } base-call count: 1
+Test stopped during Method Enter of doNothing
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 1 } base-call count: 1
+Test stopped during Method Exit of calledFunction
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 2 } base-call count: 1
+Test stopped during Method Enter of calledFunction
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 1 } base-call count: 1
+Test stopped during Method Exit due to exception thrown in same function
+Single call with PopFrame on ExceptionOnceObject { cnt: 0, throwInSub: false } base-call-count: 0
+result is ExceptionOnceObject { cnt: 2, throwInSub: false } base-call count: 1
+Test stopped during Method Exit due to exception thrown in subroutine
+Single call with PopFrame on ExceptionOnceObject { cnt: 0, throwInSub: true } base-call-count: 0
+result is ExceptionOnceObject { cnt: 2, throwInSub: true } base-call count: 1
+Test stopped during ExceptionCatch event of calledFunction (catch in called function, throw in called function)
+Single call with PopFrame on ExceptionThrowTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionThrowTestObject$TestError caught in same function.
+result is ExceptionThrowTestObject { cnt: 2 } base-call count: 1
+Test stopped during ExceptionCatch event of calledFunction (catch in called function, throw in subroutine)
+Single call with PopFrame on ExceptionCatchTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionCatchTestObject$TestError caught in called function.
+result is ExceptionCatchTestObject { cnt: 2 } base-call count: 1
+Test stopped during Exception event of calledFunction (catch in calling function)
+Single call with PopFrame on ExceptionThrowTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionThrowTestObject$TestError thrown and caught!
+result is ExceptionThrowTestObject { cnt: 2 } base-call count: 1
+Test stopped during Exception event of calledFunction (catch in called function)
+Single call with PopFrame on ExceptionThrowTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionThrowTestObject$TestError caught in same function.
+result is ExceptionThrowTestObject { cnt: 2 } base-call count: 1
+Test stopped during Exception event of calledFunction (catch in parent of calling function)
+Single call with PopFrame on ExceptionThrowFarTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionThrowFarTestObject$TestError thrown and caught!
+result is ExceptionThrowFarTestObject { cnt: 2 } base-call count: 1
+Test stopped during Exception event of calledFunction (catch in called function)
+Single call with PopFrame on ExceptionThrowFarTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionThrowFarTestObject$TestError caught in same function.
+result is ExceptionThrowFarTestObject { cnt: 2 } base-call count: 1
+Test stopped during random Suspend.
+Single call with PopFrame on SuspendSuddenlyObject { cnt: 0 } base-call-count: 0
+result is SuspendSuddenlyObject { cnt: 2 } base-call count: 1
+Test redefining frame being popped.
+Single call with PopFrame on RedefineTestObject { states: [] current: ORIGINAL } base-call-count: 0
+result is RedefineTestObject { states: [ORIGINAL, REDEFINED] current: REDEFINED } base-call count: 1
+Test stopped during a native method fails
+Single call with PopFrame on NativeCalledObject { cnt: 0 } base-call-count: 0
+Failed to pop frame due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
+	art.Test1953.popFrame(Native Method)
+	art.Test1953.runTestOn(Test1953.java)
+	art.Test1953.runTestOn(Test1953.java)
+	art.Test1953.runTests(Test1953.java)
+	<Additional frames hidden>
+result is NativeCalledObject { cnt: 1 } base-call count: 1
+Test stopped in a method called by native fails
+Single call with PopFrame on NativeCallerObject { cnt: 0 } base-call-count: 0
+Failed to pop frame due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
+	art.Test1953.popFrame(Native Method)
+	art.Test1953.runTestOn(Test1953.java)
+	art.Test1953.runTestOn(Test1953.java)
+	art.Test1953.runTests(Test1953.java)
+	<Additional frames hidden>
+result is NativeCallerObject { cnt: 1 } base-call count: 1
+Test stopped with monitor in enclosing frame.
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 2 } base-call count: 1
diff --git a/test/1955-pop-frame-jit-called/jvm-expected.patch b/test/1955-pop-frame-jit-called/jvm-expected.patch
deleted file mode 100644
index 6539d56..0000000
--- a/test/1955-pop-frame-jit-called/jvm-expected.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-37,50d36
-< Test stopped during notifyFramePop without exception on pop of calledFunction
-< Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
-< result is StandardTestObject { cnt: 2 } base-call count: 1
-< Test stopped during notifyFramePop without exception on pop of doNothing
-< Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
-< result is StandardTestObject { cnt: 1 } base-call count: 1
-< Test stopped during notifyFramePop with exception on pop of calledFunction
-< Single call with PopFrame on ExceptionThrowTestObject { cnt: 0 } base-call-count: 0
-< art.Test1953$ExceptionThrowTestObject$TestError thrown and caught!
-< result is ExceptionThrowTestObject { cnt: 2 } base-call count: 1
-< Test stopped during notifyFramePop with exception on pop of doThrow
-< Single call with PopFrame on ExceptionCatchTestObject { cnt: 0 } base-call-count: 0
-< art.Test1953$ExceptionCatchTestObject$TestError caught in called function.
-< result is ExceptionCatchTestObject { cnt: 1 } base-call count: 1
-75,94d60
-< Test stopped during a ClassLoad event.
-< Single call with PopFrame on ClassLoadObject { cnt: 0, curClass: 0} base-call-count: 0
-< Failed to pop frame due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
-< 	art.Test1953.popFrame(Native Method)
-< 	art.Test1953.runTestOn(Test1953.java)
-< 	art.Test1953.runTestOn(Test1953.java)
-< 	art.Test1953.runTests(Test1953.java)
-< 	<Additional frames hidden>
-< TC0.foo == 1
-< result is ClassLoadObject { cnt: 1, curClass: 1} base-call count: 1
-< Test stopped during a ClassPrepare event.
-< Single call with PopFrame on ClassLoadObject { cnt: 0, curClass: 1} base-call-count: 0
-< Failed to pop frame due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
-< 	art.Test1953.popFrame(Native Method)
-< 	art.Test1953.runTestOn(Test1953.java)
-< 	art.Test1953.runTestOn(Test1953.java)
-< 	art.Test1953.runTests(Test1953.java)
-< 	<Additional frames hidden>
-< TC1.foo == 2
-< result is ClassLoadObject { cnt: 1, curClass: 2} base-call count: 1
diff --git a/test/1955-pop-frame-jit-called/run.py b/test/1955-pop-frame-jit-called/run.py
index 5c78a23..a43b17d 100644
--- a/test/1955-pop-frame-jit-called/run.py
+++ b/test/1955-pop-frame-jit-called/run.py
@@ -33,4 +33,4 @@
   # quite the right way so they are disabled there too.
   if (args.jvm or args.verify_soft_fail or not args.prebuild or
       (args.jvmti_redefine_stress and args.host)):
-    ctx.run(fr"patch -p0 expected-stdout.txt < jvm-expected.patch")
+    ctx.expected_stdout = ctx.expected_stdout.with_suffix(".jvm.txt")
diff --git a/test/1956-pop-frame-jit-calling/expected-stdout.jvm.txt b/test/1956-pop-frame-jit-calling/expected-stdout.jvm.txt
new file mode 100644
index 0000000..dafc6b4
--- /dev/null
+++ b/test/1956-pop-frame-jit-calling/expected-stdout.jvm.txt
@@ -0,0 +1,87 @@
+Test stopped using breakpoint
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 2 } base-call count: 1
+Test stopped using breakpoint with declared synchronized function
+Single call with PopFrame on SynchronizedFunctionTestObject { cnt: 0 } base-call-count: 0
+result is SynchronizedFunctionTestObject { cnt: 2 } base-call count: 1
+Test stopped using breakpoint with synchronized block
+Single call with PopFrame on SynchronizedTestObject { cnt: 0 } base-call-count: 0
+result is SynchronizedTestObject { cnt: 2 } base-call count: 1
+Test stopped on single step
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 2 } base-call count: 1
+Test stopped on field access
+Single call with PopFrame on FieldBasedTestObject { cnt: 0, TARGET_FIELD: 0 } base-call-count: 0
+result is FieldBasedTestObject { cnt: 2, TARGET_FIELD: 10 } base-call count: 1
+Test stopped on field modification
+Single call with PopFrame on FieldBasedTestObject { cnt: 0, TARGET_FIELD: 0 } base-call-count: 0
+result is FieldBasedTestObject { cnt: 2, TARGET_FIELD: 10 } base-call count: 1
+Test stopped during Method Exit of doNothing
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 1 } base-call count: 1
+Test stopped during Method Enter of doNothing
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 1 } base-call count: 1
+Test stopped during Method Exit of calledFunction
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 2 } base-call count: 1
+Test stopped during Method Enter of calledFunction
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 1 } base-call count: 1
+Test stopped during Method Exit due to exception thrown in same function
+Single call with PopFrame on ExceptionOnceObject { cnt: 0, throwInSub: false } base-call-count: 0
+result is ExceptionOnceObject { cnt: 2, throwInSub: false } base-call count: 1
+Test stopped during Method Exit due to exception thrown in subroutine
+Single call with PopFrame on ExceptionOnceObject { cnt: 0, throwInSub: true } base-call-count: 0
+result is ExceptionOnceObject { cnt: 2, throwInSub: true } base-call count: 1
+Test stopped during ExceptionCatch event of calledFunction (catch in called function, throw in called function)
+Single call with PopFrame on ExceptionThrowTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionThrowTestObject$TestError caught in same function.
+result is ExceptionThrowTestObject { cnt: 2 } base-call count: 1
+Test stopped during ExceptionCatch event of calledFunction (catch in called function, throw in subroutine)
+Single call with PopFrame on ExceptionCatchTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionCatchTestObject$TestError caught in called function.
+result is ExceptionCatchTestObject { cnt: 2 } base-call count: 1
+Test stopped during Exception event of calledFunction (catch in calling function)
+Single call with PopFrame on ExceptionThrowTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionThrowTestObject$TestError thrown and caught!
+result is ExceptionThrowTestObject { cnt: 2 } base-call count: 1
+Test stopped during Exception event of calledFunction (catch in called function)
+Single call with PopFrame on ExceptionThrowTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionThrowTestObject$TestError caught in same function.
+result is ExceptionThrowTestObject { cnt: 2 } base-call count: 1
+Test stopped during Exception event of calledFunction (catch in parent of calling function)
+Single call with PopFrame on ExceptionThrowFarTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionThrowFarTestObject$TestError thrown and caught!
+result is ExceptionThrowFarTestObject { cnt: 2 } base-call count: 1
+Test stopped during Exception event of calledFunction (catch in called function)
+Single call with PopFrame on ExceptionThrowFarTestObject { cnt: 0 } base-call-count: 0
+art.Test1953$ExceptionThrowFarTestObject$TestError caught in same function.
+result is ExceptionThrowFarTestObject { cnt: 2 } base-call count: 1
+Test stopped during random Suspend.
+Single call with PopFrame on SuspendSuddenlyObject { cnt: 0 } base-call-count: 0
+result is SuspendSuddenlyObject { cnt: 2 } base-call count: 1
+Test redefining frame being popped.
+Single call with PopFrame on RedefineTestObject { states: [] current: ORIGINAL } base-call-count: 0
+result is RedefineTestObject { states: [ORIGINAL, REDEFINED] current: REDEFINED } base-call count: 1
+Test stopped during a native method fails
+Single call with PopFrame on NativeCalledObject { cnt: 0 } base-call-count: 0
+Failed to pop frame due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
+	art.Test1953.popFrame(Native Method)
+	art.Test1953.runTestOn(Test1953.java)
+	art.Test1953.runTestOn(Test1953.java)
+	art.Test1953.runTests(Test1953.java)
+	<Additional frames hidden>
+result is NativeCalledObject { cnt: 1 } base-call count: 1
+Test stopped in a method called by native fails
+Single call with PopFrame on NativeCallerObject { cnt: 0 } base-call-count: 0
+Failed to pop frame due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
+	art.Test1953.popFrame(Native Method)
+	art.Test1953.runTestOn(Test1953.java)
+	art.Test1953.runTestOn(Test1953.java)
+	art.Test1953.runTests(Test1953.java)
+	<Additional frames hidden>
+result is NativeCallerObject { cnt: 1 } base-call count: 1
+Test stopped with monitor in enclosing frame.
+Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
+result is StandardTestObject { cnt: 2 } base-call count: 1
diff --git a/test/1956-pop-frame-jit-calling/jvm-expected.patch b/test/1956-pop-frame-jit-calling/jvm-expected.patch
deleted file mode 100644
index 6539d56..0000000
--- a/test/1956-pop-frame-jit-calling/jvm-expected.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-37,50d36
-< Test stopped during notifyFramePop without exception on pop of calledFunction
-< Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
-< result is StandardTestObject { cnt: 2 } base-call count: 1
-< Test stopped during notifyFramePop without exception on pop of doNothing
-< Single call with PopFrame on StandardTestObject { cnt: 0 } base-call-count: 0
-< result is StandardTestObject { cnt: 1 } base-call count: 1
-< Test stopped during notifyFramePop with exception on pop of calledFunction
-< Single call with PopFrame on ExceptionThrowTestObject { cnt: 0 } base-call-count: 0
-< art.Test1953$ExceptionThrowTestObject$TestError thrown and caught!
-< result is ExceptionThrowTestObject { cnt: 2 } base-call count: 1
-< Test stopped during notifyFramePop with exception on pop of doThrow
-< Single call with PopFrame on ExceptionCatchTestObject { cnt: 0 } base-call-count: 0
-< art.Test1953$ExceptionCatchTestObject$TestError caught in called function.
-< result is ExceptionCatchTestObject { cnt: 1 } base-call count: 1
-75,94d60
-< Test stopped during a ClassLoad event.
-< Single call with PopFrame on ClassLoadObject { cnt: 0, curClass: 0} base-call-count: 0
-< Failed to pop frame due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
-< 	art.Test1953.popFrame(Native Method)
-< 	art.Test1953.runTestOn(Test1953.java)
-< 	art.Test1953.runTestOn(Test1953.java)
-< 	art.Test1953.runTests(Test1953.java)
-< 	<Additional frames hidden>
-< TC0.foo == 1
-< result is ClassLoadObject { cnt: 1, curClass: 1} base-call count: 1
-< Test stopped during a ClassPrepare event.
-< Single call with PopFrame on ClassLoadObject { cnt: 0, curClass: 1} base-call-count: 0
-< Failed to pop frame due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
-< 	art.Test1953.popFrame(Native Method)
-< 	art.Test1953.runTestOn(Test1953.java)
-< 	art.Test1953.runTestOn(Test1953.java)
-< 	art.Test1953.runTests(Test1953.java)
-< 	<Additional frames hidden>
-< TC1.foo == 2
-< result is ClassLoadObject { cnt: 1, curClass: 2} base-call count: 1
diff --git a/test/1956-pop-frame-jit-calling/run.py b/test/1956-pop-frame-jit-calling/run.py
index 5c78a23..a43b17d 100644
--- a/test/1956-pop-frame-jit-calling/run.py
+++ b/test/1956-pop-frame-jit-calling/run.py
@@ -33,4 +33,4 @@
   # quite the right way so they are disabled there too.
   if (args.jvm or args.verify_soft_fail or not args.prebuild or
       (args.jvmti_redefine_stress and args.host)):
-    ctx.run(fr"patch -p0 expected-stdout.txt < jvm-expected.patch")
+    ctx.expected_stdout = ctx.expected_stdout.with_suffix(".jvm.txt")
diff --git a/test/1969-force-early-return-void/class-loading-expected.patch b/test/1969-force-early-return-void/class-loading-expected.patch
deleted file mode 100644
index 5e13595..0000000
--- a/test/1969-force-early-return-void/class-loading-expected.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-178a179,212
-> Test stopped during class-load.
-> NORMAL RUN: Single call with no interference on (ID: 46) ClassLoadObject { cnt: 0, curClass: 0}
-> TC0.foo == 100
-> NORMAL RUN: result for (ID: 46) ClassLoadObject { cnt: 1, curClass: 1} on Test1969 target thread - 46
-> Single call with force-early-return on (ID: 47) ClassLoadObject { cnt: 0, curClass: 1}
-> Will force return of Test1969 target thread - 47
-> Failed to force-return due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
-> 	art.NonStandardExit.forceEarlyReturnVoid(Native Method)
-> 	art.Test1969$TestSuspender.performForceReturn(Test1969.java)
-> 	art.Test1969.runTestOn(Test1969.java)
-> 	art.Test1969.runTestOn(Test1969.java)
-> 	art.Test1969.runTestOn(Test1969.java)
-> 	art.Test1969.runTests(Test1969.java)
-> 	<Additional frames hidden>
-> 
-> TC1.foo == 201
-> result for (ID: 47) ClassLoadObject { cnt: 1, curClass: 2} on Test1969 target thread - 47
-> Test stopped during class-load.
-> NORMAL RUN: Single call with no interference on (ID: 48) ClassLoadObject { cnt: 0, curClass: 2}
-> TC2.foo == 302
-> NORMAL RUN: result for (ID: 48) ClassLoadObject { cnt: 1, curClass: 3} on Test1969 target thread - 48
-> Single call with force-early-return on (ID: 49) ClassLoadObject { cnt: 0, curClass: 3}
-> Will force return of Test1969 target thread - 49
-> Failed to force-return due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
-> 	art.NonStandardExit.forceEarlyReturnVoid(Native Method)
-> 	art.Test1969$TestSuspender.performForceReturn(Test1969.java)
-> 	art.Test1969.runTestOn(Test1969.java)
-> 	art.Test1969.runTestOn(Test1969.java)
-> 	art.Test1969.runTestOn(Test1969.java)
-> 	art.Test1969.runTests(Test1969.java)
-> 	<Additional frames hidden>
-> 
-> TC3.foo == 403
-> result for (ID: 49) ClassLoadObject { cnt: 1, curClass: 4} on Test1969 target thread - 49
diff --git a/test/1969-force-early-return-void/expected-stdout.no-jvm.txt b/test/1969-force-early-return-void/expected-stdout.no-jvm.txt
new file mode 100644
index 0000000..1bb3252
--- /dev/null
+++ b/test/1969-force-early-return-void/expected-stdout.no-jvm.txt
@@ -0,0 +1,212 @@
+Test stopped using breakpoint
+NORMAL RUN: Single call with no interference on (ID: 0) StandardTestObject { cnt: 0 }
+NORMAL RUN: result for (ID: 0) StandardTestObject { cnt: 2 } on Test1969 target thread - 0
+Single call with force-early-return on (ID: 1) StandardTestObject { cnt: 0 }
+Will force return of Test1969 target thread - 1
+result for (ID: 1) StandardTestObject { cnt: 1 } on Test1969 target thread - 1
+Test stopped using breakpoint with declared synchronized function
+NORMAL RUN: Single call with no interference on (ID: 2) SynchronizedFunctionTestObject { cnt: 0 }
+NORMAL RUN: result for (ID: 2) SynchronizedFunctionTestObject { cnt: 2 } on Test1969 target thread - 2
+Single call with force-early-return on (ID: 3) SynchronizedFunctionTestObject { cnt: 0 }
+Will force return of Test1969 target thread - 3
+result for (ID: 3) SynchronizedFunctionTestObject { cnt: 1 } on Test1969 target thread - 3
+Test stopped using breakpoint with synchronized block
+NORMAL RUN: Single call with no interference on (ID: 4) SynchronizedTestObject { cnt: 0 }
+NORMAL RUN: result for (ID: 4) SynchronizedTestObject { cnt: 2 } on Test1969 target thread - 4
+Single call with force-early-return on (ID: 5) SynchronizedTestObject { cnt: 0 }
+Will force return of Test1969 target thread - 5
+result for (ID: 5) SynchronizedTestObject { cnt: 1 } on Test1969 target thread - 5
+Test stopped on single step
+NORMAL RUN: Single call with no interference on (ID: 6) StandardTestObject { cnt: 0 }
+NORMAL RUN: result for (ID: 6) StandardTestObject { cnt: 2 } on Test1969 target thread - 6
+Single call with force-early-return on (ID: 7) StandardTestObject { cnt: 0 }
+Will force return of Test1969 target thread - 7
+result for (ID: 7) StandardTestObject { cnt: 1 } on Test1969 target thread - 7
+Test stopped on field access
+NORMAL RUN: Single call with no interference on (ID: 8) FieldBasedTestObject { TARGET_FIELD: 0, cnt: 0 }
+NORMAL RUN: result for (ID: 8) FieldBasedTestObject { TARGET_FIELD: 10, cnt: 2 } on Test1969 target thread - 8
+Single call with force-early-return on (ID: 9) FieldBasedTestObject { TARGET_FIELD: 0, cnt: 0 }
+Will force return of Test1969 target thread - 9
+result for (ID: 9) FieldBasedTestObject { TARGET_FIELD: 0, cnt: 1 } on Test1969 target thread - 9
+Test stopped on field modification
+NORMAL RUN: Single call with no interference on (ID: 10) FieldBasedTestObject { TARGET_FIELD: 0, cnt: 0 }
+NORMAL RUN: result for (ID: 10) FieldBasedTestObject { TARGET_FIELD: 10, cnt: 2 } on Test1969 target thread - 10
+Single call with force-early-return on (ID: 11) FieldBasedTestObject { TARGET_FIELD: 0, cnt: 0 }
+Will force return of Test1969 target thread - 11
+result for (ID: 11) FieldBasedTestObject { TARGET_FIELD: 0, cnt: 1 } on Test1969 target thread - 11
+Test stopped during Method Exit of calledFunction
+NORMAL RUN: Single call with no interference on (ID: 12) StandardTestObject { cnt: 0 }
+NORMAL RUN: result for (ID: 12) StandardTestObject { cnt: 2 } on Test1969 target thread - 12
+Single call with force-early-return on (ID: 13) StandardTestObject { cnt: 0 }
+Will force return of Test1969 target thread - 13
+result for (ID: 13) StandardTestObject { cnt: 2 } on Test1969 target thread - 13
+Test stopped during Method Enter of calledFunction
+NORMAL RUN: Single call with no interference on (ID: 14) StandardTestObject { cnt: 0 }
+NORMAL RUN: result for (ID: 14) StandardTestObject { cnt: 2 } on Test1969 target thread - 14
+Single call with force-early-return on (ID: 15) StandardTestObject { cnt: 0 }
+Will force return of Test1969 target thread - 15
+result for (ID: 15) StandardTestObject { cnt: 0 } on Test1969 target thread - 15
+Test stopped during Method Exit due to exception thrown in same function
+NORMAL RUN: Single call with no interference on (ID: 16) ExceptionOnceObject { cnt: 0, throwInSub: false }
+Uncaught exception in thread Thread[Test1969 target thread - 16,5,main] - art.Test1969$ExceptionOnceObject$TestError: null
+	art.Test1969$ExceptionOnceObject.calledFunction(Test1969.java)
+	art.Test1969$AbstractTestObject.run(Test1969.java)
+	art.Test1969$2.run(Test1969.java)
+	java.lang.Thread.run(Thread.java)
+
+NORMAL RUN: result for (ID: 16) ExceptionOnceObject { cnt: 1, throwInSub: false } on Test1969 target thread - 16
+Single call with force-early-return on (ID: 17) ExceptionOnceObject { cnt: 0, throwInSub: false }
+Will force return of Test1969 target thread - 17
+result for (ID: 17) ExceptionOnceObject { cnt: 1, throwInSub: false } on Test1969 target thread - 17
+Test stopped during Method Exit due to exception thrown in subroutine
+NORMAL RUN: Single call with no interference on (ID: 18) ExceptionOnceObject { cnt: 0, throwInSub: true }
+Uncaught exception in thread Thread[Test1969 target thread - 18,5,main] - art.Test1969$ExceptionOnceObject$TestError: null
+	art.Test1969$ExceptionOnceObject.doThrow(Test1969.java)
+	art.Test1969$ExceptionOnceObject.calledFunction(Test1969.java)
+	art.Test1969$AbstractTestObject.run(Test1969.java)
+	art.Test1969$2.run(Test1969.java)
+	java.lang.Thread.run(Thread.java)
+
+NORMAL RUN: result for (ID: 18) ExceptionOnceObject { cnt: 1, throwInSub: true } on Test1969 target thread - 18
+Single call with force-early-return on (ID: 19) ExceptionOnceObject { cnt: 0, throwInSub: true }
+Will force return of Test1969 target thread - 19
+result for (ID: 19) ExceptionOnceObject { cnt: 1, throwInSub: true } on Test1969 target thread - 19
+Test stopped during notifyFramePop with exception on pop of calledFunction
+NORMAL RUN: Single call with no interference on (ID: 20) ExceptionThrowTestObject { cnt: 0, baseCnt: 0 }
+art.Test1969$ExceptionThrowTestObject$TestError thrown and caught!
+NORMAL RUN: result for (ID: 20) ExceptionThrowTestObject { cnt: 2, baseCnt: 2 } on Test1969 target thread - 20
+Single call with force-early-return on (ID: 21) ExceptionThrowTestObject { cnt: 0, baseCnt: 0 }
+Will force return of Test1969 target thread - 21
+result for (ID: 21) ExceptionThrowTestObject { cnt: 2, baseCnt: 2 } on Test1969 target thread - 21
+Test stopped during notifyFramePop with exception on pop of doThrow
+NORMAL RUN: Single call with no interference on (ID: 22) ExceptionCatchTestObject { cnt: 0 }
+art.Test1969$ExceptionCatchTestObject$TestError caught in called function.
+NORMAL RUN: result for (ID: 22) ExceptionCatchTestObject { cnt: 2 } on Test1969 target thread - 22
+Single call with force-early-return on (ID: 23) ExceptionCatchTestObject { cnt: 0 }
+Will force return of Test1969 target thread - 23
+Failed to force-return due to java.lang.RuntimeException: JVMTI_ERROR_TYPE_MISMATCH
+	art.NonStandardExit.forceEarlyReturnVoid(Native Method)
+	art.Test1969$TestSuspender.performForceReturn(Test1969.java)
+	art.Test1969.runTestOn(Test1969.java)
+	art.Test1969.runTestOn(Test1969.java)
+	art.Test1969.runTestOn(Test1969.java)
+	art.Test1969.runTests(Test1969.java)
+	<Additional frames hidden>
+
+art.Test1969$ExceptionCatchTestObject$TestError caught in called function.
+result for (ID: 23) ExceptionCatchTestObject { cnt: 2 } on Test1969 target thread - 23
+Test stopped during ExceptionCatch event of calledFunction (catch in called function, throw in called function)
+NORMAL RUN: Single call with no interference on (ID: 24) ExceptionThrowTestObject { cnt: 0, baseCnt: 0 }
+art.Test1969$ExceptionThrowTestObject$TestError caught in same function.
+NORMAL RUN: result for (ID: 24) ExceptionThrowTestObject { cnt: 111, baseCnt: 2 } on Test1969 target thread - 24
+Single call with force-early-return on (ID: 25) ExceptionThrowTestObject { cnt: 0, baseCnt: 0 }
+Will force return of Test1969 target thread - 25
+result for (ID: 25) ExceptionThrowTestObject { cnt: 11, baseCnt: 2 } on Test1969 target thread - 25
+Test stopped during ExceptionCatch event of calledFunction (catch in called function, throw in subroutine)
+NORMAL RUN: Single call with no interference on (ID: 26) ExceptionCatchTestObject { cnt: 0 }
+art.Test1969$ExceptionCatchTestObject$TestError caught in called function.
+NORMAL RUN: result for (ID: 26) ExceptionCatchTestObject { cnt: 2 } on Test1969 target thread - 26
+Single call with force-early-return on (ID: 27) ExceptionCatchTestObject { cnt: 0 }
+Will force return of Test1969 target thread - 27
+result for (ID: 27) ExceptionCatchTestObject { cnt: 1 } on Test1969 target thread - 27
+Test stopped during Exception event of calledFunction (catch in calling function)
+NORMAL RUN: Single call with no interference on (ID: 28) ExceptionThrowTestObject { cnt: 0, baseCnt: 0 }
+art.Test1969$ExceptionThrowTestObject$TestError thrown and caught!
+NORMAL RUN: result for (ID: 28) ExceptionThrowTestObject { cnt: 2, baseCnt: 2 } on Test1969 target thread - 28
+Single call with force-early-return on (ID: 29) ExceptionThrowTestObject { cnt: 0, baseCnt: 0 }
+Will force return of Test1969 target thread - 29
+result for (ID: 29) ExceptionThrowTestObject { cnt: 2, baseCnt: 2 } on Test1969 target thread - 29
+Test stopped during Exception event of calledFunction (catch in called function)
+NORMAL RUN: Single call with no interference on (ID: 30) ExceptionThrowTestObject { cnt: 0, baseCnt: 0 }
+art.Test1969$ExceptionThrowTestObject$TestError caught in same function.
+NORMAL RUN: result for (ID: 30) ExceptionThrowTestObject { cnt: 111, baseCnt: 2 } on Test1969 target thread - 30
+Single call with force-early-return on (ID: 31) ExceptionThrowTestObject { cnt: 0, baseCnt: 0 }
+Will force return of Test1969 target thread - 31
+result for (ID: 31) ExceptionThrowTestObject { cnt: 11, baseCnt: 2 } on Test1969 target thread - 31
+Test stopped during Exception event of calledFunction (catch in parent of calling function)
+NORMAL RUN: Single call with no interference on (ID: 32) ExceptionThrowFarTestObject { cnt: 0, baseCnt: 0 }
+art.Test1969$ExceptionThrowFarTestObject$TestError thrown and caught!
+NORMAL RUN: result for (ID: 32) ExceptionThrowFarTestObject { cnt: 2, baseCnt: 2 } on Test1969 target thread - 32
+Single call with force-early-return on (ID: 33) ExceptionThrowFarTestObject { cnt: 0, baseCnt: 0 }
+Will force return of Test1969 target thread - 33
+result for (ID: 33) ExceptionThrowFarTestObject { cnt: 2, baseCnt: 2 } on Test1969 target thread - 33
+Test stopped during Exception event of calledFunction (catch in called function)
+NORMAL RUN: Single call with no interference on (ID: 34) ExceptionThrowFarTestObject { cnt: 0, baseCnt: 0 }
+art.Test1969$ExceptionThrowFarTestObject$TestError caught in same function.
+NORMAL RUN: result for (ID: 34) ExceptionThrowFarTestObject { cnt: 111, baseCnt: 2 } on Test1969 target thread - 34
+Single call with force-early-return on (ID: 35) ExceptionThrowFarTestObject { cnt: 0, baseCnt: 0 }
+Will force return of Test1969 target thread - 35
+result for (ID: 35) ExceptionThrowFarTestObject { cnt: 101, baseCnt: 2 } on Test1969 target thread - 35
+Test stopped during random Suspend.
+NORMAL RUN: Single call with no interference on (ID: 36) SuspendSuddenlyObject { cnt: 0, spun: false }
+NORMAL RUN: result for (ID: 36) SuspendSuddenlyObject { cnt: 2, spun: true } on Test1969 target thread - 36
+Single call with force-early-return on (ID: 37) SuspendSuddenlyObject { cnt: 0, spun: false }
+Will force return of Test1969 target thread - 37
+result for (ID: 37) SuspendSuddenlyObject { cnt: 1, spun: true } on Test1969 target thread - 37
+Test stopped during a native method fails
+NORMAL RUN: Single call with no interference on (ID: 38) NativeCalledObject { cnt: 0 }
+NORMAL RUN: result for (ID: 38) NativeCalledObject { cnt: 2 } on Test1969 target thread - 38
+Single call with force-early-return on (ID: 39) NativeCalledObject { cnt: 0 }
+Will force return of Test1969 target thread - 39
+Failed to force-return due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
+	art.NonStandardExit.forceEarlyReturnVoid(Native Method)
+	art.Test1969$TestSuspender.performForceReturn(Test1969.java)
+	art.Test1969.runTestOn(Test1969.java)
+	art.Test1969.runTestOn(Test1969.java)
+	art.Test1969.runTestOn(Test1969.java)
+	art.Test1969.runTests(Test1969.java)
+	<Additional frames hidden>
+
+result for (ID: 39) NativeCalledObject { cnt: 2 } on Test1969 target thread - 39
+Test stopped in a method called by native succeeds
+NORMAL RUN: Single call with no interference on (ID: 40) NativeCallerObject { cnt: 0 }
+NORMAL RUN: result for (ID: 40) NativeCallerObject { cnt: 2 } on Test1969 target thread - 40
+Single call with force-early-return on (ID: 41) NativeCallerObject { cnt: 0 }
+Will force return of Test1969 target thread - 41
+result for (ID: 41) NativeCallerObject { cnt: 2 } on Test1969 target thread - 41
+Test stopped in a static method
+NORMAL RUN: Single call with no interference on (ID: 42) StaticMethodObject { cnt: 0 }
+NORMAL RUN: result for (ID: 42) StaticMethodObject { cnt: 2 } on Test1969 target thread - 42
+Single call with force-early-return on (ID: 43) StaticMethodObject { cnt: 0 }
+Will force return of Test1969 target thread - 43
+result for (ID: 43) StaticMethodObject { cnt: 1 } on Test1969 target thread - 43
+Test stopped in a Object <init> method
+NORMAL RUN: Single call with no interference on (ID: 44) ObjectInitTestObject { cnt: 0 }
+NORMAL RUN: result for (ID: 44) ObjectInitTestObject { cnt: 2 } on Test1969 target thread - 44
+Single call with force-early-return on (ID: 45) ObjectInitTestObject { cnt: 0 }
+Will force return of Test1969 target thread - 45
+result for (ID: 45) ObjectInitTestObject { cnt: 1 } on Test1969 target thread - 45
+Test stopped during class-load.
+NORMAL RUN: Single call with no interference on (ID: 46) ClassLoadObject { cnt: 0, curClass: 0}
+TC0.foo == 100
+NORMAL RUN: result for (ID: 46) ClassLoadObject { cnt: 1, curClass: 1} on Test1969 target thread - 46
+Single call with force-early-return on (ID: 47) ClassLoadObject { cnt: 0, curClass: 1}
+Will force return of Test1969 target thread - 47
+Failed to force-return due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
+	art.NonStandardExit.forceEarlyReturnVoid(Native Method)
+	art.Test1969$TestSuspender.performForceReturn(Test1969.java)
+	art.Test1969.runTestOn(Test1969.java)
+	art.Test1969.runTestOn(Test1969.java)
+	art.Test1969.runTestOn(Test1969.java)
+	art.Test1969.runTests(Test1969.java)
+	<Additional frames hidden>
+
+TC1.foo == 201
+result for (ID: 47) ClassLoadObject { cnt: 1, curClass: 2} on Test1969 target thread - 47
+Test stopped during class-load.
+NORMAL RUN: Single call with no interference on (ID: 48) ClassLoadObject { cnt: 0, curClass: 2}
+TC2.foo == 302
+NORMAL RUN: result for (ID: 48) ClassLoadObject { cnt: 1, curClass: 3} on Test1969 target thread - 48
+Single call with force-early-return on (ID: 49) ClassLoadObject { cnt: 0, curClass: 3}
+Will force return of Test1969 target thread - 49
+Failed to force-return due to java.lang.RuntimeException: JVMTI_ERROR_OPAQUE_FRAME
+	art.NonStandardExit.forceEarlyReturnVoid(Native Method)
+	art.Test1969$TestSuspender.performForceReturn(Test1969.java)
+	art.Test1969.runTestOn(Test1969.java)
+	art.Test1969.runTestOn(Test1969.java)
+	art.Test1969.runTestOn(Test1969.java)
+	art.Test1969.runTests(Test1969.java)
+	<Additional frames hidden>
+
+TC3.foo == 403
+result for (ID: 49) ClassLoadObject { cnt: 1, curClass: 4} on Test1969 target thread - 49
diff --git a/test/1969-force-early-return-void/run.py b/test/1969-force-early-return-void/run.py
index 6866e1a..dda04df 100644
--- a/test/1969-force-early-return-void/run.py
+++ b/test/1969-force-early-return-void/run.py
@@ -23,4 +23,4 @@
   # quite the right way so they are disabled there too.
   if not (args.verify_soft_fail or not args.prebuild or
           (args.jvmti_redefine_stress and args.host)):
-    ctx.run(fr"patch -p0 expected-stdout.txt < class-loading-expected.patch")
+    ctx.expected_stdout = ctx.expected_stdout.with_suffix(".no-jvm.txt")
diff --git a/test/909-attach-agent/expected-stdout.interpreter.txt b/test/909-attach-agent/expected-stdout.interpreter.txt
new file mode 100644
index 0000000..fef7cc9
--- /dev/null
+++ b/test/909-attach-agent/expected-stdout.interpreter.txt
@@ -0,0 +1,26 @@
+JNI_OnLoad called
+Hello, world!
+Attached Agent for test 909-attach-agent
+Created env for kArtTiVersion
+Attached Agent for test 909-attach-agent
+Created env for kArtTiVersion
+Goodbye!
+JNI_OnLoad called
+Hello, world!
+Attached Agent for test 909-attach-agent
+Created env for kArtTiVersion
+Attached Agent for test 909-attach-agent
+Created env for kArtTiVersion
+Goodbye!
+JNI_OnLoad called
+Hello, world!
+Attached Agent for test 909-attach-agent
+Created env for kArtTiVersion
+Attached Agent for test 909-attach-agent
+Created env for kArtTiVersion
+Goodbye!
+JNI_OnLoad called
+Hello, world!
+Can't attach agent, process is not debuggable.
+Can't attach agent, process is not debuggable.
+Goodbye!
diff --git a/test/909-attach-agent/interpreter-expected.patch b/test/909-attach-agent/interpreter-expected.patch
deleted file mode 100644
index 5035c6a..0000000
--- a/test/909-attach-agent/interpreter-expected.patch
+++ /dev/null
@@ -1,4 +0,0 @@
-19d18
-< version 0x30010000 is not valid!Unable to create env for JVMTI_VERSION_1_0
-22d20
-< version 0x30010000 is not valid!Unable to create env for JVMTI_VERSION_1_0
diff --git a/test/909-attach-agent/run.py b/test/909-attach-agent/run.py
index 9050ce7..1e35ec9 100644
--- a/test/909-attach-agent/run.py
+++ b/test/909-attach-agent/run.py
@@ -22,8 +22,7 @@
   if args.interpreter:
     # On interpreter we are fully capable of providing the full jvmti api so we
     # have a slightly different expected output.
-    # TODO We should really be changing this in the 'check' script.
-    ctx.run("patch -s expected-stdout.txt <interpreter-expected.patch")
+    ctx.expected_stdout = ctx.expected_stdout.with_suffix(".interpreter.txt")
 
   # Provide additional runtime options when running on device.
   if not args.host:
diff --git a/test/961-default-iface-resolution-gen/expected-stdout.txt b/test/961-default-iface-resolution-gen/expected-stdout.txt
index 1ddd65d..c146358 100644
--- a/test/961-default-iface-resolution-gen/expected-stdout.txt
+++ b/test/961-default-iface-resolution-gen/expected-stdout.txt
@@ -1 +1 @@
-This file is generated by util-src/generate_smali.py do not directly modify!
+[DO_NOT_UPDATE] This file is generated by util-src/generate_smali.py do not directly modify!
diff --git a/test/964-default-iface-init-gen/expected-stdout.txt b/test/964-default-iface-init-gen/expected-stdout.txt
index 1ddd65d..c146358 100644
--- a/test/964-default-iface-init-gen/expected-stdout.txt
+++ b/test/964-default-iface-init-gen/expected-stdout.txt
@@ -1 +1 @@
-This file is generated by util-src/generate_smali.py do not directly modify!
+[DO_NOT_UPDATE] This file is generated by util-src/generate_smali.py do not directly modify!
diff --git a/test/968-default-partial-compile-gen/expected-stdout.txt b/test/968-default-partial-compile-gen/expected-stdout.txt
index 1ddd65d..c146358 100644
--- a/test/968-default-partial-compile-gen/expected-stdout.txt
+++ b/test/968-default-partial-compile-gen/expected-stdout.txt
@@ -1 +1 @@
-This file is generated by util-src/generate_smali.py do not directly modify!
+[DO_NOT_UPDATE] This file is generated by util-src/generate_smali.py do not directly modify!
diff --git a/test/970-iface-super-resolution-gen/expected-stdout.txt b/test/970-iface-super-resolution-gen/expected-stdout.txt
index 1ddd65d..c146358 100644
--- a/test/970-iface-super-resolution-gen/expected-stdout.txt
+++ b/test/970-iface-super-resolution-gen/expected-stdout.txt
@@ -1 +1 @@
-This file is generated by util-src/generate_smali.py do not directly modify!
+[DO_NOT_UPDATE] This file is generated by util-src/generate_smali.py do not directly modify!
diff --git a/test/971-iface-super/expected-stdout.txt b/test/971-iface-super/expected-stdout.txt
index 1ddd65d..c146358 100644
--- a/test/971-iface-super/expected-stdout.txt
+++ b/test/971-iface-super/expected-stdout.txt
@@ -1 +1 @@
-This file is generated by util-src/generate_smali.py do not directly modify!
+[DO_NOT_UPDATE] This file is generated by util-src/generate_smali.py do not directly modify!
diff --git a/test/run-test b/test/run-test
index 9c06a6a..8980c2e 100755
--- a/test/run-test
+++ b/test/run-test
@@ -21,6 +21,7 @@
 from importlib.machinery import SourceFileLoader
 from inspect import currentframe, getframeinfo, FrameInfo
 from pathlib import Path
+from shutil import copyfile
 from typing import Optional
 
 COLOR_RED = '\033[91m'
@@ -40,9 +41,13 @@
 # Context passed to individual tests to let them customize the behaviour.
 class RunTestContext:
 
-  def __init__(self):
+  def __init__(self, tmp_dir: Path) -> None:
     self.env = Environment()
 
+    # Note: The expected path can be modified by the tests.
+    self.expected_stdout = tmp_dir / "expected-stdout.txt"
+    self.expected_stderr = tmp_dir / "expected-stderr.txt"
+
   def echo(self, text):
     with open(test_stdout, "a") as f:
       f.write(text + "\n")
@@ -136,8 +141,6 @@
   chroot = ""
   info = "info.txt"
   run_cmd = "run"
-  expected_stdout = "expected-stdout.txt"
-  expected_stderr = "expected-stderr.txt"
   test_stdout = "test-stdout.txt"
   test_stderr = "test-stderr.txt"
   cfg_output = "graph.cfg"
@@ -875,15 +878,6 @@
   os.chdir(test_dir)
   test_dir = os.getcwd()
 
-  td_info = f"{test_dir}/{info}"
-  td_expected_stdout = f"{test_dir}/{expected_stdout}"
-  td_expected_stderr = f"{test_dir}/{expected_stderr}"
-
-  for td_file in [td_info, td_expected_stdout, td_expected_stderr]:
-    if not os.access(td_file, os.R_OK):
-      error(f"{test_dir}: missing file {td_file}")
-      sys.exit(1)
-
   TEST_NAME = os.path.basename(test_dir)
   export("TEST_NAME", TEST_NAME)
 
@@ -935,6 +929,11 @@
   run(f'unzip -q "{zip_file}" "{zip_entry}/*" -d "{tmp_dir}/.unzipped"')
   run(f'mv "{tmp_dir}"/.unzipped/{zip_entry}/* "{tmp_dir}"')
 
+  ctx = RunTestContext(Path(tmp_dir))
+  td_info = f"{test_dir}/{info}"
+  for td_file in [td_info, ctx.expected_stdout, ctx.expected_stderr]:
+    assert os.access(td_file, os.R_OK)
+
   joined_run_args = " ".join(run_args)
   joined_args = " ".join(args)
 
@@ -944,7 +943,6 @@
     parsed_args.stdout_file = os.path.join(tmp_dir, test_stdout)
     parsed_args.stderr_file = os.path.join(tmp_dir, test_stderr)
 
-    ctx = RunTestContext()
     script = os.path.join(tmp_dir, "run.py")
     if os.path.exists(script):
       module = SourceFileLoader("run_" + TEST_NAME, script).load_module()
@@ -964,15 +962,19 @@
   # Failing tests just raise python exception.
   os.chdir(tmp_dir)
   if update_mode == "yes":
-    run(f'''sed -e 's/[[:cntrl:]]$//g' <"{test_stdout}" >"{td_expected_stdout}"''')
-    run(f'''sed -e 's/[[:cntrl:]]$//g' <"{test_stderr}" >"{td_expected_stderr}"''')
+    for src, dst in [(test_stdout, os.path.join(test_dir, ctx.expected_stdout.name)),
+                     (test_stderr, os.path.join(test_dir, ctx.expected_stderr.name))]:
+      if "[DO_NOT_UPDATE]" not in open(dst).readline():
+        copyfile(src, dst)
 
   print("#################### info")
   run(f'cat "{td_info}" | sed "s/^/# /g"')
   print("#################### stdout diff")
-  proc_out = run(f'diff --strip-trailing-cr -u "{expected_stdout}" "{test_stdout}"', check=False)
+  proc_out = run(f'diff --strip-trailing-cr -u '
+                 f'"{ctx.expected_stdout}" "{test_stdout}"', check=False)
   print("#################### stderr diff")
-  proc_err = run(f'diff --strip-trailing-cr -u "{expected_stderr}" "{test_stderr}"', check=False)
+  proc_err = run(f'diff --strip-trailing-cr -u '
+                 f'"{ctx.expected_stderr}" "{test_stderr}"', check=False)
   if strace == "yes":
     print("#################### strace output (trimmed to 3000 lines)")
     run(f'tail -n 3000 "{tmp_dir}/{strace_output}"')