Subject: Re: bug#49261: 28.0.50; File Locking Breaks Presumptuous Toolchains

From: Eli Zaretskii <[email-masked]>
Date: Sat, 10 Jul 2021 20:04:51 +0300

> From: Lars Ingebrigtsen <[email-masked]>
> Cc: [email-masked],  [email-masked],  [email-masked]
> Date: Sat, 10 Jul 2021 18:25:27 +0200
> 
> (gdb) p $2->u.s.car
> $3 = XIL(0x2aaa9c41a9e0)
> (gdb) xtype
> Lisp_Symbol
> (gdb) xsymbol
> $4 = (struct Lisp_Symbol *) 0x7ffff1fc26c0
> "normal-top-level"
> (gdb) 
> 
> So it's segfaulting while evaling normal-top-level?

Yes.  Which is consistent with the backtrace, so this didn't teach us
anything new.

It would be good to try to understand byte code of which function is
being run in frame #3 here:

> Thread 1 "bootstrap-emacs" received signal SIGSEGV, Segmentation fault.
> 0x00005555556f0549 in AREF (idx=6988131860, array=XIL(0x7ffff1bd901d))
>     at lisp.h:731
> 731	  return lisp_h_XLP (o);
> (gdb) bt
> #0  0x00005555556f0549 in AREF (idx=6988131860, array=XIL(0x7ffff1bd901d))
>     at lisp.h:731
> #1  HASH_KEY (idx=3494065930, h=0x7ffff1bd8f98) at lisp.h:2374
> #2  hash_lookup
>     (h=0x7ffff1bd8f98, key=XIL(0x555555c76c64), hash=hash@entry=0x0)
>     at fns.c:4479
> #3  0x0000555555719cb9 in exec_byte_code
>     (bytestr=<optimized out>, vector=<optimized out>, maxdepth=<optimized out>, args_template=args_template@entry=make_fixnum(257), nargs=nargs@entry=1, args=<optimized out>, args@entry=0x7fffffffd940) at bytecode.c:1415
> #4  0x00005555556e643f in fetch_and_exec_byte_code
>     (args=0x7fffffffd940, nargs=1, syms_left=make_fixnum(257), fun=XIL(0x7ffff1bc9895)) at lisp.h:731
> #5  funcall_lambda
>     (fun=XIL(0x7ffff1bc9895), nargs=nargs@entry=1, arg_vector=arg_vector@entry=0x7fffffffd940) at eval.c:3244

The problem is this is an optimized build and many variables are
"optimized out".

Line 1415 of bytecomp.c is here:

        CASE (Bswitch):
          {
            /* TODO: Perhaps introduce another byte-code for switch when the
	       number of cases is less, which uses a simple vector for linear
	       search as the jump table.  */
            Lisp_Object jmp_table = POP;
	    if (BYTE_CODE_SAFE && !HASH_TABLE_P (jmp_table))
              emacs_abort ();
            Lisp_Object v1 = POP;
            ptrdiff_t i;
            struct Lisp_Hash_Table *h = XHASH_TABLE (jmp_table);

            /* h->count is a faster approximation for HASH_TABLE_SIZE (h)
               here. */
            if (h->count <= 5 && !h->test.cmpfn)
              { /* Do a linear search if there are not many cases
                   FIXME: 5 is arbitrarily chosen.  */
		for (i = h->count; 0 <= --i; )
		  if (EQ (v1, HASH_KEY (h, i)))
		    break;
              }
            else
              i = hash_lookup (h, v1, NULL);  <<<<<<<<<<<<<<<<<

Stefan, what code in command-line-1 is likely to produce the Bswitch
byte-code?

Anyway, looking at frame 1, I guess the value of 'idx' is bogus, which
means something is wrong with the hash table.  So maybe we should
audit the part(s) of the offending commit that have something to do
with hash tables?  Also, what kind of hash-table are we looking up
there, is it possible to understand that by looking at the variables
involved in the above code?