The sound distributed version control system

#338 [Crash] After `pijul fork --change ` and `pijul channel switch `

Opened by unidual on February 20, 2021 UI
unidual on February 20, 2021

My working dir was clean, I wanted to do the equivalent of a git checkout and branch from this particular state. I tried the following (names and hashes have been change to protect the innocent)

% pijul fork --change CAFEBABE superb_idea
% pijul channel switch superb_idea
Well, this is embarrassing.
pijul had a problem and crashed.
[...]

The crash log is copy-pasted below. Then the working directory didn’t change, i.e. pijul diff showd all the changes between CAFEBABE and the most recent state. I don’t know if it is due to the crash, or if I should have used:

% pijul reset --channel superb_idea

By the way, to prevent mixing up the two commands, they should describe in help what they do to the working dir and refer to each other.

E.g. for switch: “Switch to a channel while keeping the working dir. If you want to update the working dir to the channel state, use reset --channel instead.

And/or warn before switching: Channel ‘superb_idea’ is 43 patches away from ‘main’. Do you want to proceed?

And/or indicate how to undo the change.

You are now in channel superb_idea.
Working dir has 23 Add, 42 Mod, 12 Rem.
Use `channel switch main` to undo.   (<--- argl, wouldn't work since unrecorded change) 
Use `???` to discard this changes (in this channel only) and get the `superb_idea` state (last patch: CAFEBABE).
Use `record` to apply this changes as a single patch.
Use `???` to apply the 43 individuals patches (sync with `main`).

Maybe I got it all wrong! That’s exactly why showing the possible actions and their effects is so useful.

—log—

name = 'pijul'
operating_system = 'unix:OSX'
crate_version = '1.0.0-alpha.38'
explanation = '''
Panic occurred in file '/Users/ygy/.cargo/registry/src/github.com-1ecc6299db9ec823/libpijul-1.0.0-alpha.34/src/fs.rs' at line 842
'''
cause = 'called `Result::unwrap()` on an `Err` value: Block { block: Position { change: ChangeId(NDJT6MKVLD5NG), pos: ChangePosition(1759) } }'
method = 'Panic'
backtrace = '''

   0: 0x102e4a12a - rust_begin_unwind
                at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library/std/src/panicking.rs:495
   1: 0x102ea012f - core::panicking::panic_fmt::hde9134dd19c9a74f
                at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library/core/src/panicking.rs:92
   2: 0x102ea0035 - core::option::expect_none_failed::h686aad664d56bca5
                at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library/core/src/option.rs:1268
   3: 0x1027e82e9 - libpijul::fs::find_path::h70281caff2148012
   4: 0x10271a0fe - pijul::commands::reset::Reset::reset::{{closure}}::h637cbebd8b1653f4
   5: 0x1027344e6 - pijul::run::{{closure}}::h71e61158f554bc87
   6: 0x1026ef2fc -  as core::future::future::Future>::poll::h8e43eaf2c4a52bd7
   7: 0x1025ca061 - tokio::runtime::thread_pool::ThreadPool::block_on::hc563ba2b49fe52e9
   8: 0x102824c69 - tokio::runtime::Runtime::block_on::h7861d3aec778041c
   9: 0x10279b44a - pijul::main::hc111e9d0be631fa9
  10: 0x1025fd88a - std::sys_common::backtrace::__rust_begin_short_backtrace::h59087b3ff519c897
  11: 0x10275ea0c - std::rt::lang_start::{{closure}}::h1795e788eee11e8f
  12: 0x102e4aaf4 - core::ops::function::impls:: for &F>::call_once::h81f763a559f81b5c
                at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library/core/src/ops/function.rs:259
                 - std::panicking::try::do_call::h8f7e7501b4b6c841
                at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library/std/src/panicking.rs:381
                 - std::panicking::try::h5def58989e0f2c84
                at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library/std/src/panicking.rs:345
                 - std::panic::catch_unwind::h8210e1d7d92e8f91
                at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library/std/src/panic.rs:396
                 - std::rt::lang_start_internal::h36ccce6e8a047133
                at /rustc/e1884a8e3c3e813aada8254edfa120e85bf5ffca/library/std/src/rt.rs:51
  13: 0x10279b519 - _main'''
unidual on February 21, 2021

Nb: same error after a fork + pijul reset --channel.

unidual on February 21, 2021

Oh I think I know what happened.

I wasn’t in the root directory but in one of my module. The module didn’t exist at the forking point. So the CWD is dangling.
Edit: nope. I did a test from the root directory. Same issue.

unidual on February 21, 2021

NB: Seems to be a duplicate of #335, which has a nice example to reproduce.

fogti on February 25, 2021

I think I hit a similiar case while using the pijul repo (Tree+.pijul; sha256 = "819396a359985deb23fbc9d81ed39aec89ae0d6dc62d53cad36156ba9a9aaba1 pijul_338.tar.zst"):

zseri@orca ~ $ cd devel/pijul
zseri@orca ~/devel/pijul $ pijul pull
✓ Updating remote changelist
Nothing to pull
zseri@orca ~/devel/pijul $ pijul channel
  main
  main:301
* zseri-misc
zseri@orca ~/devel/pijul $ pijul diff
zseri@orca ~/devel/pijul $ pijul channel switch main
Well, this is embarrassing.

pijul had a problem and crashed. To help us diagnose the problem you can send us a crash report.

We have generated a report file at "/tmp/report-e21d0760-51a8-4f74-8402-ffae5afd9a1b.toml". Submit an issue or email with the subject of "pijul Crash Report" and include the report as an attachment.

- Authors: Pierre-Étienne Meunier 

We take privacy seriously, and do not perform any automated error collection. In order to improve the software, we rely on people to submit reports.

Thank you kindly!
zseri@orca ~/devel/pijul $ cat /tmp/report-e21d0760-51a8-4f74-8402-ffae5afd9a1b.toml
name = 'pijul'
operating_system = 'unix:Unknown'
crate_version = '1.0.0-alpha.38'
explanation = '''
Panic occurred in file '/mnt/fast/zseri/.cargo/registry/src/github.com-1ecc6299db9ec823/libpijul-1.0.0-alpha.34/src/fs.rs' at line 842
'''
cause = 'called `Result::unwrap()` on an `Err` value: Block { block: Position { change: ChangeId(SL45MHGVMBZRS), pos: ChangePosition(10) } }'
method = 'Panic'
backtrace = '''

   0: 0x55d628dace03 - core::option::expect_none_failed::hc6d6d4cea4fdc285
                at /rustc/04caa632dd10c2bf64b69524c7f9c4c30a436877/library/core/src/option.rs:1300
   1: 0x55d62872d3e5 - libpijul::fs::find_path::h40a5a5a057e4e08a
   2: 0x55d6286542e4 - pijul::commands::reset::Reset::reset::{{closure}}::h5cd9dbf035577544
   3: 0x55d62867233c - pijul::run::{{closure}}::h61154a7f402adbcb
   4: 0x55d62861721b -  as core::future::future::Future>::poll::h5714999f7c92ad20
   5: 0x55d6284fcca3 - tokio::runtime::thread_pool::ThreadPool::block_on::h7634729ca57860e3
   6: 0x55d6287825d4 - tokio::runtime::Runtime::block_on::hba1f86298bc852a6
   7: 0x55d628731017 - pijul::main::h6029a7ea564e2d7f
   8: 0x55d628544f86 - std::sys_common::backtrace::__rust_begin_short_backtrace::h63bed0e3cec928bf
   9: 0x55d6286af29c - std::rt::lang_start::{{closure}}::h8d901f503745d558
  10: 0x55d628d8bd17 - core::ops::function::impls:: for &F>::call_once::h7c92107c3c98a949
                at /rustc/04caa632dd10c2bf64b69524c7f9c4c30a436877/library/core/src/ops/function.rs:259
                 - std::panicking::try::do_call::h7454c57e8fbf0cc1
                at /rustc/04caa632dd10c2bf64b69524c7f9c4c30a436877/library/std/src/panicking.rs:379
                 - std::panicking::try::he71cdc15ed83b5ec
                at /rustc/04caa632dd10c2bf64b69524c7f9c4c30a436877/library/std/src/panicking.rs:343
                 - std::panic::catch_unwind::hfc08ddb043e6e18c
                at /rustc/04caa632dd10c2bf64b69524c7f9c4c30a436877/library/std/src/panic.rs:410
                 - std::rt::lang_start_internal::he4958117ec6901fd
                at /rustc/04caa632dd10c2bf64b69524c7f9c4c30a436877/library/std/src/rt.rs:51
  11: 0x55d6287310d5 - main
  12: 0x7f9476ea3e9e - __libc_start_main
  13: 0x55d6284c52ba - _start
  14:        0x0 - '''

The unwrap seems to stem from the following segment:

    let mut path = Vec::new();
    let mut name_buf = Vec::new();
    let flag0 = EdgeFlags::FOLDER | EdgeFlags::PARENT;
    let flag1 = EdgeFlags::all();
    let mut all_alive = true;
    while !v.change.is_root() {
        let mut next_v = None;
        let mut alive = false;
        let inode_vertex = txn.find_block_end(txn.graph(channel), v).unwrap(); // <-- unwrap() bailed here
        assert_eq!(inode_vertex, v.inode_vertex());

Commands (can be even called repeated, good to reproduce/test) to trigger the error in the repo linked above:

pijul reset
pijul channel switch zseri-misc
pijul channel switch main

I already posted this on Zulip. I hope this issue matches.

pmeunier on February 26, 2021

The crashes observed in this discussion have been fixed by #MDADYULS5AWVMTJDGYCGNQTN6T7XJDRUBDTFILDY5MLF6I2PE5NAC

They were due to the fact that when some files recorded in one channel are not present in another one, Pijul insisted on trying to get a “path in the other channel” for these files.

I’m leaving this discussion open because I really like @unidual’s UI suggestions.

pmeunier added tag UI on February 26, 2021