Bug #80243 [Opn]: OPCache JIT segfaults at startup

From: Date: Tue, 20 Oct 2020 15:32:09 +0000
Subject: Bug #80243 [Opn]: OPCache JIT segfaults at startup
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-229806@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=80243&edit=1

 ID:                 80243
 Updated by:         nikic@php.net
 Reported by:        jens-erik dot riedel at kippdata dot de
 Summary:            OPCache JIT segfaults at startup
 Status:             Open
 Type:               Bug
 Package:            JIT
 Operating System:   RHEL 8.0
 PHP Version:        8.0.0rc1
 Block user comment: N
 Private report:     N

 New Comment:

Thank you for the investigation, this is rather intriguing. I find is hard to believe that this is
an allocator bug (I don't think I've seen one of those in years), it's more likely
that something is corrupting the allocator state.

There's two simple things that could be tried:
1. Run "USE_ZEND_ALLOC=0 php". That will switch to using the system allocator -- which
will possibly make it work, or crash harder...
2. Run "USE_ZEND_ALLOC=0 valgrind php", which might point out memory corruption. (In this
case, "USE_ZEND_ALLOC=1 valgrind php" might also be interesting.)


Previous Comments:
------------------------------------------------------------------------
[2020-10-20 15:00:49] brainpower at mailbox dot org

I've stepped through dasm_setupglobal, too, and added that to the gist.
At the end of that function, after the "realloc", D and D->lglabels are the same.

So maybe not a Bug in JIT but in the allocation function?

Please let me know if you need more information.

------------------------------------------------------------------------
[2020-10-20 14:51:42] brainpower at mailbox dot org

Found it: https://gist.github.com/brainpower/d85cc63d6820dd2fb65d12ca52f5f957#file-gistfile2-txt-L19

I've stepped through another time, since I thought the parameters to the memset may be
important.
Well   D->lglabels  points to the same address as D, so the memset overwrites D, obviously.
(Lines 19 and 23 of gistfile2.txt)

D->lglabels is touched only in dasm_setupglobal() before dasm_setup() is called, as far as I can
see.

------------------------------------------------------------------------
[2020-10-20 14:24:50] brainpower at mailbox dot org

https://gist.github.com/brainpower/d85cc63d6820dd2fb65d12ca52f5f957

Here's stepping through dasm_setup() up to the point where D->section is broken.
As I thought, it seems something is wrong with the memsets in there...

I've added the configure command to the gist, too.
Maybe some feature I've enabled messes with things.

------------------------------------------------------------------------
[2020-10-20 14:10:23] nikic@php.net

Would it be possible for you to set a break point on dasm_setup, step through it, and check that
D->section is initialized at the end?

In the meantime, I've done a php-8.0.0RC2 build on CentOS 7 (rather than Ubuntu 20.04) and
wasn't able to reproduce the issue there either.

------------------------------------------------------------------------
[2020-10-20 13:25:53] brainpower at mailbox dot org

Lots of other members of D are zeroed, not sure if that's ok or not:

Program received signal SIGSEGV, Segmentation fault.
dasm_put (Dst=Dst@entry=0x7fffffffcc00, start=start@entry=5) at
/root/shmbuild/src/php-8.0.0RC2/ext/opcache/jit/dynasm/dasm_x86.h:176
176       int pos = sec->pos, ofs = sec->ofs, mrm = -1;
(gdb) print D->section
$1 = (dasm_Section *) 0x0
(gdb) print D->sections[0]
$2 = {rbuf = 0x0, buf = 0x0, bsize = 0, pos = 0, epos = 0, ofs = 0}
(gdb) print &D->sections[0]
$3 = (dasm_Section *) 0x7ffff3608150
(gdb) print D->maxsection
$4 = 0
(gdb) print D->status
$5 = 0
(gdb) print D->actionlist
$6 = (dasm_ActList) 0x0
(gdb) print D->lglabels
$7 = (int *) 0x0
(gdb) print D->lgsize
$8 = 0
(gdb) print D->pclabels
$9 = (int *) 0x0
(gdb) print D->pcsize
$10 = 0
(gdb) print D->globals
$11 = (void **) 0x0
(gdb) print D->psize
$12 = 0
(gdb) print D->codesize
$13 = 0
(gdb)

Maybe dasm_setup didn't run? Or some errand memset() overwrote the wrong thing(s)?

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=80243


--
Edit this bug report at https://bugs.php.net/bug.php?id=80243&edit=1


Thread (18 messages)

« previous php.bugs (#229806) next »