From f4f23de32b2466b115e7b2c0fa5b5ef185576385 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Sun, 19 Mar 2023 03:58:32 +0100 Subject: [PATCH] Fix fuzzers after HasTestcase (#1123) (#1162) * Fix fuzzers after HasTestcase (#1123) * Make the trait a trait * Implement HasTestcase for Corpora * fix * fix * a * a * fix * wasm32 * a * f * f * aa --------- Co-authored-by: tokatoka --- .github/workflows/build_and_test.yml | 2 + fuzzers/baby_fuzzer_nautilus/src/main.rs | 6 ++- fuzzers/forkserver_libafl_cc/src/main.rs | 4 +- fuzzers/forkserver_simple/src/main.rs | 4 +- fuzzers/fuzzbench/Makefile.toml | 2 +- fuzzers/fuzzbench_text/Makefile.toml | 2 +- fuzzers/nautilus_sync/Makefile.toml | 2 +- fuzzers/nautilus_sync/src/lib.rs | 6 ++- fuzzers/tutorial/src/metadata.rs | 3 +- libafl/src/corpus/cached.rs | 18 ++++++++- libafl/src/corpus/inmemory.rs | 20 ++++++++++ libafl/src/corpus/inmemory_ondisk.rs | 24 +++++++++++- libafl/src/corpus/mod.rs | 20 +++++++++- libafl/src/corpus/ondisk.rs | 21 +++++++++- libafl/src/corpus/testcase.rs | 24 +++++++++++- libafl/src/mutators/gramatron.rs | 4 +- libafl/src/schedulers/ecofuzz.rs | 4 +- libafl/src/schedulers/powersched.rs | 4 +- libafl/src/schedulers/weighted.rs | 4 +- libafl/src/stages/sync.rs | 7 +--- libafl/src/state/mod.rs | 38 ++++++++++--------- utils/build_and_test_fuzzers/src/main.rs | 2 +- utils/deexit/src/lib.rs | 2 +- .../gramatron/construct_automata/src/main.rs | 14 +++---- 24 files changed, 181 insertions(+), 56 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index f6c6b914a9..085ee5e620 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -181,6 +181,8 @@ jobs: run: rustup toolchain install nightly --component rustfmt --component clippy --allow-downgrade - name: Add no_std toolchain run: rustup toolchain install nightly-x86_64-unknown-linux-gnu ; rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu + - name: Add wasm target + run: rustup target add wasm32-unknown-unknown - name: Install cxxbridge if: runner.os == 'macOS' run: cargo install cxxbridge-cmd diff --git a/fuzzers/baby_fuzzer_nautilus/src/main.rs b/fuzzers/baby_fuzzer_nautilus/src/main.rs index bd74c04416..bbccf817c2 100644 --- a/fuzzers/baby_fuzzer_nautilus/src/main.rs +++ b/fuzzers/baby_fuzzer_nautilus/src/main.rs @@ -74,7 +74,11 @@ pub fn main() { ) .unwrap(); - if state.metadata_map().get::().is_none() { + if state + .metadata_map() + .get::() + .is_none() + { state.add_metadata(NautilusChunksMetadata::new("/tmp/".into())); } diff --git a/fuzzers/forkserver_libafl_cc/src/main.rs b/fuzzers/forkserver_libafl_cc/src/main.rs index b84472326a..5bf6635ab2 100644 --- a/fuzzers/forkserver_libafl_cc/src/main.rs +++ b/fuzzers/forkserver_libafl_cc/src/main.rs @@ -8,7 +8,7 @@ use libafl::{ rands::StdRand, shmem::{ShMem, ShMemProvider, UnixShMemProvider}, tuples::{tuple_list, MatchName, Merge}, - AsMutSlice, + AsMutSlice, Truncate, }, corpus::{Corpus, InMemoryCorpus, OnDiskCorpus}, events::SimpleEventManager, @@ -22,7 +22,7 @@ use libafl::{ inputs::BytesInput, monitors::SimpleMonitor, mutators::{scheduled::havoc_mutations, tokens_mutations, StdScheduledMutator, Tokens}, - observers::{HitcountsMapObserver, MapObserver, StdMapObserver, TimeObserver}, + observers::{HitcountsMapObserver, StdMapObserver, TimeObserver}, schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler}, stages::mutational::StdMutationalStage, state::{HasCorpus, HasMetadata, StdState}, diff --git a/fuzzers/forkserver_simple/src/main.rs b/fuzzers/forkserver_simple/src/main.rs index 8ff0dc16da..60faecf665 100644 --- a/fuzzers/forkserver_simple/src/main.rs +++ b/fuzzers/forkserver_simple/src/main.rs @@ -8,7 +8,7 @@ use libafl::{ rands::StdRand, shmem::{ShMem, ShMemProvider, UnixShMemProvider}, tuples::{tuple_list, MatchName, Merge}, - AsMutSlice, + AsMutSlice, Truncate, }, corpus::{Corpus, InMemoryCorpus, OnDiskCorpus}, events::SimpleEventManager, @@ -22,7 +22,7 @@ use libafl::{ inputs::BytesInput, monitors::SimpleMonitor, mutators::{scheduled::havoc_mutations, tokens_mutations, StdScheduledMutator, Tokens}, - observers::{HitcountsMapObserver, MapObserver, StdMapObserver, TimeObserver}, + observers::{HitcountsMapObserver, StdMapObserver, TimeObserver}, schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler}, stages::mutational::StdMutationalStage, state::{HasCorpus, HasMetadata, StdState}, diff --git a/fuzzers/fuzzbench/Makefile.toml b/fuzzers/fuzzbench/Makefile.toml index 2f2908b19a..b1a36c46c9 100644 --- a/fuzzers/fuzzbench/Makefile.toml +++ b/fuzzers/fuzzbench/Makefile.toml @@ -81,7 +81,7 @@ mkdir in || true echo a > in/a # Allow sigterm as exit code timeout 11s ./${FUZZER_NAME} -o out -i in >fuzz_stdout.log || true -if [ -z "$(grep "corpus: 30" fuzz_stdout.log)" ]; then +if [ -z "$(grep "objectives: 10" fuzz_stdout.log)" ]; then echo "Fuzzer does not generate any testcases or any crashes" exit 1 else diff --git a/fuzzers/fuzzbench_text/Makefile.toml b/fuzzers/fuzzbench_text/Makefile.toml index 4c04660a0e..0c1a1d0333 100644 --- a/fuzzers/fuzzbench_text/Makefile.toml +++ b/fuzzers/fuzzbench_text/Makefile.toml @@ -82,7 +82,7 @@ mkdir in || true echo a > in/a # Allow sigterm as exit code timeout 11s ./${FUZZER_NAME} -o out -i in >fuzz_stdout.log || true -if [ -z "$(grep "corpus: 30" fuzz_stdout.log)" ]; then +if [ -z "$(grep "objectives: 10" fuzz_stdout.log)" ]; then echo "Fuzzer does not generate any testcases or any crashes" exit 1 else diff --git a/fuzzers/nautilus_sync/Makefile.toml b/fuzzers/nautilus_sync/Makefile.toml index bc548bc615..4ab0a941ed 100644 --- a/fuzzers/nautilus_sync/Makefile.toml +++ b/fuzzers/nautilus_sync/Makefile.toml @@ -105,7 +105,7 @@ script_runner = "@shell" script=''' rm -rf libafl_unix_shmem_server || true timeout 11s ./${FUZZER_NAME} --cores 0 >fuzz_stdout.log 2>/dev/null || true -if [ -z "$(grep "corpus: 30" fuzz_stdout.log)" ]; then +if [ -z "$(grep "corpus: 8" fuzz_stdout.log)" ]; then echo "Fuzzer does not generate any testcases or any crashes" exit 1 else diff --git a/fuzzers/nautilus_sync/src/lib.rs b/fuzzers/nautilus_sync/src/lib.rs index 7f87766931..e94302a65a 100644 --- a/fuzzers/nautilus_sync/src/lib.rs +++ b/fuzzers/nautilus_sync/src/lib.rs @@ -172,7 +172,11 @@ pub fn libafl_main() { .unwrap() }); - if state.metadata_map().get::().is_none() { + if state + .metadata_map() + .get::() + .is_none() + { state.add_metadata(NautilusChunksMetadata::new("/tmp/".into())); } diff --git a/fuzzers/tutorial/src/metadata.rs b/fuzzers/tutorial/src/metadata.rs index 195a552ebf..825836b71e 100644 --- a/fuzzers/tutorial/src/metadata.rs +++ b/fuzzers/tutorial/src/metadata.rs @@ -63,9 +63,10 @@ where } #[inline] - fn append_metadata( + fn append_metadata( &mut self, _state: &mut S, + _observers: &OT, testcase: &mut Testcase, ) -> Result<(), Error> { testcase diff --git a/libafl/src/corpus/cached.rs b/libafl/src/corpus/cached.rs index 4fb611706e..7764728d25 100644 --- a/libafl/src/corpus/cached.rs +++ b/libafl/src/corpus/cached.rs @@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize}; use crate::{ corpus::{ inmemory_ondisk::InMemoryOnDiskCorpus, ondisk::OnDiskMetadataFormat, Corpus, CorpusId, - Testcase, + HasTestcase, Testcase, }, inputs::{Input, UsesInput}, Error, @@ -130,6 +130,22 @@ where } } +impl HasTestcase for CachedOnDiskCorpus +where + I: Input, +{ + fn testcase(&self, id: CorpusId) -> Result>, Error> { + Ok(self.get(id)?.borrow()) + } + + fn testcase_mut( + &self, + id: CorpusId, + ) -> Result>, Error> { + Ok(self.get(id)?.borrow_mut()) + } +} + impl CachedOnDiskCorpus where I: Input, diff --git a/libafl/src/corpus/inmemory.rs b/libafl/src/corpus/inmemory.rs index 69093766d7..f7c05a5075 100644 --- a/libafl/src/corpus/inmemory.rs +++ b/libafl/src/corpus/inmemory.rs @@ -5,6 +5,7 @@ use core::cell::RefCell; use serde::{Deserialize, Serialize}; +use super::HasTestcase; use crate::{ corpus::{Corpus, CorpusId, Testcase}, inputs::{Input, UsesInput}, @@ -381,6 +382,25 @@ where } } +impl HasTestcase for InMemoryCorpus +where + I: Input, +{ + fn testcase( + &self, + id: CorpusId, + ) -> Result::Input>>, Error> { + Ok(self.get(id)?.borrow()) + } + + fn testcase_mut( + &self, + id: CorpusId, + ) -> Result::Input>>, Error> { + Ok(self.get(id)?.borrow_mut()) + } +} + impl InMemoryCorpus where I: Input, diff --git a/libafl/src/corpus/inmemory_ondisk.rs b/libafl/src/corpus/inmemory_ondisk.rs index 5460bcea5d..d70fe2eb19 100644 --- a/libafl/src/corpus/inmemory_ondisk.rs +++ b/libafl/src/corpus/inmemory_ondisk.rs @@ -13,7 +13,10 @@ use std::{ use serde::{Deserialize, Serialize}; -use super::ondisk::{OnDiskMetadata, OnDiskMetadataFormat}; +use super::{ + ondisk::{OnDiskMetadata, OnDiskMetadataFormat}, + HasTestcase, +}; #[cfg(feature = "gzip")] use crate::bolts::compress::GzipCompressor; use crate::{ @@ -134,6 +137,25 @@ where } } +impl HasTestcase for InMemoryOnDiskCorpus +where + I: Input, +{ + fn testcase( + &self, + id: CorpusId, + ) -> Result::Input>>, Error> { + Ok(self.get(id)?.borrow()) + } + + fn testcase_mut( + &self, + id: CorpusId, + ) -> Result::Input>>, Error> { + Ok(self.get(id)?.borrow_mut()) + } +} + impl InMemoryOnDiskCorpus where I: Input, diff --git a/libafl/src/corpus/mod.rs b/libafl/src/corpus/mod.rs index 8859822668..9f2ab47c38 100644 --- a/libafl/src/corpus/mod.rs +++ b/libafl/src/corpus/mod.rs @@ -1,7 +1,7 @@ //! Corpuses contain the testcases, either in memory, on disk, or somewhere else. pub mod testcase; -pub use testcase::{SchedulerTestcaseMetadata, Testcase}; +pub use testcase::{HasTestcase, SchedulerTestcaseMetadata, Testcase}; pub mod inmemory; pub use inmemory::InMemoryCorpus; @@ -187,7 +187,7 @@ pub mod pybind { cached::pybind::PythonCachedOnDiskCorpus, inmemory::pybind::PythonInMemoryCorpus, inmemory_ondisk::pybind::PythonInMemoryOnDiskCorpus, ondisk::pybind::PythonOnDiskCorpus, testcase::pybind::PythonTestcaseWrapper, Corpus, - CorpusId, Testcase, + CorpusId, HasTestcase, Testcase, }, inputs::{BytesInput, UsesInput}, Error, @@ -384,6 +384,22 @@ pub mod pybind { }*/ } + impl HasTestcase for PythonCorpus { + fn testcase( + &self, + id: CorpusId, + ) -> Result::Input>>, Error> { + Ok(self.get(id)?.borrow()) + } + + fn testcase_mut( + &self, + id: CorpusId, + ) -> Result::Input>>, Error> { + Ok(self.get(id)?.borrow_mut()) + } + } + /// Register the classes to the python module pub fn register(_py: Python, m: &PyModule) -> PyResult<()> { m.add_class::()?; diff --git a/libafl/src/corpus/ondisk.rs b/libafl/src/corpus/ondisk.rs index 1364d08d9f..254df123d7 100644 --- a/libafl/src/corpus/ondisk.rs +++ b/libafl/src/corpus/ondisk.rs @@ -9,7 +9,7 @@ use std::path::{Path, PathBuf}; use serde::{Deserialize, Serialize}; -use super::CachedOnDiskCorpus; +use super::{CachedOnDiskCorpus, HasTestcase}; use crate::{ bolts::serdeany::SerdeAnyMap, corpus::{Corpus, CorpusId, Testcase}, @@ -140,6 +140,25 @@ where } } +impl HasTestcase for OnDiskCorpus +where + I: Input, +{ + fn testcase( + &self, + id: CorpusId, + ) -> Result::Input>>, Error> { + Ok(self.get(id)?.borrow()) + } + + fn testcase_mut( + &self, + id: CorpusId, + ) -> Result::Input>>, Error> { + Ok(self.get(id)?.borrow_mut()) + } +} + impl OnDiskCorpus where I: Input, diff --git a/libafl/src/corpus/testcase.rs b/libafl/src/corpus/testcase.rs index 55e2e3778d..16d62fbbfd 100644 --- a/libafl/src/corpus/testcase.rs +++ b/libafl/src/corpus/testcase.rs @@ -2,18 +2,38 @@ //! It will contain a respective input, and metadata. use alloc::string::String; -use core::{default::Default, option::Option, time::Duration}; +use core::{ + cell::{Ref, RefMut}, + default::Default, + option::Option, + time::Duration, +}; use serde::{Deserialize, Serialize}; use crate::{ bolts::{serdeany::SerdeAnyMap, HasLen}, corpus::CorpusId, - inputs::Input, + inputs::{Input, UsesInput}, state::HasMetadata, Error, }; +/// Shorthand to receive a [`Ref`] or [`RefMut`] to a stored [`Testcase`], by [`CorpusId`]. +/// For a normal state, this should return a [`Testcase`] in the corpus, not the objectives. +pub trait HasTestcase: UsesInput { + /// Shorthand to receive a [`Ref`] to a stored [`Testcase`], by [`CorpusId`]. + /// For a normal state, this should return a [`Testcase`] in the corpus, not the objectives. + fn testcase(&self, id: CorpusId) -> Result::Input>>, Error>; + + /// Shorthand to receive a [`RefMut`] to a stored [`Testcase`], by [`CorpusId`]. + /// For a normal state, this should return a [`Testcase`] in the corpus, not the objectives. + fn testcase_mut( + &self, + id: CorpusId, + ) -> Result::Input>>, Error>; +} + /// An entry in the Testcase Corpus #[derive(Serialize, Deserialize, Clone, Debug)] #[serde(bound = "I: serde::de::DeserializeOwned")] diff --git a/libafl/src/mutators/gramatron.rs b/libafl/src/mutators/gramatron.rs index 330096aa85..e37ffd5b91 100644 --- a/libafl/src/mutators/gramatron.rs +++ b/libafl/src/mutators/gramatron.rs @@ -8,12 +8,12 @@ use serde::{Deserialize, Serialize}; use crate::{ bolts::{rands::Rand, tuples::Named}, - corpus::Corpus, + corpus::{Corpus, HasTestcase}, generators::GramatronGenerator, inputs::{GramatronInput, Terminal}, mutators::{MutationResult, Mutator}, random_corpus_id, - state::{HasCorpus, HasMetadata, HasRand, HasTestcase}, + state::{HasCorpus, HasMetadata, HasRand}, Error, }; diff --git a/libafl/src/schedulers/ecofuzz.rs b/libafl/src/schedulers/ecofuzz.rs index 0c826a90df..4698bd80a1 100644 --- a/libafl/src/schedulers/ecofuzz.rs +++ b/libafl/src/schedulers/ecofuzz.rs @@ -6,11 +6,11 @@ use core::marker::PhantomData; use serde::{Deserialize, Serialize}; use crate::{ - corpus::{Corpus, CorpusId, SchedulerTestcaseMetadata, Testcase}, + corpus::{Corpus, CorpusId, HasTestcase, SchedulerTestcaseMetadata, Testcase}, inputs::UsesInput, observers::{MapObserver, ObserversTuple}, schedulers::{powersched::SchedulerMetadata, testcase_score::TestcaseScore, Scheduler}, - state::{HasCorpus, HasExecutions, HasMetadata, HasRand, HasTestcase, UsesState}, + state::{HasCorpus, HasExecutions, HasMetadata, HasRand, UsesState}, Error, }; diff --git a/libafl/src/schedulers/powersched.rs b/libafl/src/schedulers/powersched.rs index 6a40d0ff8e..2e6be4aa01 100644 --- a/libafl/src/schedulers/powersched.rs +++ b/libafl/src/schedulers/powersched.rs @@ -9,11 +9,11 @@ use core::{marker::PhantomData, time::Duration}; use serde::{Deserialize, Serialize}; use crate::{ - corpus::{Corpus, CorpusId, SchedulerTestcaseMetadata, Testcase}, + corpus::{Corpus, CorpusId, HasTestcase, SchedulerTestcaseMetadata, Testcase}, inputs::UsesInput, observers::{MapObserver, ObserversTuple}, schedulers::{RemovableScheduler, Scheduler}, - state::{HasCorpus, HasMetadata, HasTestcase, UsesState}, + state::{HasCorpus, HasMetadata, UsesState}, Error, }; diff --git a/libafl/src/schedulers/weighted.rs b/libafl/src/schedulers/weighted.rs index d09280c5ed..76c1bef0ba 100644 --- a/libafl/src/schedulers/weighted.rs +++ b/libafl/src/schedulers/weighted.rs @@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize}; use crate::{ bolts::rands::Rand, - corpus::{Corpus, CorpusId, SchedulerTestcaseMetadata}, + corpus::{Corpus, CorpusId, HasTestcase, SchedulerTestcaseMetadata}, inputs::UsesInput, observers::{MapObserver, ObserversTuple}, random_corpus_id, @@ -18,7 +18,7 @@ use crate::{ testcase_score::{CorpusWeightTestcaseScore, TestcaseScore}, RemovableScheduler, Scheduler, }, - state::{HasCorpus, HasMetadata, HasRand, HasTestcase, UsesState}, + state::{HasCorpus, HasMetadata, HasRand, UsesState}, Error, }; diff --git a/libafl/src/stages/sync.rs b/libafl/src/stages/sync.rs index 9bf821aeb2..62cb2abfe5 100644 --- a/libafl/src/stages/sync.rs +++ b/libafl/src/stages/sync.rs @@ -11,16 +11,13 @@ use serde::{Deserialize, Serialize}; use crate::{ bolts::{current_time, shmem::ShMemProvider}, - corpus::{Corpus, CorpusId}, + corpus::{Corpus, CorpusId, HasTestcase}, events::{llmp::LlmpEventConverter, Event, EventConfig, EventFirer}, executors::{Executor, ExitKind, HasObservers}, fuzzer::{Evaluator, EvaluatorObservers, ExecutionProcessor}, inputs::{Input, InputConverter, UsesInput}, stages::Stage, - state::{ - HasClientPerfMonitor, HasCorpus, HasExecutions, HasMetadata, HasRand, HasTestcase, - UsesState, - }, + state::{HasClientPerfMonitor, HasCorpus, HasExecutions, HasMetadata, HasRand, UsesState}, Error, }; diff --git a/libafl/src/state/mod.rs b/libafl/src/state/mod.rs index 488fafdf15..b61112979a 100644 --- a/libafl/src/state/mod.rs +++ b/libafl/src/state/mod.rs @@ -22,7 +22,7 @@ use crate::{ rands::Rand, serdeany::{NamedSerdeAnyMap, SerdeAny, SerdeAnyMap}, }, - corpus::{Corpus, CorpusId, Testcase}, + corpus::{Corpus, CorpusId, HasTestcase, Testcase}, events::{Event, EventFirer, LogSeverity}, feedbacks::Feedback, fuzzer::{Evaluator, ExecuteInputResult}, @@ -219,22 +219,6 @@ pub trait HasStartTime { fn start_time_mut(&mut self) -> &mut Duration; } -/// Trait for the testcase -pub trait HasTestcase: HasCorpus { - /// To get the testcase - fn testcase(&self, id: CorpusId) -> Result::Input>>, Error> { - Ok(self.corpus().get(id)?.borrow()) - } - - /// To get mutable testcase - fn testcase_mut( - &self, - id: CorpusId, - ) -> Result::Input>>, Error> { - Ok(self.corpus().get(id)?.borrow_mut()) - } -} - /// The state a fuzz run. #[derive(Serialize, Deserialize, Clone, Debug)] #[serde(bound = " @@ -324,6 +308,26 @@ where } } +impl HasTestcase for StdState +where + I: Input, + C: Corpus::Input>, + R: Rand, +{ + /// To get the testcase + fn testcase(&self, id: CorpusId) -> Result::Input>>, Error> { + Ok(self.corpus().get(id)?.borrow()) + } + + /// To get mutable testcase + fn testcase_mut( + &self, + id: CorpusId, + ) -> Result::Input>>, Error> { + Ok(self.corpus().get(id)?.borrow_mut()) + } +} + impl HasSolutions for StdState where I: Input, diff --git a/utils/build_and_test_fuzzers/src/main.rs b/utils/build_and_test_fuzzers/src/main.rs index b7c2029e80..61e5d6f5a2 100644 --- a/utils/build_and_test_fuzzers/src/main.rs +++ b/utils/build_and_test_fuzzers/src/main.rs @@ -23,5 +23,5 @@ fn main() { } } - log::info!("{}", fuzzers.join("\n")); + println!("{}", fuzzers.join("\n")); } diff --git a/utils/deexit/src/lib.rs b/utils/deexit/src/lib.rs index a42c245391..53e88a5e58 100644 --- a/utils/deexit/src/lib.rs +++ b/utils/deexit/src/lib.rs @@ -9,7 +9,7 @@ extern "C" { /// Hooked `exit` function #[no_mangle] pub extern "C" fn exit(status: i32) { - log::info!("DeExit: The target called exit with status code {status}"); + println!("DeExit: The target called exit with status code {status}"); unsafe { abort(); } diff --git a/utils/gramatron/construct_automata/src/main.rs b/utils/gramatron/construct_automata/src/main.rs index 9da1b90ae9..ff0c7d2df2 100644 --- a/utils/gramatron/construct_automata/src/main.rs +++ b/utils/gramatron/construct_automata/src/main.rs @@ -165,7 +165,7 @@ fn prepare_transitions( state_stacks.s.insert(dest, state_stack_sorted); pda.push(transition); - log::info!("worklist size: {}", worklist.len()); + println!("worklist size: {}", worklist.len()); *state_count += 1; // i += 1; @@ -193,10 +193,10 @@ fn postprocess(pda: &[Transition], stack_limit: usize) -> Automaton { assert!(initial.len() == 1); - log::info!("# transitions: {}", pda.len()); - log::info!("# states: {}", states.len()); - log::info!("initial state: {:?}", &initial); - log::info!("final states: {:?}", &finals); + println!("# transitions: {}", pda.len()); + println!("# states: {}", states.len()); + println!("initial state: {:?}", &initial); + println!("final states: {:?}", &finals); let mut memoized = Vec::with_capacity(states.len()); //let mut memoized_unique = Vec::with_capacity(states.len()); @@ -238,7 +238,7 @@ fn postprocess(pda: &[Transition], stack_limit: usize) -> Automaton { }); if num_transition % 4096 == 0 { - log::info!( + println!( "processed {} transitions over {}", num_transition, culled_pda.len() @@ -279,7 +279,7 @@ fn postprocess(pda: &[Transition], stack_limit: usize) -> Automaton { }); if num_transition % 4096 == 0 { - log::info!( + println!( "processed {} transitions over {}", num_transition, pda.len()