View Issue Details

IDProjectCategoryView StatusLast Update
0000725Xdebugpublic2011-11-11 23:48
Reporterr.osmanov Assigned Toderick  
PriorityhighSeveritytweakReproducibilityN/A
Status closedResolutionfixed 
PlatformAllOSopenSUSEOS Version11.4
Product Version2.1.0 
Summary0000725: EG(current_execute_data) is not checked in xdebug.c, xdebug_statement_call
Description

I've PECL extension that calls a user space function with call_user_function(). The latter is normally called via zend_execute(). But zend_execute is replaced with xdebug_execute, which implies EG(current_execute_data) is set. But, call_user_function() is invoked asyncronously(!) by means of external library, and current_execute_data couldn't generally be updated in an async call. Consequently, extension fails with segmentation fault.

Standard zend_execute() checks, if EG(current_execute_data) is available, and doesn't crash with segfault:

Simple
Raw
Download

 /* Initialize execute_data */
    if (EG(current_execute_data)) {
        execute_data = *EG(current_execute_data);
        EX(op_array) = NULL;
        EX(opline) = NULL;
        EX(object) = NULL;
    } else {
        /* This only happens when we're called outside any execute()'s
         * It shouldn't be strictly necessary to NULL execute_data out,
         * but it may make bugs easier to spot
         */
        memset(&execute_data, 0, sizeof(zend_execute_data));
    }

While xdebug_execute() .. xdebug_statement_call() lacks this check:
ZEND_DLEXPORT void xdebug_statement_call(zend_op_array op_array)
{
xdebug_llist_element
le;
xdebug_brk_info brk;
function_stack_entry
fse;
int lineno;
char *file;
int file_len = 0;
int level = 0;
TSRMLS_FETCH();

lineno = EG(current_execute_data)->opline->lineno;

/ HERE I'VE GOT SEGMENTATION FAULT /
...

Steps To Reproduce

compile an extension with function like
my_internal_func(data)
{
// Fetch tsrm_ls from data
// ...
call_user_function(...);
}
PHP_FUNCTION(my_func)
{
// ...
async_call(my_internal_func, data);
}

Additional Information

The following change should fix the problem:
--- xdebug.c 2011-07-28 16:13:03.000000000 +0500
+++ xdebug2.c 2011-10-02 19:35:28.964404001 +0500
@@ -1693,7 +1693,11 @@
int level = 0;
TSRMLS_FETCH();

  • lineno = EG(current_execute_data)->opline->lineno;
  • zend_execute_data *ceg = EG(current_execute_data);
  • if (!ceg) {
  • return;
  • }
  • lineno = ceg->opline->lineno;

    file = op_array->filename;
    file_len = strlen(file);

=====================================

I'm quoting gdb's output:
$ gdb php
GNU gdb (GDB) SUSE (7.2-3.3)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-suse-linux".
For bug reporting instructions, please see:
http://www.gnu.org/software/gdb/bugs/...
Reading symbols from /usr/local/bin/php...(no debugging symbols found)...done.
(gdb) r eio.php
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff7fe6700 (LWP 11958)]
0x00007ffff3ab5299 in xdebug_statement_call (op_array=0x12e4cb0) at /opt/src/xdebug-2.1.2/xdebug.c:1702
1702 lineno = ceg->opline->lineno;
(gdb) where
#0 0x00007ffff3ab5299 in xdebug_statement_call (op_array=0x12e4cb0) at /opt/src/xdebug-2.1.2/xdebug.c:1702
#1 0x0000000000955f52 in ?? ()
0000002 0x000000000090a151 in zend_llist_apply_with_argument ()
0000003 0x000000000095aaae in ?? ()
0000004 0x000000000095b664 in ?? ()
0000005 0x0000000000958654 in execute ()
0000006 0x00007ffff3ab36a0 in xdebug_execute (op_array=0x12e4cb0, tsrm_ls=0xfe1900) at /opt/src/xdebug-2.1.2/xdebug.c:1274
0000007 0x0000000000906126 in zend_call_function ()
0000008 0x0000000000904dac in call_user_function_ex ()
0000009 0x0000000000904bfc in call_user_function ()
0000010 0x00007ffff3897f87 in php_eio_custom_execute (req=0x13de490) at /home/ruslan/projects/c/zend/libeio/eio.c:696
0000011 0x00007ffff368e455 in ?? () from /usr/local/lib/libeio.so.1
0000012 0x00007ffff50c7a3f in start_thread (arg=0x7ffff7fe6700) at pthread_create.c:297
0000013 0x00007ffff4e2766d in clone () from /lib64/libc.so.6
0000014 0x0000000000000000 in ?? ()
(gdb)

Tagsgdb, pecl, SIGSEGV
Operating SystemopenSUSE 11.4
PHP Version5.3.6

Activities

derick

2011-10-22 14:06

administrator   ~0001849

Fixed in GIT (locally). Will push when I get a better internet connection again.

derick

2011-11-11 23:48

administrator   ~0001855

It's on github now.

Issue History

Date Modified Username Field Change
2011-10-02 17:51 r.osmanov New Issue
2011-10-02 17:52 r.osmanov Tag Attached: gdb
2011-10-02 17:52 r.osmanov Tag Attached: pecl
2011-10-02 17:52 r.osmanov Tag Attached: SIGSEGV
2011-10-22 14:06 derick Note Added: 0001849
2011-10-22 14:06 derick Status new => closed
2011-10-22 14:06 derick Assigned To => derick
2011-10-22 14:06 derick Resolution open => fixed
2011-11-11 23:48 derick Note Added: 0001855
2016-07-31 12:35 derick Category Debug client (console) => debugclient (debugging tool)
2016-07-31 12:35 derick Category debugclient (debugging tool) => (No Category)