Crash in Lix 2.91.0 in debugger mode #592

Open
opened 2024-12-04 23:13:19 +00:00 by jade · 4 comments
Owner
$ command nix develop --debugger
trace: checking if /hadrian/hadrian.cabal is present:  no
error: undefined variable 'happy'
       at /nix/store/n2byjw7c7hxzvqpd4nq3k8h8qr64a8h9-source/ghc.nix:275:20:
          274|     export GHCPKG=$NIX_GHCPKG
          275|     export HAPPY=${happy}/bin/happy
             |                    ^
          276|     export ALEX=${alex}/bin/alex

evaluating derivation 'git+file:///Users/wiggles/ghc.nix#devShells.aarch64-darwin.default'fish: Job 1, 'command nix develop --debugger' terminated by signal SIGSEGV (Address boundary error)

Crash report:

lix/lix2 » pycrashreport /home/jade/Downloads/nix-2024-12-02-131817.ips
8F03B9F8-8BBD-4578-BCEC-6D8F550DDFC0 2024-12-02 13:18:17
/home/jade/Downloads/nix-2024-12-02-131817.ips

Exception: EXC_BAD_ACCESS
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000004

Registers:
      x0 = 0x0000000111c2cb40       x1 = 0x0000000000000001       x2 = 0x0000000000000000       x3 = 0x0000000000000000 
      x4 = 0x000000000000006f       x5 = 0x0000000000000070       x6 = 0x0000000000002d80       x7 = 0x0000000000000000 
      x8 = 0x0000000000000000       x9 = 0x0000000000000002      x10 = 0x0000000000000001      x11 = 0x0000000000006000 
     x12 = 0x0000000000000018      x13 = 0x0000600004faa020      x14 = 0x00000000001ff800      x15 = 0x00000000000007fb 
     x16 = 0x000000010142f3b4      x17 = 0x00000001f061e460      x18 = 0x0000000000000000      x19 = 0x0000600004882d80 
     x20 = 0x000000010352dfe0      x21 = 0x00000001034f4aa8      x22 = 0x00006000018f1398      x23 = 0x00006000018f5b58 
     x24 = 0x000000010114c928      x25 = 0x000000016f6209c0      x26 = 0x00006000071b0008      x27 = 0x000060002125acd8 
     x28 = 0x000000016f6209c0       x0 = 0x0000000111c2cb40       x1 = 0x0000000000000001       x2 = 0x0000000000000000 
      x3 = 0x0000000000000000       x4 = 0x000000000000006f       x5 = 0x0000000000000070       x6 = 0x0000000000002d80 
      x7 = 0x0000000000000000       x8 = 0x0000000000000000       x9 = 0x0000000000000002      x10 = 0x0000000000000001 
     x11 = 0x0000000000006000      x12 = 0x0000000000000018      x13 = 0x0000600004faa020      x14 = 0x00000000001ff800 
     x15 = 0x00000000000007fb      x16 = 0x000000010142f3b4      x17 = 0x00000001f061e460      x18 = 0x0000000000000000 
     x19 = 0x0000600004882d80      x20 = 0x000000010352dfe0      x21 = 0x00000001034f4aa8      x22 = 0x00006000018f1398 
     x23 = 0x00006000018f5b58      x24 = 0x000000010114c928      x25 = 0x000000016f6209c0      x26 = 0x00006000071b0008 
     x27 = 0x000060002125acd8      x28 = 0x000000016f6209c0       lr = 0x0000000101a0fc5c     cpsr = 0x0000000080001000 
      fp = 0x000000016f620770       sp = 0x000000016f620710      esr = 0x0000000092000006       pc = 0x0000000101a0fce8 
     far = 0x0000000000000004 

Frames:
        [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x2fce8 (nix::mapStaticEnvBindings() + 0xdc)
        [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x2fc5c (nix::mapStaticEnvBindings() + 0x50)
        [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x2fc5c (nix::mapStaticEnvBindings() + 0x50)
        [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x30320 (nix::EvalState::runDebugRepl(nix::Error const*, nix::Env const&, nix::Expr const&) + 0x4cc)
        [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x24148 (nix::EvalErrorBuilder<nix::UndefinedVarError>::debugThrow() + 0x50)
        [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x31ae4 (nix::EvalState::lookupVar(nix::Env*, nix::ExprVar const&, bool) + 0x254)
        [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x33da4 (nix::ExprVar::eval(nix::EvalState&, nix::Env&, nix::Value&) + 0x4c)
        [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x39f28 (nix::ExprConcatStrings::eval(nix::EvalState&, nix::Env&, nix::Value&) + 0x12c)
        [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0xcb15c (nix::derivationStrictInternal(nix::EvalState&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, nix::Bindings*
, nix::Value&) + 0x478)
        [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0xb8dec (nix::prim_derivationStrict(nix::EvalState&, nix::PosIdx, nix::Value**, nix::Value&) + 0xd8)
        [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x360a8 (nix::EvalState::callFunction(nix::Value&, unsigned long, nix::Value**, nix::Value&, nix::PosIdx) + 0x3f4)
        [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x37f44 (nix::ExprCall::eval(nix::EvalState&, nix::Env&, nix::Value&) + 0x25c)
        [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x33df4 (nix::ExprVar::eval(nix::EvalState&, nix::Env&, nix::Value&) + 0x9c)
        [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x33ef4 (nix::ExprSelect::eval(nix::EvalState&, nix::Env&, nix::Value&) + 0x5c)
        [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x34358 (nix::ExprSelect::eval(nix::EvalState&, nix::Env&, nix::Value&) + 0x4c0)
        [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x14a18 (nix::eval_cache::AttrCursor::forceValue() + 0x138)
        [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x171a4 (nix::eval_cache::AttrCursor::getString() + 0xc0)
        [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x18e28 (nix::eval_cache::AttrCursor::forceDerivation() + 0x5c)
        [/Volumes/VOLUME/*/liblixcmd.dylib] 0x100dd8000 + 0x459ac (nix::InstallableFlake::toDerivedPaths() + 0x144)
        [/Volumes/VOLUME/*/liblixcmd.dylib] 0x100dd8000 + 0x56154 (nix::Installable::toDerivations(nix::ref<nix::Store>, std::__1::vector<nix::ref<nix::Installable>, std::__1::allocator<nix::ref<nix::Installable>>> const&,
 bool) + 0x80)
        [/Volumes/VOLUME/*/nix] 0x1007d4000 + 0x4b0bc (Common::getShellOutPath(nix::ref<nix::Store>, nix::ref<nix::Installable>) + 0x124)
        [/Volumes/VOLUME/*/nix] 0x1007d4000 + 0x48048 (Common::getBuildEnvironment(nix::ref<nix::Store>, nix::ref<nix::Installable>) + 0x78)
        [/Volumes/VOLUME/*/nix] 0x1007d4000 + 0x59988 (CmdDevelop::run(nix::ref<nix::Store>, nix::ref<nix::Installable>) + 0x80)
        [/Volumes/VOLUME/*/liblixcmd.dylib] 0x100dd8000 + 0x586ec (nix::InstallableCommand::run(nix::ref<nix::Store>) + 0xd0)
        [/Volumes/VOLUME/*/liblixcmd.dylib] 0x100dd8000 + 0x32ae0 (nix::StoreCommand::run() + 0x40)
        [/Volumes/VOLUME/*/nix] 0x1007d4000 + 0xa4288 (nix::mainWrapped(int, char**) + 0x169c)
        [/Volumes/VOLUME/*/liblixmain.dylib] 0x100b98000 + 0x1e388 (nix::handleExceptions(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, std::__1::function<void ()>) + 0x120)
        [/Volumes/VOLUME/*/nix] 0x1007d4000 + 0xaaaac (main + 0x70)
        [/usr/lib/dyld] 0x182f22000 + 0x6274 (start + 0xb18)

Binaries: /nix/store/93ni93d5g2v62kz9a0v3cwn5p0qrq8nl-lix-2.91.0/bin/lix (should be in https://cache.lix.systems).

Annotated disassembly of faulting function

000000000002fc0c <nix::mapStaticEnvBindings(nix::SymbolTable const&, nix::StaticEnv const&, nix::Env const&, std::__1::map<std::string, nix::Value*>&)>:
; nix::mapStaticEnvBindings(nix::SymbolTable const&, nix::StaticEnv const&, nix::Env const&, std::__1::map<std::string, nix::Value*, std::__1::less<std::string>, traceable_allocator<std::__1::pair<std::string const, nix::Value*>>>&)():
   2fc0c: d101c3ff     	sub	sp, sp, #0x70
   2fc10: a90267fa     	stp	x26, x25, [sp, #0x20]
   2fc14: a9035ff8     	stp	x24, x23, [sp, #0x30]
   2fc18: a90457f6     	stp	x22, x21, [sp, #0x40]
   2fc1c: a9054ff4     	stp	x20, x19, [sp, #0x50]
   2fc20: a9067bfd     	stp	x29, x30, [sp, #0x60]
   2fc24: 910183fd     	add	x29, sp, #0x60
   2fc28: aa0203f4     	mov	x20, x2
   2fc2c: b0000e48     	adrp	x8, 0x1f8000 <dyld_stub_binder+0x1f8000>
   2fc30: f9461908     	ldr	x8, [x8, #0xc30]
   2fc34: f9400108     	ldr	x8, [x8]
   2fc38: f9000fe8     	str	x8, [sp, #0x18]
	; x2 = ((Env *)x2)->up
   2fc3c: f9400042     	ldr	x2, [x2]
   2fc40: b4000922     	cbz	x2, 0x2fd64 leave
	; x0 = SymbolTable *st
	; x1 = StaticEnv * se
	; x2 = Env * env
	; x3 = ValMap * vm
   2fc44: aa0103f6     	mov	x22, x1
	; x1 = ((StaticEnv *)x1)->up
   2fc48: f9400421     	ldr	x1, [x1, #0x8]
   2fc4c: b40008c1     	cbz	x1, 0x2fd64 leave

    ; save x0, x3
   2fc50: aa0303f3     	mov	x19, x3
   2fc54: aa0003f5     	mov	x21, x0
    ; recurse with:
    ; x0 = orig_x0
    ; x1 = orig_x1->up
    ; x2 = orig_x2->up
    ; mapStaticEnvBindings(st, *se.up, *env.up, vm);
   2fc58: 97ffffed     	bl	0x2fc0c <nix::mapStaticEnvBindings>

    ; x8 = se->isWith
   2fc5c: f94002c8     	ldr	x8, [x22]
   2fc60: b40000a8     	cbz	x8, 0x2fc74 isnt_with

    ; x8 = (Value *)env->values[0]
   2fc64: f9400688     	ldr	x8, [x20, #0x8]
    ; w9 = x8->internalType
   2fc68: b9400109     	ldr	w9, [x8]
     ; internalType == tThunk
   2fc6c: 7100293f     	cmp	w9, #0xa
   2fc70: 540003a1     	b.ne	0x2fce4 <nix::mapStaticEnvBindings+0xd8> notThunk

isnt_with:
   2fc74: a94162d7     	ldp	x23, x24, [x22, #0x10]
   2fc78: eb1802ff     	cmp	x23, x24
   2fc7c: 54000740     	b.eq	0x2fd64 leave
   2fc80: 9100a2b5     	add	x21, x21, #0x28
   2fc84: d0000cd6     	adrp	x22, 0x1c9000 <typeinfo name for nix::ExprOpUpdate+0xf>
   2fc88: 910c7ad6     	add	x22, x22, #0x31e
   2fc8c: b94002e8     	ldr	w8, [x23]
   2fc90: b94002a9     	ldr	w9, [x21]
   2fc94: 51000501     	sub	w1, w8, #0x1
   2fc98: 6b09003f     	cmp	w1, w9
   2fc9c: 540007e2     	b.hs	0x2fd98 <nix::mapStaticEnvBindings+0x18c>
   2fca0: b94006e8     	ldr	w8, [x23, #0x4]
   2fca4: 8b080e88     	add	x8, x20, x8, lsl #3
   2fca8: f9400519     	ldr	x25, [x8, #0x8]
   2fcac: aa1503e0     	mov	x0, x21
   2fcb0: 97ff7ccf     	bl	0xefec <nix::ChunkedVector<std::string, 8192ul>::operator[](unsigned int) const>
   2fcb4: aa0003e1     	mov	x1, x0
   2fcb8: f9000be0     	str	x0, [sp, #0x10]
   2fcbc: 910043e3     	add	x3, sp, #0x10
   2fcc0: 910023e4     	add	x4, sp, #0x8
   2fcc4: aa1303e0     	mov	x0, x19
   2fcc8: aa1603e2     	mov	x2, x22
   2fccc: 94007975     	bl	0x4e2a0 <std::__1::pair<std::__1::__tree_iterator<std::__1::__value_type<std::string, nix::Value*>, std::__1::__tree_node<std::__1::__value_type<std::string, nix::Value*>, void*>*, long>, bool> std::__1::__tree<std::__1::__value_type<std::string, nix::Value*>, std::__1::__map_value_compare<std::string, std::__1::__value_type<std::string, nix::Value*>, std::__1::less<std::string>, true>, traceable_allocator<std::__1::__value_type<std::string, nix::Value*>>>::__emplace_unique_key_args<std::string, std::__1::piecewise_construct_t const&, std::__1::tuple<std::string const&>, std::__1::tuple<>>(std::string const&, std::__1::piecewise_construct_t const&, std::__1::tuple<std::string const&>&&, std::__1::tuple<>&&)>
   2fcd0: f9001c19     	str	x25, [x0, #0x38]
   2fcd4: 910022f7     	add	x23, x23, #0x8
   2fcd8: eb1802ff     	cmp	x23, x24
   2fcdc: 54fffd81     	b.ne	0x2fc8c <nix::mapStaticEnvBindings+0x80>
   2fce0: 14000021     	b	0x2fd64 leave

notThunk:
    ; x8 = (Bindings *)((Value *)x8)->attrs
   2fce4: f9400508     	ldr	x8, [x8, #0x8]
	;; CRASH HERE ;;
	; x8 = 0 so null deref
    ; w9 = ((Bindings*)x8)->size
   2fce8: b9400509     	ldr	w9, [x8, #0x4]

    ; x9 *= 16 (sizeof (Attr))
   2fcec: d37ced29     	lsl	x9, x9, #4
   2fcf0: b40003a9     	cbz	x9, 0x2fd64 leave

    ; x23 = &x8->attrs
   2fcf4: 91004117     	add	x23, x8, #0x10
    ; x21 = st-> something (i am *not* confident in my offset calculations here from Linux)
   2fcf8: 9100a2b5     	add	x21, x21, #0x28
   2fcfc: d0000cd6     	adrp	x22, 0x1c9000 <typeinfo name for nix::ExprOpUpdate+0xf>
   2fd00: 910c7ad6     	add	x22, x22, #0x31e
   2fd04: b94002e8     	ldr	w8, [x23]
   2fd08: b94002a9     	ldr	w9, [x21]
   2fd0c: 51000501     	sub	w1, w8, #0x1
   2fd10: 6b09003f     	cmp	w1, w9
   2fd14: 54000422     	b.hs	0x2fd98 <nix::mapStaticEnvBindings+0x18c>
   2fd18: f94006f8     	ldr	x24, [x23, #0x8]
   2fd1c: aa1503e0     	mov	x0, x21
   2fd20: 97ff7cb3     	bl	0xefec <nix::ChunkedVector<std::string, 8192ul>::operator[](unsigned int) const>
   2fd24: aa0003e1     	mov	x1, x0
   2fd28: f9000be0     	str	x0, [sp, #0x10]
   2fd2c: 910043e3     	add	x3, sp, #0x10
   2fd30: 910023e4     	add	x4, sp, #0x8
   2fd34: aa1303e0     	mov	x0, x19
   2fd38: aa1603e2     	mov	x2, x22
   2fd3c: 94007959     	bl	0x4e2a0 <std::__1::pair<std::__1::__tree_iterator<std::__1::__value_type<std::string, nix::Value*>, std::__1::__tree_node<std::__1::__value_type<std::string, nix::Value*>, void*>*, long>, bool> std::__1::__tree<std::__1::__value_type<std::string, nix::Value*>, std::__1::__map_value_compare<std::string, std::__1::__value_type<std::string, nix::Value*>, std::__1::less<std::string>, true>, traceable_allocator<std::__1::__value_type<std::string, nix::Value*>>>::__emplace_unique_key_args<std::string, std::__1::piecewise_construct_t const&, std::__1::tuple<std::string const&>, std::__1::tuple<>>(std::string const&, std::__1::piecewise_construct_t const&, std::__1::tuple<std::string const&>&&, std::__1::tuple<>&&)>
   2fd40: f9001c18     	str	x24, [x0, #0x38]
   2fd44: f9400688     	ldr	x8, [x20, #0x8]
   2fd48: f9400508     	ldr	x8, [x8, #0x8]
   2fd4c: b9400509     	ldr	w9, [x8, #0x4]
   2fd50: 8b091108     	add	x8, x8, x9, lsl #4
   2fd54: 910042e9     	add	x9, x23, #0x10
   2fd58: eb0802ff     	cmp	x23, x8
   2fd5c: aa0903f7     	mov	x23, x9
   2fd60: 54fffd21     	b.ne	0x2fd04 <nix::mapStaticEnvBindings+0xf8>

leave:
    ; leave
   2fd64: f9400fe8     	ldr	x8, [sp, #0x18]
   2fd68: b0000e49     	adrp	x9, 0x1f8000 <dyld_stub_binder+0x1f8000>
   2fd6c: f9461929     	ldr	x9, [x9, #0xc30]
   2fd70: f9400129     	ldr	x9, [x9]
   2fd74: eb08013f     	cmp	x9, x8
   2fd78: 54000121     	b.ne	0x2fd9c <nix::mapStaticEnvBindings+0x190>
   2fd7c: a9467bfd     	ldp	x29, x30, [sp, #0x60]
   2fd80: a9454ff4     	ldp	x20, x19, [sp, #0x50]
   2fd84: a94457f6     	ldp	x22, x21, [sp, #0x40]
   2fd88: a9435ff8     	ldp	x24, x23, [sp, #0x30]
   2fd8c: a94267fa     	ldp	x26, x25, [sp, #0x20]
   2fd90: 9101c3ff     	add	sp, sp, #0x70
   2fd94: d65f03c0     	ret
   2fd98: 9405e751     	bl	0x1a9adc <dyld_stub_binder+0x1a9adc>
   2fd9c: 9405e74a     	bl	0x1a9ac4 <dyld_stub_binder+0x1a9ac4>

Crashing function sources:

void mapStaticEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & env, ValMap & vm)
{
    // add bindings for the next level up first, so that the bindings for this level
    // override the higher levels.
    // The top level bindings (builtins) are skipped since they are added for us by initEnv()
    if (env.up && se.up) {
        mapStaticEnvBindings(st, *se.up, *env.up, vm);

        if (se.isWith && !env.values[0]->isThunk()) {
            // add 'with' bindings.
            // CRASH HERE
            Bindings::iterator j = env.values[0]->attrs->begin();
            while (j != env.values[0]->attrs->end()) {
                vm[st[j->name]] = j->value;
                ++j;
            }
        } else {
            // iterate through staticenv bindings and add them.
            for (auto & i : se.vars)
                vm[st[i.first]] = env.values[i.second];
        }
    }
}

Analysis

The program crashed with SEGV since x8 was a null pointer. This corresponds to:

            Bindings::iterator j = env.values[0]->attrs->begin();

Specifically, env.values[0]->attrs is nullptr, so calling ->begin() on it crashes when trying to read the bindings object's size.

Do I have any idea why attrs was nullptr? no lol. I would like a reproducer, but I am not sure if we are getting one of those.

``` $ command nix develop --debugger trace: checking if /hadrian/hadrian.cabal is present: no error: undefined variable 'happy' at /nix/store/n2byjw7c7hxzvqpd4nq3k8h8qr64a8h9-source/ghc.nix:275:20: 274| export GHCPKG=$NIX_GHCPKG 275| export HAPPY=${happy}/bin/happy | ^ 276| export ALEX=${alex}/bin/alex evaluating derivation 'git+file:///Users/wiggles/ghc.nix#devShells.aarch64-darwin.default'fish: Job 1, 'command nix develop --debugger' terminated by signal SIGSEGV (Address boundary error) ``` Crash report: ``` lix/lix2 » pycrashreport /home/jade/Downloads/nix-2024-12-02-131817.ips 8F03B9F8-8BBD-4578-BCEC-6D8F550DDFC0 2024-12-02 13:18:17 /home/jade/Downloads/nix-2024-12-02-131817.ips Exception: EXC_BAD_ACCESS Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000004 Registers: x0 = 0x0000000111c2cb40 x1 = 0x0000000000000001 x2 = 0x0000000000000000 x3 = 0x0000000000000000 x4 = 0x000000000000006f x5 = 0x0000000000000070 x6 = 0x0000000000002d80 x7 = 0x0000000000000000 x8 = 0x0000000000000000 x9 = 0x0000000000000002 x10 = 0x0000000000000001 x11 = 0x0000000000006000 x12 = 0x0000000000000018 x13 = 0x0000600004faa020 x14 = 0x00000000001ff800 x15 = 0x00000000000007fb x16 = 0x000000010142f3b4 x17 = 0x00000001f061e460 x18 = 0x0000000000000000 x19 = 0x0000600004882d80 x20 = 0x000000010352dfe0 x21 = 0x00000001034f4aa8 x22 = 0x00006000018f1398 x23 = 0x00006000018f5b58 x24 = 0x000000010114c928 x25 = 0x000000016f6209c0 x26 = 0x00006000071b0008 x27 = 0x000060002125acd8 x28 = 0x000000016f6209c0 x0 = 0x0000000111c2cb40 x1 = 0x0000000000000001 x2 = 0x0000000000000000 x3 = 0x0000000000000000 x4 = 0x000000000000006f x5 = 0x0000000000000070 x6 = 0x0000000000002d80 x7 = 0x0000000000000000 x8 = 0x0000000000000000 x9 = 0x0000000000000002 x10 = 0x0000000000000001 x11 = 0x0000000000006000 x12 = 0x0000000000000018 x13 = 0x0000600004faa020 x14 = 0x00000000001ff800 x15 = 0x00000000000007fb x16 = 0x000000010142f3b4 x17 = 0x00000001f061e460 x18 = 0x0000000000000000 x19 = 0x0000600004882d80 x20 = 0x000000010352dfe0 x21 = 0x00000001034f4aa8 x22 = 0x00006000018f1398 x23 = 0x00006000018f5b58 x24 = 0x000000010114c928 x25 = 0x000000016f6209c0 x26 = 0x00006000071b0008 x27 = 0x000060002125acd8 x28 = 0x000000016f6209c0 lr = 0x0000000101a0fc5c cpsr = 0x0000000080001000 fp = 0x000000016f620770 sp = 0x000000016f620710 esr = 0x0000000092000006 pc = 0x0000000101a0fce8 far = 0x0000000000000004 Frames: [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x2fce8 (nix::mapStaticEnvBindings() + 0xdc) [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x2fc5c (nix::mapStaticEnvBindings() + 0x50) [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x2fc5c (nix::mapStaticEnvBindings() + 0x50) [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x30320 (nix::EvalState::runDebugRepl(nix::Error const*, nix::Env const&, nix::Expr const&) + 0x4cc) [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x24148 (nix::EvalErrorBuilder<nix::UndefinedVarError>::debugThrow() + 0x50) [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x31ae4 (nix::EvalState::lookupVar(nix::Env*, nix::ExprVar const&, bool) + 0x254) [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x33da4 (nix::ExprVar::eval(nix::EvalState&, nix::Env&, nix::Value&) + 0x4c) [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x39f28 (nix::ExprConcatStrings::eval(nix::EvalState&, nix::Env&, nix::Value&) + 0x12c) [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0xcb15c (nix::derivationStrictInternal(nix::EvalState&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, nix::Bindings* , nix::Value&) + 0x478) [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0xb8dec (nix::prim_derivationStrict(nix::EvalState&, nix::PosIdx, nix::Value**, nix::Value&) + 0xd8) [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x360a8 (nix::EvalState::callFunction(nix::Value&, unsigned long, nix::Value**, nix::Value&, nix::PosIdx) + 0x3f4) [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x37f44 (nix::ExprCall::eval(nix::EvalState&, nix::Env&, nix::Value&) + 0x25c) [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x33df4 (nix::ExprVar::eval(nix::EvalState&, nix::Env&, nix::Value&) + 0x9c) [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x33ef4 (nix::ExprSelect::eval(nix::EvalState&, nix::Env&, nix::Value&) + 0x5c) [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x34358 (nix::ExprSelect::eval(nix::EvalState&, nix::Env&, nix::Value&) + 0x4c0) [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x14a18 (nix::eval_cache::AttrCursor::forceValue() + 0x138) [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x171a4 (nix::eval_cache::AttrCursor::getString() + 0xc0) [/Volumes/VOLUME/*/liblixexpr.dylib] 0x1019e0000 + 0x18e28 (nix::eval_cache::AttrCursor::forceDerivation() + 0x5c) [/Volumes/VOLUME/*/liblixcmd.dylib] 0x100dd8000 + 0x459ac (nix::InstallableFlake::toDerivedPaths() + 0x144) [/Volumes/VOLUME/*/liblixcmd.dylib] 0x100dd8000 + 0x56154 (nix::Installable::toDerivations(nix::ref<nix::Store>, std::__1::vector<nix::ref<nix::Installable>, std::__1::allocator<nix::ref<nix::Installable>>> const&, bool) + 0x80) [/Volumes/VOLUME/*/nix] 0x1007d4000 + 0x4b0bc (Common::getShellOutPath(nix::ref<nix::Store>, nix::ref<nix::Installable>) + 0x124) [/Volumes/VOLUME/*/nix] 0x1007d4000 + 0x48048 (Common::getBuildEnvironment(nix::ref<nix::Store>, nix::ref<nix::Installable>) + 0x78) [/Volumes/VOLUME/*/nix] 0x1007d4000 + 0x59988 (CmdDevelop::run(nix::ref<nix::Store>, nix::ref<nix::Installable>) + 0x80) [/Volumes/VOLUME/*/liblixcmd.dylib] 0x100dd8000 + 0x586ec (nix::InstallableCommand::run(nix::ref<nix::Store>) + 0xd0) [/Volumes/VOLUME/*/liblixcmd.dylib] 0x100dd8000 + 0x32ae0 (nix::StoreCommand::run() + 0x40) [/Volumes/VOLUME/*/nix] 0x1007d4000 + 0xa4288 (nix::mainWrapped(int, char**) + 0x169c) [/Volumes/VOLUME/*/liblixmain.dylib] 0x100b98000 + 0x1e388 (nix::handleExceptions(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&, std::__1::function<void ()>) + 0x120) [/Volumes/VOLUME/*/nix] 0x1007d4000 + 0xaaaac (main + 0x70) [/usr/lib/dyld] 0x182f22000 + 0x6274 (start + 0xb18) ``` Binaries: `/nix/store/93ni93d5g2v62kz9a0v3cwn5p0qrq8nl-lix-2.91.0/bin/lix` (should be in https://cache.lix.systems). Annotated disassembly of faulting function ```asm 000000000002fc0c <nix::mapStaticEnvBindings(nix::SymbolTable const&, nix::StaticEnv const&, nix::Env const&, std::__1::map<std::string, nix::Value*>&)>: ; nix::mapStaticEnvBindings(nix::SymbolTable const&, nix::StaticEnv const&, nix::Env const&, std::__1::map<std::string, nix::Value*, std::__1::less<std::string>, traceable_allocator<std::__1::pair<std::string const, nix::Value*>>>&)(): 2fc0c: d101c3ff sub sp, sp, #0x70 2fc10: a90267fa stp x26, x25, [sp, #0x20] 2fc14: a9035ff8 stp x24, x23, [sp, #0x30] 2fc18: a90457f6 stp x22, x21, [sp, #0x40] 2fc1c: a9054ff4 stp x20, x19, [sp, #0x50] 2fc20: a9067bfd stp x29, x30, [sp, #0x60] 2fc24: 910183fd add x29, sp, #0x60 2fc28: aa0203f4 mov x20, x2 2fc2c: b0000e48 adrp x8, 0x1f8000 <dyld_stub_binder+0x1f8000> 2fc30: f9461908 ldr x8, [x8, #0xc30] 2fc34: f9400108 ldr x8, [x8] 2fc38: f9000fe8 str x8, [sp, #0x18] ; x2 = ((Env *)x2)->up 2fc3c: f9400042 ldr x2, [x2] 2fc40: b4000922 cbz x2, 0x2fd64 leave ; x0 = SymbolTable *st ; x1 = StaticEnv * se ; x2 = Env * env ; x3 = ValMap * vm 2fc44: aa0103f6 mov x22, x1 ; x1 = ((StaticEnv *)x1)->up 2fc48: f9400421 ldr x1, [x1, #0x8] 2fc4c: b40008c1 cbz x1, 0x2fd64 leave ; save x0, x3 2fc50: aa0303f3 mov x19, x3 2fc54: aa0003f5 mov x21, x0 ; recurse with: ; x0 = orig_x0 ; x1 = orig_x1->up ; x2 = orig_x2->up ; mapStaticEnvBindings(st, *se.up, *env.up, vm); 2fc58: 97ffffed bl 0x2fc0c <nix::mapStaticEnvBindings> ; x8 = se->isWith 2fc5c: f94002c8 ldr x8, [x22] 2fc60: b40000a8 cbz x8, 0x2fc74 isnt_with ; x8 = (Value *)env->values[0] 2fc64: f9400688 ldr x8, [x20, #0x8] ; w9 = x8->internalType 2fc68: b9400109 ldr w9, [x8] ; internalType == tThunk 2fc6c: 7100293f cmp w9, #0xa 2fc70: 540003a1 b.ne 0x2fce4 <nix::mapStaticEnvBindings+0xd8> notThunk isnt_with: 2fc74: a94162d7 ldp x23, x24, [x22, #0x10] 2fc78: eb1802ff cmp x23, x24 2fc7c: 54000740 b.eq 0x2fd64 leave 2fc80: 9100a2b5 add x21, x21, #0x28 2fc84: d0000cd6 adrp x22, 0x1c9000 <typeinfo name for nix::ExprOpUpdate+0xf> 2fc88: 910c7ad6 add x22, x22, #0x31e 2fc8c: b94002e8 ldr w8, [x23] 2fc90: b94002a9 ldr w9, [x21] 2fc94: 51000501 sub w1, w8, #0x1 2fc98: 6b09003f cmp w1, w9 2fc9c: 540007e2 b.hs 0x2fd98 <nix::mapStaticEnvBindings+0x18c> 2fca0: b94006e8 ldr w8, [x23, #0x4] 2fca4: 8b080e88 add x8, x20, x8, lsl #3 2fca8: f9400519 ldr x25, [x8, #0x8] 2fcac: aa1503e0 mov x0, x21 2fcb0: 97ff7ccf bl 0xefec <nix::ChunkedVector<std::string, 8192ul>::operator[](unsigned int) const> 2fcb4: aa0003e1 mov x1, x0 2fcb8: f9000be0 str x0, [sp, #0x10] 2fcbc: 910043e3 add x3, sp, #0x10 2fcc0: 910023e4 add x4, sp, #0x8 2fcc4: aa1303e0 mov x0, x19 2fcc8: aa1603e2 mov x2, x22 2fccc: 94007975 bl 0x4e2a0 <std::__1::pair<std::__1::__tree_iterator<std::__1::__value_type<std::string, nix::Value*>, std::__1::__tree_node<std::__1::__value_type<std::string, nix::Value*>, void*>*, long>, bool> std::__1::__tree<std::__1::__value_type<std::string, nix::Value*>, std::__1::__map_value_compare<std::string, std::__1::__value_type<std::string, nix::Value*>, std::__1::less<std::string>, true>, traceable_allocator<std::__1::__value_type<std::string, nix::Value*>>>::__emplace_unique_key_args<std::string, std::__1::piecewise_construct_t const&, std::__1::tuple<std::string const&>, std::__1::tuple<>>(std::string const&, std::__1::piecewise_construct_t const&, std::__1::tuple<std::string const&>&&, std::__1::tuple<>&&)> 2fcd0: f9001c19 str x25, [x0, #0x38] 2fcd4: 910022f7 add x23, x23, #0x8 2fcd8: eb1802ff cmp x23, x24 2fcdc: 54fffd81 b.ne 0x2fc8c <nix::mapStaticEnvBindings+0x80> 2fce0: 14000021 b 0x2fd64 leave notThunk: ; x8 = (Bindings *)((Value *)x8)->attrs 2fce4: f9400508 ldr x8, [x8, #0x8] ;; CRASH HERE ;; ; x8 = 0 so null deref ; w9 = ((Bindings*)x8)->size 2fce8: b9400509 ldr w9, [x8, #0x4] ; x9 *= 16 (sizeof (Attr)) 2fcec: d37ced29 lsl x9, x9, #4 2fcf0: b40003a9 cbz x9, 0x2fd64 leave ; x23 = &x8->attrs 2fcf4: 91004117 add x23, x8, #0x10 ; x21 = st-> something (i am *not* confident in my offset calculations here from Linux) 2fcf8: 9100a2b5 add x21, x21, #0x28 2fcfc: d0000cd6 adrp x22, 0x1c9000 <typeinfo name for nix::ExprOpUpdate+0xf> 2fd00: 910c7ad6 add x22, x22, #0x31e 2fd04: b94002e8 ldr w8, [x23] 2fd08: b94002a9 ldr w9, [x21] 2fd0c: 51000501 sub w1, w8, #0x1 2fd10: 6b09003f cmp w1, w9 2fd14: 54000422 b.hs 0x2fd98 <nix::mapStaticEnvBindings+0x18c> 2fd18: f94006f8 ldr x24, [x23, #0x8] 2fd1c: aa1503e0 mov x0, x21 2fd20: 97ff7cb3 bl 0xefec <nix::ChunkedVector<std::string, 8192ul>::operator[](unsigned int) const> 2fd24: aa0003e1 mov x1, x0 2fd28: f9000be0 str x0, [sp, #0x10] 2fd2c: 910043e3 add x3, sp, #0x10 2fd30: 910023e4 add x4, sp, #0x8 2fd34: aa1303e0 mov x0, x19 2fd38: aa1603e2 mov x2, x22 2fd3c: 94007959 bl 0x4e2a0 <std::__1::pair<std::__1::__tree_iterator<std::__1::__value_type<std::string, nix::Value*>, std::__1::__tree_node<std::__1::__value_type<std::string, nix::Value*>, void*>*, long>, bool> std::__1::__tree<std::__1::__value_type<std::string, nix::Value*>, std::__1::__map_value_compare<std::string, std::__1::__value_type<std::string, nix::Value*>, std::__1::less<std::string>, true>, traceable_allocator<std::__1::__value_type<std::string, nix::Value*>>>::__emplace_unique_key_args<std::string, std::__1::piecewise_construct_t const&, std::__1::tuple<std::string const&>, std::__1::tuple<>>(std::string const&, std::__1::piecewise_construct_t const&, std::__1::tuple<std::string const&>&&, std::__1::tuple<>&&)> 2fd40: f9001c18 str x24, [x0, #0x38] 2fd44: f9400688 ldr x8, [x20, #0x8] 2fd48: f9400508 ldr x8, [x8, #0x8] 2fd4c: b9400509 ldr w9, [x8, #0x4] 2fd50: 8b091108 add x8, x8, x9, lsl #4 2fd54: 910042e9 add x9, x23, #0x10 2fd58: eb0802ff cmp x23, x8 2fd5c: aa0903f7 mov x23, x9 2fd60: 54fffd21 b.ne 0x2fd04 <nix::mapStaticEnvBindings+0xf8> leave: ; leave 2fd64: f9400fe8 ldr x8, [sp, #0x18] 2fd68: b0000e49 adrp x9, 0x1f8000 <dyld_stub_binder+0x1f8000> 2fd6c: f9461929 ldr x9, [x9, #0xc30] 2fd70: f9400129 ldr x9, [x9] 2fd74: eb08013f cmp x9, x8 2fd78: 54000121 b.ne 0x2fd9c <nix::mapStaticEnvBindings+0x190> 2fd7c: a9467bfd ldp x29, x30, [sp, #0x60] 2fd80: a9454ff4 ldp x20, x19, [sp, #0x50] 2fd84: a94457f6 ldp x22, x21, [sp, #0x40] 2fd88: a9435ff8 ldp x24, x23, [sp, #0x30] 2fd8c: a94267fa ldp x26, x25, [sp, #0x20] 2fd90: 9101c3ff add sp, sp, #0x70 2fd94: d65f03c0 ret 2fd98: 9405e751 bl 0x1a9adc <dyld_stub_binder+0x1a9adc> 2fd9c: 9405e74a bl 0x1a9ac4 <dyld_stub_binder+0x1a9ac4> ``` Crashing function sources: ```cpp void mapStaticEnvBindings(const SymbolTable & st, const StaticEnv & se, const Env & env, ValMap & vm) { // add bindings for the next level up first, so that the bindings for this level // override the higher levels. // The top level bindings (builtins) are skipped since they are added for us by initEnv() if (env.up && se.up) { mapStaticEnvBindings(st, *se.up, *env.up, vm); if (se.isWith && !env.values[0]->isThunk()) { // add 'with' bindings. // CRASH HERE Bindings::iterator j = env.values[0]->attrs->begin(); while (j != env.values[0]->attrs->end()) { vm[st[j->name]] = j->value; ++j; } } else { // iterate through staticenv bindings and add them. for (auto & i : se.vars) vm[st[i.first]] = env.values[i.second]; } } } ``` ## Analysis The program crashed with SEGV since x8 was a null pointer. This corresponds to: ```cpp Bindings::iterator j = env.values[0]->attrs->begin(); ``` Specifically, `env.values[0]->attrs` is `nullptr`, so calling `->begin()` on it crashes when trying to read the bindings object's size. Do I have any idea why attrs was nullptr? no lol. I would like a reproducer, but I am not sure if we are getting one of those.
jade added the
bug
crash 💥
labels 2024-12-04 23:13:19 +00:00
Author
Owner

cc @rbt as reporter

cc @rbt as reporter
Author
Owner

Though I am sure this file was in the process of being changed when Lix blew up, here is the approximate Nix code involved: 5f00003fc2/ghc.nix

Though I am sure this file was in the process of being changed when Lix blew up, here is the approximate Nix code involved: https://gitlab.haskell.org/ghc/ghc.nix/-/blob/5f00003fc28eb2df4aa914271e8cffca7e809d22/ghc.nix
Owner

reproducer:

❯  nix repl --debugger
Lix 2.92.0-dev-pre20241120-66f6dbd debugger
Type :? for help.
nix-repl> let x = 4; in __seq x (with x; (x: builtins.break x) 1)
info: breakpoint reached

[1]    949722 segmentation fault (core dumped)  nix repl --debugger

the !isThunk check in mapStaticEnvBindings is insufficient, it must be isAttrs

reproducer: ``` ❯ nix repl --debugger Lix 2.92.0-dev-pre20241120-66f6dbd debugger Type :? for help. nix-repl> let x = 4; in __seq x (with x; (x: builtins.break x) 1) info: breakpoint reached [1] 949722 segmentation fault (core dumped) nix repl --debugger ``` the `!isThunk` check in mapStaticEnvBindings is insufficient, it must be isAttrs
Author
Owner

Oh yeah, from the crash report we can observe that it was actually a bool since x9, which still should have the internal type as of the crash, is 2.

Oh yeah, from the crash report we can observe that it was actually a bool since x9, which still should have the internal type as of the crash, is 2.
jade added the
E/reproducible
label 2024-12-05 17:55:18 +00:00
rbt was assigned by jade 2024-12-06 01:18:03 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lix-project/lix#592
No description provided.