Imagick / imagick

🌈 The Imagick PHP extension 🌈
http://pecl.php.net/imagick
Other
536 stars 135 forks source link

OpenMP segmentation fault when compiling with clang+preload is enabled #637

Open danog opened 10 months ago

danog commented 10 months ago

Reproducer Dockerfile:

FROM ubuntu:22.04

ENV DEBIAN_FRONTEND=noninteractive

ENV CC=clang-16
ENV CXX=clang++-16

RUN true \
    && apt update \
    && apt install -y --no-install-recommends \
        tzdata software-properties-common locales curl apt-utils gpg-agent cron logrotate \
        gnupg2 ca-certificates lsb-release \
        make pkg-config binutils wget \
    && wget https://apt.llvm.org/llvm.sh \
    && chmod +x llvm.sh \
    && ./llvm.sh 16 all \
    && apt update \
    && apt install -y php-dev

RUN apt install imagemagick libmagickcore-dev libmagickwand-dev -y && \
    wget https://pecl.php.net/get/imagick && \
    tar -xf imagick && \
    rm imagick && \
    cd imagick* && \
    phpize && \
    ./configure --enable-debug && \
    \
    make -j100 && \
    make install

ADD php.imagick.ini /etc/php/8.1/cli/php.ini

RUN rm /etc/php/8.1/cli/conf.d/*

RUN echo '<?php var_dump("Preloaded");' > /tmp/a.php

WORKDIR /app

php.imagick.ini:

memory_limit = -1
zend.assertions = 1
display_errors = On
display_startup_errors = On
extension=imagick
[opcache]
zend_extension=opcache
opcache.memory_consumption=64M
opcache.enable=1
opcache.enable_cli=1
opcache.jit=disable

opcache.preload=/tmp/a.php
opcache.preload_user=root

opcache.protect_memory=1

Result:

root@bcc7ee2f4cae:/app# php -v
AddressSanitizer:DEADLYSIGNAL
=================================================================
==10==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000018 (pc 0x7f2a66e96286 bp 0x000000000000 sp 0x7ffe502bfcc0 T0)
==10==The signal is caused by a WRITE memory access.
==10==Hint: address points to the zero page.

    #0 0x7f2a66e96286  (/lib/x86_64-linux-gnu/libomp.so.5+0xa6286) (BuildId: 553aab45440348b202b8d0e3f285e2b48f827aea)
    #1 0x7f2a66e1f9ac in __kmpc_set_lock (/lib/x86_64-linux-gnu/libomp.so.5+0x2f9ac) (BuildId: 553aab45440348b202b8d0e3f285e2b48f827aea)
    #2 0x7f2a66b85353 in SetMagickResourceLimit (/lib/x86_64-linux-gnu/libMagickCore-6.Q16.so.6+0x18d353) (BuildId: 07037e3a04f36f23e9e9e17a83b2a3d5942c2670)
    #3 0x7f2a699b4c3c in zm_activate_imagick /imagick-3.7.0/imagick.c:1236:3
    #4 0x55e31cfe1acb in zend_activate_modules /php-src/Zend/zend_API.c:3091:7
    #5 0x55e31cdd6217 in php_request_startup /php-src/main/main.c:1785:3
    #6 0x7f2a675a0f81 in accel_finish_startup /php-src/ext/opcache/ZendAccelerator.c:4721:8
    #7 0x7f2a6759e138 in accel_post_startup /php-src/ext/opcache/ZendAccelerator.c:3356:6
    #8 0x55e31cfb9a85 in zend_post_startup /php-src/Zend/zend.c:1045:7
    #9 0x55e31cdd89c6 in php_module_startup /php-src/main/main.c:2294:6
    #10 0x55e31d536f38 in php_cli_startup /php-src/sapi/cli/php_cli.c:410:9
    #11 0x55e31d533068 in main /php-src/sapi/cli/php_cli.c:1300:6
    #12 0x7f2a6a3d5d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId: a43bfc8428df6623cd498c9c0caeb91aec9be4f9)
    #13 0x7f2a6a3d5e3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f) (BuildId: a43bfc8428df6623cd498c9c0caeb91aec9be4f9)
    #14 0x55e31c602354 in _start (/usr/local/bin/php+0x402354) (BuildId: b5620a3713a279732d643f558dbbee599c56c20b)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/lib/x86_64-linux-gnu/libomp.so.5+0xa6286) (BuildId: 553aab45440348b202b8d0e3f285e2b48f827aea)
==10==ABORTING
danog commented 10 months ago

The same segfault also occurs on shutdown in certain conditions even when opcache is disabled (opcache.enable_cli=0).

danog commented 10 months ago

Actually the issue seems to be unrelated to ASAN, it just always segfaults when compiling with clang

danog commented 10 months ago

Clang 14 is also affected (which is the version offered by default on ubuntu 22.04)

Danack commented 10 months ago

I don't get exactly the same result as you.

For me, trying to run PHP exits silently with 1 as the exit code. Running it through valgrind, which I normally use to investigate weird crashes, gives:

# valgrind php
==315== Memcheck, a memory error detector
==315== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==315== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==315== Command: php
==315==
### unhandled dwarf2 abbrev form code 0x25
### unhandled dwarf2 abbrev form code 0x25
### unhandled dwarf2 abbrev form code 0x25
### unhandled dwarf2 abbrev form code 0x1b
### unhandled dwarf2 abbrev form code 0x25
### unhandled dwarf2 abbrev form code 0x25
### unhandled dwarf2 abbrev form code 0x25
### unhandled dwarf2 abbrev form code 0x1b
==315== Valgrind: debuginfo reader: ensure_valid failed:
==315== Valgrind:   during call to ML_(img_get)
==315== Valgrind:   request for range [107074559, +4) exceeds
==315== Valgrind:   valid image size of 1069896 for image:
==315== Valgrind:   "/usr/lib/php/20210902/imagick.so"
==315==
==315== Valgrind: debuginfo reader: Possibly corrupted debuginfo file.
==315== Valgrind: I can't recover.  Giving up.  Sorry.
==315==

According to this that might be avoided by Try compiling with -gdwarf-4 instead of just -g

Can you tell me how to pass that flag to clang?

danog commented 10 months ago

@Danack I suppose just passing it in the CFLAGS and CXXFLAGS envvars should help!