mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
GP-994: Improve error reporting when GADP-based models fail to start
This commit is contained in:
parent
7a92882ba3
commit
b4d2cb75ba
14 changed files with 80 additions and 16 deletions
|
@ -277,10 +277,12 @@ public class AsyncLock {
|
|||
/**
|
||||
* Queue a sequence of actions on this lock
|
||||
*
|
||||
* <p>
|
||||
* The lock will be acquired before executing the first action of the sequence, and the hold
|
||||
* will be automatically released upon completion, whether normal or exceptional. The first
|
||||
* action receives a reference to the hold, which may be used to re-enter the lock.
|
||||
*
|
||||
* <p>
|
||||
* If the sequence stalls, i.e., an action never completes, it will cause deadlock.
|
||||
*
|
||||
* @param type the type "returned" by the sequence
|
||||
|
@ -297,6 +299,7 @@ public class AsyncLock {
|
|||
/**
|
||||
* Queue a sequence of actions on this lock
|
||||
*
|
||||
* <p>
|
||||
* Identical to {@link #with(TypeSpec, Hold)} except that the acquired hold is stored into an
|
||||
* atomic reference rather than passed to the first action.
|
||||
*
|
||||
|
|
|
@ -18,7 +18,8 @@ package ghidra.async;
|
|||
import java.lang.ref.Cleaner.Cleanable;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
|
@ -375,7 +376,7 @@ public class AsyncReference<T, C> {
|
|||
}
|
||||
}
|
||||
|
||||
ExecutionException ex = new ExecutionException("Disposed", reason);
|
||||
DisposedException ex = new DisposedException(reason);
|
||||
for (CompletableFuture<?> future : toExcept) {
|
||||
future.completeExceptionally(ex);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.async;
|
||||
|
||||
public class DisposedException extends RuntimeException {
|
||||
public DisposedException(Throwable reason) {
|
||||
super(reason);
|
||||
}
|
||||
}
|
|
@ -38,6 +38,7 @@ public class AsyncSequenceWithoutTemp<R> {
|
|||
/**
|
||||
* Construct a new sequence without a temporary value
|
||||
*
|
||||
* <p>
|
||||
* Do not call this directly. Please use {@link AsyncUtils#sequence(TypeSpec)}.
|
||||
*
|
||||
* @param seqResult the result of the whole sequence, passed to each appended sequence
|
||||
|
@ -180,6 +181,7 @@ public class AsyncSequenceWithoutTemp<R> {
|
|||
/**
|
||||
* Finish defining this sequence of actions and obtain its future result
|
||||
*
|
||||
* <p>
|
||||
* When an action in the sequence calls {@link AsyncHandlerCanExit#exit(Object, Throwable)}, the
|
||||
* returned {@link CompletableFuture} is completed. If any action completes exceptionally, the
|
||||
* returned {@link CompletableFuture} is completed exceptionally. If the final action executes,
|
||||
|
@ -197,13 +199,17 @@ public class AsyncSequenceWithoutTemp<R> {
|
|||
/**
|
||||
* Register an action to execute on sequence completion
|
||||
*
|
||||
* <p>
|
||||
* All registered actions are submitted for execution simultaneously when an action in the
|
||||
* sequence calls {@link AsyncHandlerCanExit#exit(Object, Throwable)}. This is useful for
|
||||
* methods that begin executing sequences "with a context". It is roughly equivalent to a
|
||||
* {@code finally} block. On-exit actions can be registered before other actions are appended to
|
||||
* the chain.
|
||||
*
|
||||
* An uncaught exception in an on-exit action will simply be logged and ignored.
|
||||
* <p>
|
||||
* If the sequence completes exceptionally, that exception is passed to the action. This method
|
||||
* cannot be used to handle the exception, since this method returns this same sequence, not the
|
||||
* resulting one. An uncaught exception in an on-exit action will simply be logged and ignored.
|
||||
*
|
||||
* @param action the action to execute
|
||||
*/
|
||||
|
|
|
@ -87,6 +87,18 @@ public class AsyncLockTest {
|
|||
}).finish();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithError() throws Throwable {
|
||||
AsyncLock l = new AsyncLock();
|
||||
int result = l.with(TypeSpec.INT, null).then((own, seq) -> {
|
||||
throw new AssertionError("Blargh");
|
||||
}).finish().exceptionally(exc -> {
|
||||
return 0xdead;
|
||||
}).get(1000, TimeUnit.MILLISECONDS);
|
||||
|
||||
assertEquals(0xdead, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReentry() {
|
||||
// This is very contrived. A real use would pass ownership to some method which cannot
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue