You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@thrift.apache.org by "Tim Behrendsen (JIRA)" <ji...@apache.org> on 2014/03/15 06:02:42 UTC
[jira] [Commented] (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=13935993#comment-13935993 ]
Tim Behrendsen commented on THRIFT-1908:
----------------------------------------
Update: I just tried the accelerated protocol with thrift 0.9.1, still on Centos 6.4. I get the same symptom where Apache core dumps. The stack traceback looks pretty much the same as my original report.
When I try my small test program, it also still gives me the possibly corrupted $options array.
However! I just tried something different. I did a loop of the client call, and that caused a core dump:
{code}
for ($i = 0; $i < 20; ++$i) {
$client->List_Range('session_id', $options);
print "afterward: options = " . print_r($options, true);
}
{code}
This produced:
{noformat}
$ php client.php
before: options = Array
(
[type] => C
[all] => 1
[client] => 1
)
afterward: options = Array
(
[type] => C
[all] =>
[client] =>
)
afterward: options = Array
(
[type] => C
[all] => 11
[client] => 11
)
Segmentation fault (core dumped)
{noformat}
Tyler Hobbs posted on this issue about 11 months ago; did anything come of that?
If anyone has any workarounds (or a fix!), it would be greatly appreciated. The binary protocol is much faster, but I'm stuck using the php-native protocol. Or is there another way people do the binary protocol? I would think others must be running into this problem.
Thanks in advance for any help!
> 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 was sent by Atlassian JIRA
(v6.2#6252)