View Issue Details

IDProjectCategoryView StatusLast Update
0001790XdebugStep Debuggingpublic2020-05-28 14:38
Reporterdustinmailc Assigned Toderick  
PriorityhighSeveritycrashReproducibilityalways
Status closedResolutionfixed 
OSLinuxOS VersionDebian 
Product Version2.9.5 
Fixed in Version2.9.6 
Summary0001790: Segfault in var_dump() or while debugging with protobuf extension
Description

While debugging scripts with classes that use the protobuf extension, the php interpreter segfaults reliably when xdebug inspects instances of classes from the extension. The crash also occurs when calling var_dump() with xdebug's var_dump() override enabled. This crash prevents us from using step debugging when the protobuf extension is enabled.

Steps To Reproduce

Since this requires a separate extension to reproduce, I put together a containerized demonstration of this here: https://github.com/dcloues/xdebug-protobuf-segfault

I used the protobuf extension for this, but I believe the crash will occur with any internal class that has a get_properties() handler that returns null.

Additional Information

I tested adding a null check here: https://github.com/xdebug/xdebug/blob/00a928eb760833a07e01a7b17cc040e4f3a8a077/src/lib/var_export_text.c#L250 which seems to resolve the issue. I'd be happy to open a pull request for this change.

TagsSIGSEGV
Attached Files
Operating SystemDebian Linux
PHP Version7.4.0-7.4.4

Activities

dustinmailc

2020-05-26 15:07

reporter   ~0005416

I forgot to include a gdb backtrace from this - sorry about that! I attached it here.

backtrace.txt (4,331 bytes)   
Program received signal SIGSEGV, Segmentation fault.
xdebug_zend_hash_is_recursive (ht=ht@entry=0x0) at /tmp/pear/temp/xdebug/src/lib/compat.c:433
#0  xdebug_zend_hash_is_recursive (ht=ht@entry=0x0) at /tmp/pear/temp/xdebug/src/lib/compat.c:433
433	/tmp/pear/temp/xdebug/src/lib/compat.c: No such file or directory.
No locals.
#1  0x00007efeecef3575 in xdebug_var_export_text_ansi (struc=struc@entry=0x7fff826d8b58, str=str@entry=0x55dcd58eade0, mode=mode@entry=0, level=level@entry=1, debug_zval=debug_zval@entry=0, options=options@entry=0x55dcd58ea230) at /tmp/pear/temp/xdebug/src/lib/var_export_text.c:250
        myht = 0x0
        tmp_str = <optimized out>
        tmp_len = <optimized out>
        num = <optimized out>
        key = <optimized out>
        val = <optimized out>
        tmpz = 0x0
#2  0x00007efeecef444d in xdebug_var_export_text_ansi (options=0x55dcd58ea230, debug_zval=0, level=1, mode=0, str=0x55dcd58eade0, struc=0x7fff826d8b58) at /tmp/pear/temp/xdebug/src/lib/var_export_text.c:323
        myht = <optimized out>
        tmp_str = <optimized out>
        tmp_len = <optimized out>
        key = <optimized out>
        val = <optimized out>
        num = <optimized out>
        tmpz = <optimized out>
        myht = <optimized out>
        tmp_str = <optimized out>
        tmp_len = <optimized out>
        num = <optimized out>
        key = <optimized out>
        val = <optimized out>
        tmpz = <optimized out>
        pattern = <optimized out>
        pattern_len = <optimized out>
        i_string = <optimized out>
        tmp_zstr = <optimized out>
        __ht = <optimized out>
        _p = <optimized out>
        _end = <optimized out>
        _z = <optimized out>
        __ht = <optimized out>
        _p = <optimized out>
        _end = <optimized out>
        _z = <optimized out>
        type_name = <optimized out>
#3  xdebug_get_zval_value_text_ansi (val=<optimized out>, val@entry=0x7efeecc61050, mode=0, debug_zval=0, options=0x55dcd58ea230) at /tmp/pear/temp/xdebug/src/lib/var_export_text.c:323
        str = 0x55dcd58eade0
        default_options = 1
#4  0x00007efeecee6375 in zif_xdebug_var_dump (execute_data=<optimized out>, return_value=<optimized out>) at /tmp/pear/temp/xdebug/xdebug.c:811
        args = 0x7efeecc61050
        argc = <optimized out>
        i = <optimized out>
        val = <optimized out>
#5  0x00007efeecee747d in xdebug_execute_internal (current_execute_data=0x7efeecc120a0, return_value=0x7fff826d8c28) at /tmp/pear/temp/xdebug/src/base/base.c:466
        edata = <optimized out>
        fse = 0x55dcd5790470
        function_nr = 2
        function_call_traced = 0
        restore_error_handler_situation = 0
        tmp_error_cb = 0x0
#6  0x000055dcd31a8aa4 in ?? ()
No symbol table info available.
#7  0x000055dcd34f7bfd in execute_ex ()
No symbol table info available.
#8  0x00007efeecee6b26 in xdebug_execute_ex (execute_data=0x7efeecc12020) at /tmp/pear/temp/xdebug/src/base/base.c:380
        op_array = 0x7efeecc7c2a0
        edata = <optimized out>
        fse = 0x55dcd57a9ea0
        xfse = <optimized out>
        function_nr = 0
        le = <optimized out>
        code_coverage_function_name = 0x0
        code_coverage_file_name = 0x0
        code_coverage_init = 0
#9  0x000055dcd34feda3 in zend_execute ()
No symbol table info available.
#10 0x000055dcd346b9cc in zend_eval_stringl ()
No symbol table info available.
#11 0x000055dcd346bb69 in zend_eval_stringl_ex ()
No symbol table info available.
#12 0x000055dcd3500a65 in ?? ()
No symbol table info available.
#13 0x000055dcd31b667b in ?? ()
No symbol table info available.
#14 0x00007efeefd4609b in __libc_start_main (main=0x55dcd31b6230, argc=3, argv=0x7fff826da4c8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fff826da4b8) at ../csu/libc-start.c:308
        self = <optimized out>
        result = <optimized out>
        unwind_buf = {cancel_jmp_buf = {{jmp_buf = {0, -5124611990319189412, 94406922956176, 140735381611712, 0, 0, -1394115934335978916, -1250380556739857828}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x7fff826da4e8, 0x7efef0b16190}, data = {prev = 0x0, cleanup = 0x0, canceltype = -2106743576}}}
        not_first_call = <optimized out>
#15 0x000055dcd31b6dba in _start ()
No symbol table info available.
backtrace.txt (4,331 bytes)   

derick

2020-05-28 09:17

administrator   ~0005417

Hi Dustin,

thanks for the report. It was quite easy to reproduce, even without Docker. However, the fix (https://github.com/xdebug/xdebug/commit/009c26f723ab7680084b90401de17aaeee35c386) wasn't as easy as just adding the test for null on the line that you indicated. In the end, it needed to be done in different places making sure that it wouldn't also ignore the whole class.

The fix for this report has just been merged into xdebug_2_9 for the 2.9.6 release, as well as into master.

thanks!

cheers,
Derick

dustinmailc

2020-05-28 14:38

reporter   ~0005421

Thanks so much! I (and my coworkers) really appreciate it.

Issue History

Date Modified Username Field Change
2020-05-26 15:03 dustinmailc New Issue
2020-05-26 15:03 dustinmailc Tag Attached: SIGSEGV
2020-05-26 15:07 dustinmailc File Added: backtrace.txt
2020-05-26 15:07 dustinmailc Note Added: 0005416
2020-05-28 09:17 derick Assigned To => derick
2020-05-28 09:17 derick Status new => closed
2020-05-28 09:17 derick Resolution open => fixed
2020-05-28 09:17 derick Fixed in Version => 2.9.6
2020-05-28 09:17 derick Note Added: 0005417
2020-05-28 14:38 dustinmailc Note Added: 0005421