pub fn new(
        exe_path: &OsStr,
        // We don't use flags.extra_env. We augment flags.extra_env producing `envp`.
        envp: &[(OsString, OsString)],
        flags: &RecordCommand,
        asan_active: bool,
    ) -> SessionSharedPtr {
        let sched = Scheduler::new(flags.max_ticks, flags.always_switch);

        if flags.scarce_fds {
            for _ in 0..950 {
                // DIFF NOTE: rr swallows any errors on open. We don't for now.
                open("/dev/null", OFlag::O_RDONLY, Mode::empty()).unwrap();
            }
        }

        let mut rec_sess = RecordSession {
            session_inner: SessionInner::new(),
            trace_out: RefCell::new(TraceWriter::new(
                &flags.args[0],
                choose_cpu(flags.bind_cpu),
                flags.output_trace_dir.as_deref(),
                TicksSemantics::default(),
            )),
            scheduler_: RefCell::new(sched),
            initial_thread_group: Default::default(),
            seccomp_filter_rewriter_: SeccompFilterRewriter,
            trace_id: flags.trace_id.clone(),
            disable_cpuid_features_: flags.disable_cpuid_features.clone(),
            ignore_sig: flags.ignore_sig,
            continue_through_sig: flags.continue_through_sig,
            last_task_switchable: Switchable::PreventSwitch,
            syscall_buffer_size_: flags.syscall_buffer_size,
            syscallbuf_desched_sig_: flags.syscallbuf_desched_sig,
            use_syscall_buffer_: flags.use_syscall_buffer == SyscallBuffering::EnableSycallBuf,
            use_file_cloning_: flags.use_file_cloning,
            use_read_cloning_: flags.use_read_cloning,
            enable_chaos_: Default::default(),
            asan_active_: asan_active,
            wait_for_all_: flags.wait_for_all,
            output_trace_dir: flags.output_trace_dir.clone(),
        };

        if !SessionInner::has_cpuid_faulting()
            && rec_sess.disable_cpuid_features_.any_features_disabled()
        {
            fatal!("CPUID faulting required to disable CPUID features");
        }

        // CPU affinity has been set.
        rec_sess.trace_out.borrow_mut().setup_cpuid_records(
            SessionInner::has_cpuid_faulting(),
            &flags.disable_cpuid_features,
        );

        let env: Vec<OsString> = envp
            .iter()
            .map(|(k, v)| -> OsString {
                let mut kv = k.clone();
                kv.push("=");
                kv.push(v);
                kv
            })
            .collect();
        let error_fd: ScopedFd = rec_sess.create_spawn_task_error_pipe();
        let socket_fd = rec_sess.tracee_socket_fd();

        let mut rc: SessionSharedPtr = Rc::new(Box::new(rec_sess));
        let weak_self = Rc::downgrade(&rc);
        // We never change the weak_self pointer so its a good idea to use
        // a bit of unsafe here otherwise we would unecessarily need a RefCell.
        let rs = unsafe {
            let s = Rc::get_mut_unchecked(&mut rc);
            s.weak_self = weak_self.clone();
            // Use this to also set things that shouldn't change.
            s.as_record_mut().unwrap()
        };

        rs.scheduler_mut().set_session_weak_ptr(weak_self);

        if flags.chaos {
            rs.scheduler_mut().set_enable_chaos(flags.chaos);
        }

        match flags.num_cores {
            Some(num_cores) => {
                // Set the number of cores reported, possibly overriding the chaos mode
                // setting.
                rs.scheduler_mut().set_num_cores(num_cores);
            }
            // This is necessary for the default case
            None => rs.scheduler_mut().regenerate_affinity_mask(),
        }

        let t = TaskInner::spawn(
            (*rc).as_ref(),
            &error_fd,
            socket_fd,
            SaveTraceeFdNumber::SaveToSession,
            exe_path,
            &flags.args,
            &env,
            None,
        );
        // The initial_thread_group is set only once so its worth it to use
        // unsafe
        unsafe {
            Rc::get_mut_unchecked(&mut rc)
                .as_record_mut()
                .unwrap()
                .initial_thread_group = Some(t.borrow().thread_group_shr_ptr());
        }
        rc.on_create_task(t);
        rc
    }
/// DIFF NOTE:
/// - The param list is much simpler than rr RecordSession::RecordSession. Takes the
///   whole RecordCommand for simplicity.
/// - This method also incorporates functionality from rr setup_session_from_flags()
///   method
DIFF NOTE:
The param list is much simpler than rr RecordSession::RecordSession. Takes the
whole RecordCommand for simplicity.
This method also incorporates functionality from rr setup_session_from_flags()
method
DIFF NOTE : The param list is much simpler than rr RecordSession :: RecordSession . Takes the whole RecordCommand for simplicity . This method also incorporates functionality from rr setup_session_from_flags () method
pub fn new(
        exe_path: &OsStr,
        // We don't use flags.extra_env. We augment flags.extra_env producing `envp`.
        envp: &[(OsString, OsString)],
        flags: &RecordCommand,
        asan_active: bool,
    ) -> SessionSharedPtr {
        let sched = Scheduler::new(flags.max_ticks, flags.always_switch);
        if flags.scarce_fds {
            for _ in 0..950 {
                // DIFF NOTE: rr swallows any errors on open. We don't for now.
                open("/dev/null", OFlag::O_RDONLY, Mode::empty()).unwrap();
            }
        }
        let mut rec_sess = RecordSession {
            session_inner: SessionInner::new(),
            trace_out: RefCell::new(TraceWriter::new(
                &flags.args[0],
                choose_cpu(flags.bind_cpu),
                flags.output_trace_dir.as_deref(),
                TicksSemantics::default(),
            )),
            scheduler_: RefCell::new(sched),
            initial_thread_group: Default::default(),
            seccomp_filter_rewriter_: SeccompFilterRewriter,
            trace_id: flags.trace_id.clone(),
            disable_cpuid_features_: flags.disable_cpuid_features.clone(),
            ignore_sig: flags.ignore_sig,
            continue_through_sig: flags.continue_through_sig,
            last_task_switchable: Switchable::PreventSwitch,
            syscall_buffer_size_: flags.syscall_buffer_size,
            syscallbuf_desched_sig_: flags.syscallbuf_desched_sig,
            use_syscall_buffer_: flags.use_syscall_buffer == SyscallBuffering::EnableSycallBuf,
            use_file_cloning_: flags.use_file_cloning,
            use_read_cloning_: flags.use_read_cloning,
            enable_chaos_: Default::default(),
            asan_active_: asan_active,
            wait_for_all_: flags.wait_for_all,
            output_trace_dir: flags.output_trace_dir.clone(),
        };
        if !SessionInner::has_cpuid_faulting()
            && rec_sess.disable_cpuid_features_.any_features_disabled()
        {
            fatal!("CPUID faulting required to disable CPUID features");
        }
        // CPU affinity has been set.
        rec_sess.trace_out.borrow_mut().setup_cpuid_records(
            SessionInner::has_cpuid_faulting(),
            &flags.disable_cpuid_features,
        );
        let env: Vec<OsString> = envp
            .iter()
            .map(|(k, v)| -> OsString {
                let mut kv = k.clone();
                kv.push("=");
                kv.push(v);
                kv
            })
            .collect();
        let error_fd: ScopedFd = rec_sess.create_spawn_task_error_pipe();
        let socket_fd = rec_sess.tracee_socket_fd();
        let mut rc: SessionSharedPtr = Rc::new(Box::new(rec_sess));
        let weak_self = Rc::downgrade(&rc);
        // We never change the weak_self pointer so its a good idea to use
        // a bit of unsafe here otherwise we would unecessarily need a RefCell.
        let rs = unsafe {
            let s = Rc::get_mut_unchecked(&mut rc);
            s.weak_self = weak_self.clone();
            // Use this to also set things that shouldn't change.
            s.as_record_mut().unwrap()
        };
        rs.scheduler_mut().set_session_weak_ptr(weak_self);
        if flags.chaos {
            rs.scheduler_mut().set_enable_chaos(flags.chaos);
        }
        match flags.num_cores {
            Some(num_cores) => {
                // Set the number of cores reported, possibly overriding the chaos mode
                // setting.
                rs.scheduler_mut().set_num_cores(num_cores);
            }
            // This is necessary for the default case
            None => rs.scheduler_mut().regenerate_affinity_mask(),
        }
        let t = TaskInner::spawn(
            (*rc).as_ref(),
            &error_fd,
            socket_fd,
            SaveTraceeFdNumber::SaveToSession,
            exe_path,
            &flags.args,
            &env,
            None,
        );
        // The initial_thread_group is set only once so its worth it to use
        // unsafe
        unsafe {
            Rc::get_mut_unchecked(&mut rc)
                .as_record_mut()
                .unwrap()
                .initial_thread_group = Some(t.borrow().thread_group_shr_ptr());
        }
        rc.on_create_task(t);
        rc
    }
pub fn new ( exe_path : & OsStr , // We don't use flags.extra_env. We augment flags.extra_env producing `envp`. envp : & [ ( OsString , OsString ) ] , flags : & RecordCommand , asan_active : bool , ) -> SessionSharedPtr { let sched = Scheduler :: new ( flags . max_ticks , flags . always_switch ) ; if flags . scarce_fds { for _ in 0 .. 950 { // DIFF NOTE: rr swallows any errors on open. We don't for now. open ( " " , OFlag :: O_RDONLY , Mode :: empty ( ) ) . unwrap ( ) ; } } let mut rec_sess = RecordSession { session_inner : SessionInner :: new ( ) , trace_out : RefCell :: new ( TraceWriter :: new ( & flags . args [ 0 ] , choose_cpu ( flags . bind_cpu ) , flags . output_trace_dir . as_deref ( ) , TicksSemantics :: default ( ) , ) ) , scheduler_ : RefCell :: new ( sched ) , initial_thread_group : Default :: default ( ) , seccomp_filter_rewriter_ : SeccompFilterRewriter , trace_id : flags . trace_id . clone ( ) , disable_cpuid_features_ : flags . disable_cpuid_features . clone ( ) , ignore_sig : flags . ignore_sig , continue_through_sig : flags . continue_through_sig , last_task_switchable : Switchable :: PreventSwitch , syscall_buffer_size_ : flags . syscall_buffer_size , syscallbuf_desched_sig_ : flags . syscallbuf_desched_sig , use_syscall_buffer_ : flags . use_syscall_buffer == SyscallBuffering :: EnableSycallBuf , use_file_cloning_ : flags . use_file_cloning , use_read_cloning_ : flags . use_read_cloning , enable_chaos_ : Default :: default ( ) , asan_active_ : asan_active , wait_for_all_ : flags . wait_for_all , output_trace_dir : flags . output_trace_dir . clone ( ) , } ; if ! SessionInner :: has_cpuid_faulting ( ) && rec_sess . disable_cpuid_features_ . any_features_disabled ( ) { fatal ! ( " " ) ; } // CPU affinity has been set. rec_sess . trace_out . borrow_mut ( ) . setup_cpuid_records ( SessionInner :: has_cpuid_faulting ( ) , & flags . disable_cpuid_features , ) ; let env : Vec < OsString > = envp . iter ( ) . map ( | ( k , v ) | -> OsString { let mut kv = k . clone ( ) ; kv . push ( " " ) ; kv . push ( v ) ; kv } ) . collect ( ) ; let error_fd : ScopedFd = rec_sess . create_spawn_task_error_pipe ( ) ; let socket_fd = rec_sess . tracee_socket_fd ( ) ; let mut rc : SessionSharedPtr = Rc :: new ( Box :: new ( rec_sess ) ) ; let weak_self = Rc :: downgrade ( & rc ) ; // We never change the weak_self pointer so its a good idea to use // a bit of unsafe here otherwise we would unecessarily need a RefCell. let rs = unsafe { let s = Rc :: get_mut_unchecked ( & mut rc ) ; s . weak_self = weak_self . clone ( ) ; // Use this to also set things that shouldn't change. s . as_record_mut ( ) . unwrap ( ) } ; rs . scheduler_mut ( ) . set_session_weak_ptr ( weak_self ) ; if flags . chaos { rs . scheduler_mut ( ) . set_enable_chaos ( flags . chaos ) ; } match flags . num_cores { Some ( num_cores ) => { // Set the number of cores reported, possibly overriding the chaos mode // setting. rs . scheduler_mut ( ) . set_num_cores ( num_cores ) ; } // This is necessary for the default case None => rs . scheduler_mut ( ) . regenerate_affinity_mask ( ) , } let t = TaskInner :: spawn ( ( * rc ) . as_ref ( ) , & error_fd , socket_fd , SaveTraceeFdNumber :: SaveToSession , exe_path , & flags . args , & env , None , ) ; // The initial_thread_group is set only once so its worth it to use // unsafe unsafe { Rc :: get_mut_unchecked ( & mut rc ) . as_record_mut ( ) . unwrap ( ) . initial_thread_group = Some ( t . borrow ( ) . thread_group_shr_ptr ( ) ) ; } rc . on_create_task ( t ) ; rc }
DIFF NOTE:
 The param list is much simpler than rr RecordSession::RecordSession.
DIFF NOTE : The param list is much simpler than rr RecordSession :: RecordSession .
exe_path
&OsStr
envp
&[(OsString, OsString)]
flags
&RecordCommand
asan_active
bool