This reverts commit ee7dafae4100397698e5266465919bfdbc40af51.
This commit is contained in:
parent
ee7dafae41
commit
7c9ac6d4b5
@ -334,56 +334,13 @@ where
|
|||||||
|
|
||||||
let mut child = self.configurer.spawn_child(input)?;
|
let mut child = self.configurer.spawn_child(input)?;
|
||||||
|
|
||||||
let res = child
|
let res = match child
|
||||||
.wait_timeout(self.configurer.exec_timeout())
|
.wait_timeout(self.configurer.exec_timeout())
|
||||||
.expect("waiting on child failed");
|
.expect("waiting on child failed")
|
||||||
|
.map(|status| status.signal())
|
||||||
if self.observers.observes_stderr() {
|
{
|
||||||
let mut stderr = Vec::new();
|
|
||||||
child.stderr.as_mut().ok_or_else(|| {
|
|
||||||
Error::illegal_state(
|
|
||||||
"Observer tries to read stderr, but stderr was not `Stdio::pipe` in CommandExecutor",
|
|
||||||
)
|
|
||||||
})?.read_to_end(&mut stderr)?;
|
|
||||||
self.observers.observe_stderr(&stderr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.observers.observes_stdout() {
|
|
||||||
let mut stdout = Vec::new();
|
|
||||||
child.stdout.as_mut().ok_or_else(|| {
|
|
||||||
Error::illegal_state(
|
|
||||||
"Observer tries to read stdout, but stdout was not `Stdio::pipe` in CommandExecutor",
|
|
||||||
)
|
|
||||||
})?.read_to_end(&mut stdout)?;
|
|
||||||
self.observers.observe_stdout(&stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.observers.observes_exit_code() {
|
|
||||||
if let Some(r) = res {
|
|
||||||
if let Some(exit_code) = r.code() {
|
|
||||||
self.observers.observe_exit_code(exit_code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.observers.observes_exit_signal() {
|
|
||||||
if let Some(r) = res {
|
|
||||||
if let Some(exit_signal) = r.signal() {
|
|
||||||
self.observers.observe_exit_signal(exit_signal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::match_same_arms)]
|
|
||||||
// to make different signals leading to an ExitKind::Interrupted explicit
|
|
||||||
match res.map(|status| status.signal()) {
|
|
||||||
// for reference: https://www.man7.org/linux/man-pages/man7/signal.7.html
|
// for reference: https://www.man7.org/linux/man-pages/man7/signal.7.html
|
||||||
Some(Some(2)) => Ok(ExitKind::Interrupted), // SIGINT
|
Some(Some(9)) => Ok(ExitKind::Oom),
|
||||||
Some(Some(10)) => Ok(ExitKind::Interrupted), // SIGUSR1
|
|
||||||
Some(Some(12)) => Ok(ExitKind::Interrupted), // SIGUSR2
|
|
||||||
Some(Some(14)) => Ok(ExitKind::Interrupted), // SIGALRM
|
|
||||||
Some(Some(15)) => Ok(ExitKind::Interrupted), // SIGTERM
|
|
||||||
Some(Some(18)) => Ok(ExitKind::Interrupted), // SIGCONT
|
|
||||||
Some(Some(_)) => Ok(ExitKind::Crash),
|
Some(Some(_)) => Ok(ExitKind::Crash),
|
||||||
Some(None) => Ok(ExitKind::Ok),
|
Some(None) => Ok(ExitKind::Ok),
|
||||||
None => {
|
None => {
|
||||||
@ -394,7 +351,28 @@ where
|
|||||||
drop(child.wait());
|
drop(child.wait());
|
||||||
Ok(ExitKind::Timeout)
|
Ok(ExitKind::Timeout)
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if self.observers.observes_stderr() {
|
||||||
|
let mut stderr = Vec::new();
|
||||||
|
child.stderr.as_mut().ok_or_else(|| {
|
||||||
|
Error::illegal_state(
|
||||||
|
"Observer tries to read stderr, but stderr was not `Stdio::pipe` in CommandExecutor",
|
||||||
|
)
|
||||||
|
})?.read_to_end(&mut stderr)?;
|
||||||
|
self.observers.observe_stderr(&stderr);
|
||||||
}
|
}
|
||||||
|
if self.observers.observes_stdout() {
|
||||||
|
let mut stdout = Vec::new();
|
||||||
|
child.stdout.as_mut().ok_or_else(|| {
|
||||||
|
Error::illegal_state(
|
||||||
|
"Observer tries to read stdout, but stdout was not `Stdio::pipe` in CommandExecutor",
|
||||||
|
)
|
||||||
|
})?.read_to_end(&mut stdout)?;
|
||||||
|
self.observers.observe_stdout(&stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,17 +166,6 @@ where
|
|||||||
fn observes_stderr(&self) -> bool {
|
fn observes_stderr(&self) -> bool {
|
||||||
self.primary.as_ref().observes_stderr() || self.secondary.as_ref().observes_stderr()
|
self.primary.as_ref().observes_stderr() || self.secondary.as_ref().observes_stderr()
|
||||||
}
|
}
|
||||||
/// Returns true if an exit code observer was added to the list
|
|
||||||
#[inline]
|
|
||||||
fn observes_exit_code(&self) -> bool {
|
|
||||||
self.primary.as_ref().observes_exit_code() || self.secondary.as_ref().observes_exit_code()
|
|
||||||
}
|
|
||||||
/// Returns true if an exit signal observer was added to the list
|
|
||||||
#[inline]
|
|
||||||
fn observes_exit_signal(&self) -> bool {
|
|
||||||
self.primary.as_ref().observes_exit_signal()
|
|
||||||
|| self.secondary.as_ref().observes_exit_signal()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Runs `observe_stdout` for all stdout observers in the list
|
/// Runs `observe_stdout` for all stdout observers in the list
|
||||||
fn observe_stdout(&mut self, stdout: &[u8]) {
|
fn observe_stdout(&mut self, stdout: &[u8]) {
|
||||||
@ -188,20 +177,6 @@ where
|
|||||||
fn observe_stderr(&mut self, stderr: &[u8]) {
|
fn observe_stderr(&mut self, stderr: &[u8]) {
|
||||||
self.primary.as_mut().observe_stderr(stderr);
|
self.primary.as_mut().observe_stderr(stderr);
|
||||||
self.secondary.as_mut().observe_stderr(stderr);
|
self.secondary.as_mut().observe_stderr(stderr);
|
||||||
self.primary.as_mut().observe_stderr(stderr);
|
|
||||||
self.secondary.as_mut().observe_stderr(stderr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Runs `observe_exit_code` for all exit code observers in the list
|
|
||||||
fn observe_exit_code(&mut self, exit_code: i32) {
|
|
||||||
self.primary.as_mut().observe_exit_code(exit_code);
|
|
||||||
self.secondary.as_mut().observe_exit_code(exit_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Runs `observe_exit_signal` for all exit signal observers in the list
|
|
||||||
fn observe_exit_signal(&mut self, exit_signal: i32) {
|
|
||||||
self.primary.as_mut().observe_exit_signal(exit_signal);
|
|
||||||
self.secondary.as_mut().observe_exit_signal(exit_signal);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,14 +57,9 @@ pub enum ExitKind {
|
|||||||
/// The run resulted in a target crash.
|
/// The run resulted in a target crash.
|
||||||
Crash,
|
Crash,
|
||||||
/// The run hit an out of memory error.
|
/// The run hit an out of memory error.
|
||||||
/// Only applicable when using `libafl_libfuzzer`
|
|
||||||
Oom,
|
Oom,
|
||||||
/// The run timed out
|
/// The run timed out
|
||||||
Timeout,
|
Timeout,
|
||||||
/// The process was interrupted, likely not because of a crash but because of user interaction.
|
|
||||||
/// Only applicable for certain executors (like [`CommandExecutor`]).
|
|
||||||
/// Check their source code for the actual conditions that lead to this.
|
|
||||||
Interrupted,
|
|
||||||
/// Special case for [`DiffExecutor`] when both exitkinds don't match
|
/// Special case for [`DiffExecutor`] when both exitkinds don't match
|
||||||
Diff {
|
Diff {
|
||||||
/// The exitkind of the primary executor
|
/// The exitkind of the primary executor
|
||||||
@ -77,8 +72,6 @@ pub enum ExitKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// How one of the diffing executions finished.
|
/// How one of the diffing executions finished.
|
||||||
///
|
|
||||||
/// Refer to the definitions in [`ExitKind`] for disclaimers about applicability
|
|
||||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
any(not(feature = "serdeany_autoreg"), miri),
|
any(not(feature = "serdeany_autoreg"), miri),
|
||||||
@ -87,8 +80,6 @@ pub enum ExitKind {
|
|||||||
pub enum DiffExitKind {
|
pub enum DiffExitKind {
|
||||||
/// The run exited normally.
|
/// The run exited normally.
|
||||||
Ok,
|
Ok,
|
||||||
/// The run was interrupted by a signal likely not tied to a crash
|
|
||||||
Interrupted,
|
|
||||||
/// The run resulted in a target crash.
|
/// The run resulted in a target crash.
|
||||||
Crash,
|
Crash,
|
||||||
/// The run hit an out of memory error.
|
/// The run hit an out of memory error.
|
||||||
@ -107,7 +98,6 @@ impl From<ExitKind> for DiffExitKind {
|
|||||||
fn from(exitkind: ExitKind) -> Self {
|
fn from(exitkind: ExitKind) -> Self {
|
||||||
match exitkind {
|
match exitkind {
|
||||||
ExitKind::Ok => DiffExitKind::Ok,
|
ExitKind::Ok => DiffExitKind::Ok,
|
||||||
ExitKind::Interrupted => DiffExitKind::Interrupted,
|
|
||||||
ExitKind::Crash => DiffExitKind::Crash,
|
ExitKind::Crash => DiffExitKind::Crash,
|
||||||
ExitKind::Oom => DiffExitKind::Oom,
|
ExitKind::Oom => DiffExitKind::Oom,
|
||||||
ExitKind::Timeout => DiffExitKind::Timeout,
|
ExitKind::Timeout => DiffExitKind::Timeout,
|
||||||
|
@ -92,16 +92,6 @@ where
|
|||||||
fn observes_stderr(&self) -> bool {
|
fn observes_stderr(&self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
/// If this observer observes exit codes
|
|
||||||
#[inline]
|
|
||||||
fn observes_exit_code(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
/// If this observer observes exit signals
|
|
||||||
#[inline]
|
|
||||||
fn observes_exit_signal(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
/// React to new `stdout`
|
/// React to new `stdout`
|
||||||
/// To use this, always return `true` from `observes_stdout`
|
/// To use this, always return `true` from `observes_stdout`
|
||||||
@ -114,17 +104,6 @@ where
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn observe_stderr(&mut self, stderr: &[u8]) {}
|
fn observe_stderr(&mut self, stderr: &[u8]) {}
|
||||||
|
|
||||||
/// React to new exit code
|
|
||||||
/// To use this, always return `true` from `observes_exit_code`
|
|
||||||
#[inline]
|
|
||||||
#[allow(unused_variables)]
|
|
||||||
fn observe_exit_code(&mut self, exit_code: i32) {}
|
|
||||||
/// React to new exit signal
|
|
||||||
/// To use this, always return `true` from `observes_exit_signal`
|
|
||||||
#[inline]
|
|
||||||
#[allow(unused_variables)]
|
|
||||||
fn observe_exit_signal(&mut self, exit_signal: i32) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines the observer type shared across traits of the type.
|
/// Defines the observer type shared across traits of the type.
|
||||||
@ -165,19 +144,11 @@ where
|
|||||||
fn observes_stdout(&self) -> bool;
|
fn observes_stdout(&self) -> bool;
|
||||||
/// Returns true if a `stderr` observer was added to the list
|
/// Returns true if a `stderr` observer was added to the list
|
||||||
fn observes_stderr(&self) -> bool;
|
fn observes_stderr(&self) -> bool;
|
||||||
/// Returns true if an exit code observer was added to the list
|
|
||||||
fn observes_exit_code(&self) -> bool;
|
|
||||||
/// Returns true if an exit signal observer was added to the list
|
|
||||||
fn observes_exit_signal(&self) -> bool;
|
|
||||||
|
|
||||||
/// Runs `observe_stdout` for all stdout observers in the list
|
/// Runs `observe_stdout` for all stdout observers in the list
|
||||||
fn observe_stdout(&mut self, stdout: &[u8]);
|
fn observe_stdout(&mut self, stdout: &[u8]);
|
||||||
/// Runs `observe_stderr` for all stderr observers in the list
|
/// Runs `observe_stderr` for all stderr observers in the list
|
||||||
fn observe_stderr(&mut self, stderr: &[u8]);
|
fn observe_stderr(&mut self, stderr: &[u8]);
|
||||||
/// Runs `observe_exit_code` for all exit code observers in the list
|
|
||||||
fn observe_exit_code(&mut self, exit_code: i32);
|
|
||||||
/// Runs `observe_exit_signal` for all exit signal observers in the list
|
|
||||||
fn observe_exit_signal(&mut self, exit_signal: i32);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> ObserversTuple<S> for ()
|
impl<S> ObserversTuple<S> for ()
|
||||||
@ -222,18 +193,6 @@ where
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if an exit code observer was added to the list
|
|
||||||
#[inline]
|
|
||||||
fn observes_exit_code(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if an exit signal observer was added to the list
|
|
||||||
#[inline]
|
|
||||||
fn observes_exit_signal(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Runs `observe_stdout` for all stdout observers in the list
|
/// Runs `observe_stdout` for all stdout observers in the list
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
@ -243,16 +202,6 @@ where
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn observe_stderr(&mut self, stderr: &[u8]) {}
|
fn observe_stderr(&mut self, stderr: &[u8]) {}
|
||||||
|
|
||||||
/// Runs `observe_exit_code` for all exit code observers in the list
|
|
||||||
#[inline]
|
|
||||||
#[allow(unused_variables)]
|
|
||||||
fn observe_exit_code(&mut self, exit_code: i32) {}
|
|
||||||
|
|
||||||
/// Runs `observe_exit_signal` for all exit signal observers in the list
|
|
||||||
#[inline]
|
|
||||||
#[allow(unused_variables)]
|
|
||||||
fn observe_exit_signal(&mut self, exit_signal: i32) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Head, Tail, S> ObserversTuple<S> for (Head, Tail)
|
impl<Head, Tail, S> ObserversTuple<S> for (Head, Tail)
|
||||||
@ -303,18 +252,6 @@ where
|
|||||||
self.0.observes_stderr() || self.1.observes_stderr()
|
self.0.observes_stderr() || self.1.observes_stderr()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if an exit code observer was added to the list
|
|
||||||
#[inline]
|
|
||||||
fn observes_exit_code(&self) -> bool {
|
|
||||||
self.0.observes_exit_code() || self.1.observes_exit_code()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if an exit signal observer was added to the list
|
|
||||||
#[inline]
|
|
||||||
fn observes_exit_signal(&self) -> bool {
|
|
||||||
self.0.observes_exit_signal() || self.1.observes_exit_signal()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Runs `observe_stdout` for all stdout observers in the list
|
/// Runs `observe_stdout` for all stdout observers in the list
|
||||||
#[inline]
|
#[inline]
|
||||||
fn observe_stdout(&mut self, stdout: &[u8]) {
|
fn observe_stdout(&mut self, stdout: &[u8]) {
|
||||||
@ -328,20 +265,6 @@ where
|
|||||||
self.0.observe_stderr(stderr);
|
self.0.observe_stderr(stderr);
|
||||||
self.1.observe_stderr(stderr);
|
self.1.observe_stderr(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Runs `observe_exit_code` for all exit code observers in the list
|
|
||||||
#[inline]
|
|
||||||
fn observe_exit_code(&mut self, exit_code: i32) {
|
|
||||||
self.0.observe_exit_code(exit_code);
|
|
||||||
self.1.observe_exit_code(exit_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Runs `observe_exit_signal` for all exit signal observers in the list
|
|
||||||
#[inline]
|
|
||||||
fn observe_exit_signal(&mut self, exit_signal: i32) {
|
|
||||||
self.0.observe_exit_signal(exit_signal);
|
|
||||||
self.1.observe_exit_signal(exit_signal);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A trait for [`Observer`]`s` with a hash field
|
/// A trait for [`Observer`]`s` with a hash field
|
||||||
|
@ -95,89 +95,3 @@ impl Named for StdErrObserver {
|
|||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An observer that captures the exit code of a target.
|
|
||||||
/// Only works for supported executors.
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
||||||
pub struct ExitCodeObserver {
|
|
||||||
/// The name of the observer.
|
|
||||||
pub name: Cow<'static, str>,
|
|
||||||
/// The exit code of the target during its last execution.
|
|
||||||
pub exit_code: Option<i32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An observer that captures exit signal of a target.
|
|
||||||
impl ExitCodeObserver {
|
|
||||||
/// Create a new [`ExitCodeObserver`] with the given name.
|
|
||||||
#[must_use]
|
|
||||||
pub fn new(name: &'static str) -> Self {
|
|
||||||
Self {
|
|
||||||
name: Cow::from(name),
|
|
||||||
exit_code: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S> Observer<S> for ExitCodeObserver
|
|
||||||
where
|
|
||||||
S: UsesInput,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn observes_exit_code(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
/// React to new exit code
|
|
||||||
fn observe_exit_code(&mut self, exit_code: i32) {
|
|
||||||
self.exit_code = Some(exit_code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Named for ExitCodeObserver {
|
|
||||||
fn name(&self) -> &Cow<'static, str> {
|
|
||||||
&self.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An observer that captures the exit code of a target.
|
|
||||||
/// Only works for supported executors.
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
||||||
pub struct ExitSignalObserver {
|
|
||||||
/// The name of the observer.
|
|
||||||
pub name: Cow<'static, str>,
|
|
||||||
/// The exit signal of the target during its last execution.
|
|
||||||
pub exit_signal: Option<i32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An observer that captures the exit signal of a target.
|
|
||||||
impl ExitSignalObserver {
|
|
||||||
/// Create a new [`ExitSignalObserver`] with the given name.
|
|
||||||
#[must_use]
|
|
||||||
pub fn new(name: &'static str) -> Self {
|
|
||||||
Self {
|
|
||||||
name: Cow::from(name),
|
|
||||||
exit_signal: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S> Observer<S> for ExitSignalObserver
|
|
||||||
where
|
|
||||||
S: UsesInput,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn observes_exit_signal(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
/// React to new exit signal
|
|
||||||
fn observe_exit_signal(&mut self, exit_signal: i32) {
|
|
||||||
self.exit_signal = Some(exit_signal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Named for ExitSignalObserver {
|
|
||||||
fn name(&self) -> &Cow<'static, str> {
|
|
||||||
&self.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user