You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@thrift.apache.org by "Tyler Hobbs (JIRA)" <ji...@apache.org> on 2013/04/19 22:45:16 UTC

[jira] [Comment Edited] (THRIFT-1908) Using php thrift_protocol accelerated transfer causes core dump

    [ https://issues.apache.org/jira/browse/THRIFT-1908?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13636863#comment-13636863 ] 

Tyler Hobbs edited comment on THRIFT-1908 at 4/19/13 8:45 PM:
--------------------------------------------------------------

I've been digging into this, and THRIFT-1453 is definitely the cause. With the changes in THRIFT-1453, I can consistently reproduce, and with the changes reversed, there are no problems. (I'm also working with the fix for THRIFT-1903 applied so that the extension will be used.)
                
      was (Author: thobbs):
    I've been digging into this, and THRIFT-1453 is definitely the cause. With the changes in THRIFT-1543, I can consistently reproduce, and with the changes reversed, there are no problems. (I'm also working with the fix for THRIFT-1903 applied so that the extension will be used.)
                  
> Using php thrift_protocol accelerated transfer causes core dump
> ---------------------------------------------------------------
>
>                 Key: THRIFT-1908
>                 URL: https://issues.apache.org/jira/browse/THRIFT-1908
>             Project: Thrift
>          Issue Type: Bug
>          Components: PHP - Library
>    Affects Versions: 0.9
>         Environment: CentOS 6.4 64 bit
>            Reporter: Tim Behrendsen
>            Priority: Critical
>              Labels: accelerated, core, dump, php, thrift_protocol
>
> Unfortunately, this is a bit of a Heisenbug among a complex code base and I
> wasn't able to make a small reproducible example that actually crashes.
> However, I might have been able to make a small example that shows possible
> memory corruption that leads to the crash.
> The crash happens as my script terminates, so it does appear to be memory
> corruption. Here is the gdb stack trace:
> {noformat}
> (gdb) bt
> #0  0x00007f6e7dad4ad9 in gc_zval_possible_root ()
>    from /etc/httpd/modules/libphp5.so
> #1  0x00007f6e7dac36db in zend_hash_destroy ()
>    from /etc/httpd/modules/libphp5.so
> #2  0x00007f6e7dab6a6f in _zval_dtor_func () from
> /etc/httpd/modules/libphp5.so
> #3  0x00007f6e7daab0da in _zval_ptr_dtor () from /etc/httpd/modules/libphp5.so
> #4  0x00007f6e7dac36db in zend_hash_destroy ()
>    from /etc/httpd/modules/libphp5.so
> #5  0x00007f6e7dad60c9 in zend_object_std_dtor ()
>    from /etc/httpd/modules/libphp5.so
> #6  0x00007f6e7dad60e9 in zend_objects_free_object_storage ()
>    from /etc/httpd/modules/libphp5.so
> #7  0x00007f6e7dad95bc in zend_objects_store_free_object_storage ()
>    from /etc/httpd/modules/libphp5.so
> #8  0x00007f6e7daab4e4 in ?? () from /etc/httpd/modules/libphp5.so
> #9  0x00007f6e7dab7792 in ?? () from /etc/httpd/modules/libphp5.so
> #10 0x00007f6e7da658e5 in php_request_shutdown ()
>    from /etc/httpd/modules/libphp5.so
> #11 0x00007f6e7db3fbd7 in ?? () from /etc/httpd/modules/libphp5.so
> #12 0x00007f6e88f9abb0 in ap_run_handler ()
> #13 0x00007f6e88f9e46e in ap_invoke_handler ()
> #14 0x00007f6e88fa9b30 in ap_process_request ()
> #15 0x00007f6e88fa69a8 in ?? ()
> #16 0x00007f6e88fa26b8 in ap_run_process_connection ()
> #17 0x00007f6e88fae977 in ?? ()
> #18 0x00007f6e88faec8a in ?? ()
> #19 0x00007f6e88faefbb in ap_mpm_run ()
> #20 0x00007f6e88f86900 in main ()
> {noformat}
> One thing I noticed in tracking this down was that a php data structure
> that I sent to the thrift call came back modified, which I don't think is
> normal behavior. This is the behavior I was able to reproduce. This example
> is loosely based on the tutorial.
> Thrift File (smallbug.thrift):
> {noformat}
> namespace php tutorial
> struct Date_Range {
>     1: string low_date,
>     2: string high_date
> }
> service Calculator {
>    Date_Range List_Range( 1:string session_id,
>         2:map<string,string> options),
> }
> {noformat}
> Client File client.php:
> {noformat}
> #!/usr/bin/env php
> <?php
> error_reporting(E_ALL);
> define('THRIFT_ROOT', '/home/tim/projects/inquisic/thrift-0.9.0/lib/php/lib');
> require_once(THRIFT_ROOT . '/Thrift/ClassLoader/ThriftClassLoader.php');
> use Thrift\ClassLoader\ThriftClassLoader;
> $GEN_DIR = '/home/tim/public_html/smallbug/gen-php';
> $loader = new ThriftClassLoader();
> $loader->registerNamespace('Thrift', THRIFT_ROOT);
> $loader->registerDefinition('shared', $GEN_DIR);
> $loader->registerDefinition('tutorial', $GEN_DIR);
> $loader->register();
> use Thrift\Protocol\TBinaryProtocol;
> use Thrift\Protocol\TBinaryProtocolAccelerated;
> use Thrift\Transport\TSocket;
> use Thrift\Transport\THttpClient;
> use Thrift\Transport\TBufferedTransport;
> use Thrift\Exception\TException;
> try {
>   $socket = new THttpClient('localhost', 8383, '/~tim/smallbug/server.php');
>   $transport = new TBufferedTransport($socket, 1024, 1024);
>   $protocol = new TBinaryProtocolAccelerated($transport);
>   $client = new \tutorial\CalculatorClient($protocol);
>   $transport->open();
>   $options = array(
>             'type' => 'C',
>             'all' => 1,
>             'client' => 1 );
> print "before: options = " . print_r($options, true);
>   $client->List_Range('session_id', $options);
> print "afterward: options = " . print_r($options, true);
>   $transport->close();
> } catch (TException $tx) {
>   print 'TException: '.$tx->getMessage()."\n";
> }
> ?>
> {noformat}
> Server File server.php:
> {noformat}
> <?php
> namespace tutorial\php;
> error_reporting(E_ALL);
> define('THRIFT_ROOT', '/home/tim/projects/inquisic/thrift-0.9.0/lib/php/lib');
> require_once(THRIFT_ROOT . '/Thrift/ClassLoader/ThriftClassLoader.php');
> use Thrift\ClassLoader\ThriftClassLoader;
> $GEN_DIR = '/home/tim/public_html/smallbug/gen-php';
> $loader = new ThriftClassLoader();
> $loader->registerNamespace('Thrift', THRIFT_ROOT);
> $loader->registerDefinition('tutorial', $GEN_DIR);
> $loader->register();
> if (php_sapi_name() == 'cli') {
>   ini_set("display_errors", "stderr");
> }
> use Thrift\Protocol\TBinaryProtocol;
> use Thrift\Protocol\TBinaryProtocolAccelerated;
> use Thrift\Transport\TPhpStream;
> use Thrift\Transport\TBufferedTransport;
> class CalculatorHandler implements \tutorial\CalculatorIf {
>   public function List_Range($session_id, $options) {
>     error_log("List_Range()");
>     $ret = new \tutorial\Date_Range;
>     return $ret;
>   }
> };
> header('Content-Type', 'application/x-thrift');
> if (php_sapi_name() == 'cli') {
>   echo "\r\n";
> }
> $handler = new CalculatorHandler();
> $processor = new \tutorial\CalculatorProcessor($handler);
> $transport = new TBufferedTransport(new TPhpStream(TPhpStream::MODE_R | TPhpStream::MODE_W));
> $protocol = new TBinaryProtocolAccelerated($transport, true, true);
> error_log("protocol = " . get_class($protocol));
> $transport->open();
> $processor->process($protocol, $protocol);
> $transport->close();
> {noformat}
> Output after running the test program:
> {noformat}
> before: options = Array
> (
>     [type] => C
>     [all] => 1
>     [client] => 1
> )
> afterward: options = Array
> (
>     [type] => C
>     [all] =>
>     [client] =>
> )
> {noformat}
> As you can see, the $options array was corrupted on return. This does not
> happen when using the non-accelerated class.
> WARNING! If you run this example, please make sure the accelerated protocol
> is really being used! Take a look at my other bug report; the normal PHP
> Thrift library has a bug where the accelerated thrift_protocol module will
> not be used. It's bug THRIFT-1903.
> Thanks for your help.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira