Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segfault with frameless jumps and minimal JIT #15981

Open
YuanchengJiang opened this issue Sep 22, 2024 · 5 comments · May be fixed by #17329
Open

Segfault with frameless jumps and minimal JIT #15981

YuanchengJiang opened this issue Sep 22, 2024 · 5 comments · May be fixed by #17329

Comments

@YuanchengJiang
Copy link

Description

The following code:

<?php
require('tester.inc');
$cfg = <<<EOT
EOT;
$code = <<<EOT
EOT;
$tester = new FPM\Tester($cfg, $code);
$tester->start();

Resulted in this output:

Zend/zend_vm_execute.h:6025:2: runtime error: member access within misaligned address 0x7fd6e5c0520f for type 'zval' (aka 'struct _zval_struct'), which requires 8 byte alignment
0x7fd6e5c0520f: note: pointer points here
 00 00 00 00 00  f8 12 0c 41 00 00 00 00  00 00 00 00 00 00 00 00  f0 51 c0 e5 d6 7f 00 00  58 09 0c
             ^ 
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior Zend/zend_vm_execute.h:6025:2

To reproduce:

-d "opcache.jit_hot_loop=1" -d "zend_extension=/php-src/modules/opcache.so" -d "opcache.enable_cli=1" -d "opcache.jit=1131"

tester.inc:

sapi/fpm/tests/tester.inc

PHP Version

PHP 8.4.0-dev

Operating System

ubuntu 22.04

@cmb69
Copy link
Member

cmb69 commented Sep 22, 2024

Looks related to #15658.

@nielsdos
Copy link
Member

nielsdos commented Sep 24, 2024

Semi-automatically reduced to:

<?php

namespace NS { // Namespace is important to reproduce the issue
    class Tester {
        static public function findExecutable(): string {
            for ($i = 0; $i < 2; $i++) {
                // Need this loop to reproduce
            }
            return dirname(__DIR__);
        }
    }
}

namespace {
    NS\Tester::findExecutable();
}

Or with opcache.jit=1111:

<?php

namespace NS { // Namespace is important to reproduce the issue
    class Tester {
        static public function findExecutable(): string {
            return dirname(__DIR__);
        }
    }
}

namespace {
    NS\Tester::findExecutable();
}

@nielsdos
Copy link
Member

nielsdos commented Sep 24, 2024

It's again related to FLFs.

ZEND_INIT_NS_FCALL_BY_NAME VM handler is called with opline->opcode == JMP_FRAMELESS and pointing at the wrong cache slot as a consequence.

I think the JIT should generate a move to %r15 with the right opline in both possible successor blocks of JMP_FRAMELESS, but I'm not sure how to do that properly. Using zend_jit_reset_last_valid_opline in zend_jit_jmp_frameless doesn't work because the following code resets the last valid opline:

if (JIT_G(opt_level) < ZEND_JIT_LEVEL_INLINE) {
if ((ssa->cfg.blocks[b].flags & ZEND_BB_FOLLOW)
&& ssa->cfg.blocks[b].start != 0
&& (op_array->opcodes[ssa->cfg.blocks[b].start - 1].opcode == ZEND_NOP
|| op_array->opcodes[ssa->cfg.blocks[b].start - 1].opcode == ZEND_SWITCH_LONG
|| op_array->opcodes[ssa->cfg.blocks[b].start - 1].opcode == ZEND_SWITCH_STRING
|| op_array->opcodes[ssa->cfg.blocks[b].start - 1].opcode == ZEND_MATCH)) {
zend_jit_reset_last_valid_opline(&ctx);
} else {
zend_jit_set_last_valid_opline(&ctx, op_array->opcodes + ssa->cfg.blocks[b].start);
}

@nielsdos
Copy link
Member

cc @dstogov I'm not sure how to fix this, I would need some input to know how to tackle this issue please.

@dstogov
Copy link
Member

dstogov commented Sep 25, 2024

I don't know this new code...
It looks like JIT code generated by zend_jit_jmp_frameless() doesn't update EX(opline).
Actually JIT with optimization_level=1 shouldn't generate the complex code at all.

cc @iluuu1994

@nielsdos nielsdos changed the title Segmentation fault in Zend/zend_vm_execute.h Segfault with frameless jumps and minimal JIT Jan 2, 2025
@nielsdos nielsdos linked a pull request Jan 2, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants