I'm developing my own PHP extension with a class in it. I recently upgraded from Ubuntu 9.04 to 9.10 and the extension broke. I since tried to update to 10.04 to see if it fixes it as my dev environment is 10.04 and it works fine on there. The only major difference from what I can understand is the server is 64 bit and my laptop 32 bit architecture. I have PHP version 5.3.2-1ubuntu4.5 (Zend build 20090626).

I have tried running my test PHP file:

<?php
$server =  "http://localhost/";
$port = 1214;
$f = new PPKeyClient($server, $port);
var_dump($f);

In GDB:

root@node:/etc/php5/conf.d# gdb php
GNU gdb (GDB) 7.1-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
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-linux-gnu".
For bug reporting instructions, please see:
...
Reading symbols from /usr/bin/php...Reading symbols from /usr/lib/debug/usr/bin/php5...done.
done.
(gdb) run -f /var/www/test.php 
Starting program: /usr/bin/php -f /var/www/test.php
[Thread debugging using libthread_db enabled]
[New Thread 0x7fffef15b710 (LWP 9228)]
[Thread 0x7fffef15b710 (LWP 9228) exited]
1
Program received signal SIGSEGV, Segmentation fault.
0x00000000006e7767 in zend_do_fcall_common_helper_SPEC (execute_data=0x7fff00000000)
    at /build/buildd/php5-5.3.2/Zend/zend_vm_execute.h:371
371 /build/buildd/php5-5.3.2/Zend/zend_vm_execute.h: No such file or directory.
 in /build/buildd/php5-5.3.2/Zend/zend_vm_execute.h
(gdb) bt
#0  0x00000000006e7767 in zend_do_fcall_common_helper_SPEC (execute_data=0x7fff00000000)
    at /build/buildd/php5-5.3.2/Zend/zend_vm_execute.h:371
#1  0x00000000006bec20 in execute (op_array=0xfef1b0) at /build/buildd/php5-5.3.2/Zend/zend_vm_execute.h:104
#2  0x000000000069694d in zend_execute_scripts (type=0, retval=0x7fffffffbf90, file_count=3)
    at /build/buildd/php5-5.3.2/Zend/zend.c:1266
#3  0x0000000000642598 in php_execute_script (primary_file=0x2) at /build/buildd/php5-5.3.2/main/main.c:2288
#4  0x0000000000727a56 in main (argc=0, argv=0x1) at /build/buildd/php5-5.3.2/sapi/cli/php_cli.c:1196
(gdb) 

And the relevant bits from the extension:

PHP_MINIT_FUNCTION(pp)
{
        // Register PPKeyClient class
        zend_class_entry ce;
        INIT_CLASS_ENTRY(ce, "PPKeyClient", pp_functions);
        PPKeyClient_ce = zend_register_internal_class(&ce TSRMLS_CC);
        PPKeyClient_ce->create_object = PPKeyClient_object_new;
        memcpy(&PPKeyClient_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
        PPKeyClient_handlers.clone_obj = NULL;
        return SUCCESS;
}

zend_object_value PPKeyClient_object_new(zend_class_entry *ce TSRMLS_DC)
{
        zend_object_value retval;
        PPKeyClient_object *intern;

        // TODO - only instantiate look at
        // http://stackoverflow.com/questions/1906565/php-extension-library-accessing-php-superglobals
        // or google for http://www.google.co.uk/search?hl=en&safe=off&q=superglobals+in+php+extensions&aq=f&aqi=&aql=&oq=&gs_rfai=

        intern = ecalloc(1, sizeof(PPKeyClient_object));
        zend_object_std_init(&(intern->std), ce TSRMLS_CC);
        zend_hash_copy(intern->std.properties, &ce->default_properties, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));

        intern->last_curl_result = PPKC_NO_REQUEST;

        retval.handle = zend_objects_store_put(intern, PPKeyClient_object_dtor, NULL, NULL TSRMLS_CC);
        retval.handlers = &PPKeyClient_handlers;
        return retval;
}

PHP_METHOD(PPKeyClient, __construct)
{
        PPKeyClient_object *intern;
        char *url, *ssl_ca_crt = NULL;
        int port = 80, url_len, ssl_ca_crt_len = 0, ua_len = 0;

        if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ls", &url, &url_len, &port, &ssl_ca_crt, &ssl_ca_crt_len) == SUCCES$
        {
                intern = (PPKeyClient_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
//              intern->port = port;

//              intern->baseurl = estrndup(url, url_len);
//              intern->baseurl_len = url_len;
//              intern->ssl_ca_crt = estrndup(ssl_ca_crt, ssl_ca_crt_len);
//              intern->ssl_ca_crt_len = ssl_ca_crt_len;
//              intern->useragent = "PP KeyClient (PPExt#" PHP_PRIVATE_PASSWORDS_EXTNAME " v" PHP_PRIVATE_PASSWORDS_VERSION ")";
        }
}

I know that commenting the intern = (PPKeyClient_object*)zend_object_store_get_object... line makes it work, but obviously I can't set the values from the constructor without that.

I'm so lost and would appreciate any help finding what's up!

Comments

Pointers are 4 bytes long on a 32 bit system and 8 on a 64 bit system.

Written by SlappyTheFish

Accepted Answer

I can't remember exactly how I fixed this - I think @SlappyTheFish was right - something to do with 64 bitness. I later re-installed the server to be 32-bit and I believe that fixed it, so essentially the problem wasn't solved but I worked around it.

Written by Asgrim
This page was build to provide you fast access to the question and the direct accepted answer.
The content is written by members of the stackoverflow.com community.
It is licensed under cc-wiki