mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
Tests - cleanup of stack traces in test log file
This commit is contained in:
parent
b7c8056c8a
commit
e5358323d8
24 changed files with 889 additions and 678 deletions
|
@ -0,0 +1,81 @@
|
|||
/* ###
|
||||
* 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 generic.concurrent.io;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import ghidra.util.Msg;
|
||||
import utilities.util.reflection.ReflectionUtilities;
|
||||
import utility.function.Dummy;
|
||||
|
||||
/**
|
||||
* Class to pass to a thread pool that will consume all output from an external process. This is
|
||||
* a {@link Runnable} that get submitted to a thread pool. This class records the data it reads
|
||||
*/
|
||||
public class IOResult implements Runnable {
|
||||
|
||||
public static final String THREAD_POOL_NAME = "I/O Thread Pool";
|
||||
|
||||
private List<String> outputLines = new ArrayList<String>();
|
||||
private BufferedReader commandOutput;
|
||||
private final Throwable inception;
|
||||
private Consumer<String> consumer = Dummy.consumer();
|
||||
|
||||
public IOResult(InputStream input) {
|
||||
this(ReflectionUtilities.createThrowableWithStackOlderThan(IOResult.class), input);
|
||||
}
|
||||
|
||||
public IOResult(Throwable inception, InputStream input) {
|
||||
this.inception = inception;
|
||||
commandOutput = new BufferedReader(new InputStreamReader(input));
|
||||
}
|
||||
|
||||
public void setConsumer(Consumer<String> consumer) {
|
||||
this.consumer = consumer;
|
||||
}
|
||||
|
||||
public String getOutputAsString() {
|
||||
StringBuilder buffy = new StringBuilder();
|
||||
for (String line : outputLines) {
|
||||
buffy.append(line);
|
||||
}
|
||||
return buffy.toString();
|
||||
}
|
||||
|
||||
public List<String> getOutput() {
|
||||
return outputLines;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
String line = null;
|
||||
|
||||
try {
|
||||
while ((line = commandOutput.readLine()) != null) {
|
||||
consumer.accept(line);
|
||||
outputLines.add(line);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
String inceptionString = ReflectionUtilities.stackTraceToString(inception);
|
||||
Msg.debug(IOResult.class,
|
||||
"Exception reading output from process. Created from:\n" + inceptionString, e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/* ###
|
||||
* 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 generic.concurrent.io;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import generic.concurrent.GThreadPool;
|
||||
import utilities.util.reflection.ReflectionUtilities;
|
||||
import utility.function.Dummy;
|
||||
|
||||
/**
|
||||
* A class that allows clients to <b>asynchronously</b> consume the output of a {@link Process}s
|
||||
* input and error streams. The task is asynchronous to avoid deadlocks when both streams need
|
||||
* to be read in order for the process to proceed.
|
||||
*/
|
||||
public class ProcessConsumer {
|
||||
|
||||
/**
|
||||
* Read the given input stream line-by-line.
|
||||
*
|
||||
* <p>To get all output after all reading is done you can call the blocking operation
|
||||
* {@link Future#get()}.
|
||||
*
|
||||
* @param is the input stream
|
||||
* @return the future that will be complete when all lines are read
|
||||
*/
|
||||
public static Future<IOResult> consume(InputStream is) {
|
||||
return consume(is, Dummy.consumer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the given input stream line-by-line.
|
||||
*
|
||||
* <p>If you wish to get all output after all reading is done you can call the blocking
|
||||
* operation {@link Future#get()}.
|
||||
*
|
||||
* @param is the input stream
|
||||
* @param lineConsumer the line consumer; may be null
|
||||
* @return the future that will be complete when all lines are read
|
||||
*/
|
||||
public static Future<IOResult> consume(InputStream is,
|
||||
Consumer<String> lineConsumer) {
|
||||
|
||||
lineConsumer = Dummy.ifNull(lineConsumer);
|
||||
|
||||
Throwable inception = ReflectionUtilities.filterJavaThrowable(
|
||||
ReflectionUtilities.createThrowableWithStackOlderThan(ProcessConsumer.class));
|
||||
|
||||
GThreadPool pool = GThreadPool.getSharedThreadPool(IOResult.THREAD_POOL_NAME);
|
||||
IOResult runnable = new IOResult(inception, is);
|
||||
runnable.setConsumer(lineConsumer);
|
||||
Future<IOResult> future = pool.submit(runnable, runnable);
|
||||
return future;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue