Hi,

I was testing myphp and it didn't work for me, because argv was initialized at
an inaccessible address.

Since I'm not farmiliar with C++, I made some changes using C, basically to
allocate a block for argv, and realloc when needed (see attached patch).
I know I still need to check reallocation in the other types, but that's not the
issue.
I also made some changes to the Makefile, in order to use mysql_config, so that's
why I changed "mysql/mysql.h" to "mysql.h". Please excuse the hard paths there.

The following works once:
$ mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1 to server version: 4.0.4-beta-log

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> SELECT php('strftime("%c", $argv[1])', UNIX_TIMESTAMP(NOW()));
+--------------------------------------------------------+
| php('strftime("%c", $argv[1])', UNIX_TIMESTAMP(NOW())) |
+--------------------------------------------------------+
| 11/09/02 21:22:57 |
+--------------------------------------------------------+
1 row in set (0.02 sec)

mysql> SELECT php('strftime("%c", $argv[1])', UNIX_TIMESTAMP(NOW()));

gdb output is attached and basically shows an error in the thread safety, which
I know very little about.

I'd appreciate any pointers in this area.


With kind regards,

Melvyn Sopacua
<?php include("not_reflecting_employers_views.txt"); ?>
0x8325011 in _syscall_sys_select ()
(gdb) cont
Continuing.
[Switching to thread 0xad4e900]

Program received signal SIGSEGV, Segmentation fault.
0x487061f5 in ts_resource_ex (id=5, th_id=0x0) at /home/mdev/cvs/php4/TSRM/TSRM.c:316
316                             TSRM_SAFE_RETURN_RSRC(thread_resources->storage, id, 
thread_resources->count);
(gdb) bt
#0  0x487061f5 in ts_resource_ex (id=5, th_id=0x0) at 
/home/mdev/cvs/php4/TSRM/TSRM.c:316
#1  0x487740c1 in php_embed_init (argc=2, argv=0xb02d000, ptsrm_ls=0x4881a4a0)
    at /home/mdev/cvs/php4/sapi/embed/php_embed.c:170
#2  0x485dec80 in php (initid=0xb03121c, args=0xb031208, result=0x4881a57c "\001", 
length=0x4881a504, 
    is_null=0x0, error=0x0) at myphp.cc:121
#3  0x805fd2c in udf_handler::val_str ()
#4  0x8065db7 in Item_func_udf_str::val_str ()
#5  0x80576f7 in Item::send ()
#6  0x8085a61 in select_send::send_data ()
#7  0x80b29f4 in mysql_select ()
#8  0x80c0ac6 in handle_select ()
#9  0x80995fc in mysql_execute_command ()
#10 0x809d1b8 in mysql_parse ()
#11 0x8098613 in dispatch_command ()
#12 0x809e612 in do_command ()
#13 0x8097845 in handle_one_connection ()
#14 0x82ebc7f in _thread_kern_start ()
(gdb) frame 2
#2  0x485dec80 in php (initid=0xb03121c, args=0xb031208, result=0x4881a57c "\001", 
length=0x4881a504, 
    is_null=0x0, error=0x0) at myphp.cc:121
121         PHP_EMBED_START_BLOCK(args->arg_count, argv);
Current language:  auto; currently c++
(gdb) info local
tsrm_ls = (void ***) 0x805fc68
rv = (rv_str *) 0x843a310
zv = (zval *) 0x843a340
argv = (char **) 0xb02d000
argv_size = 2048
argv_alloc = 24
i = 2
(gdb) print args->arg_count
$1 = 2
(gdb) print argv[1]
$2 = 0x843a330 "1036873384"
(gdb) frame 1
#1  0x487740c1 in php_embed_init (argc=2, argv=0xb02d000, ptsrm_ls=0x4881a4a0)
    at /home/mdev/cvs/php4/sapi/embed/php_embed.c:170
170       compiler_globals = ts_resource(compiler_globals_id);
Current language:  auto; currently c
(gdb) info local
global_vars = {head = 0x8300000, tail = 0x0, size = 0, count = 1216455788, 
  dtor = 0x8075917 <Item_func_now::val_str(String *)+27>, persistent = 200 'È', 
traverse_ptr = 0xb0311fc}
compiler_globals = (zend_compiler_globals *) 0x4881a448
executor_globals = (zend_executor_globals *) 0x13
core_globals = (php_core_globals *) 0xc
sapi_globals = (sapi_globals_struct *) 0x82e194c
tsrm_ls = (void ***) 0x4881a44c
(gdb) frame 0
#0  0x487061f5 in ts_resource_ex (id=5, th_id=0x0) at 
/home/mdev/cvs/php4/TSRM/TSRM.c:316
316                             TSRM_SAFE_RETURN_RSRC(thread_resources->storage, id, 
thread_resources->count);
(gdb) info local
thread_id = 0x2
hash_value = 0
thread_resources = (tsrm_tls_entry *) 0x843a370
(gdb) print id
$3 = 5
(gdb) print thread_resources->storage
$4 = (void **) 0x1
(gdb) print thread_resources->count
$5 = 0
--- orig/myphp.cc       Fri Oct 25 17:05:54 2002
+++ ./myphp.cc  Sat Nov  9 21:19:34 2002
@@ -1,15 +1,18 @@
 /* Copyright (c) 2002 David Sklar 
  *
  * Inspiration from myperl by Brian Aker - http://software.tangent.org/
+ * vim600: noet ts=4 sw=4
  */
 
 #include <stdio.h>
 #include <stdarg.h>
 #include <string.h>
 #include <stdlib.h>
-#include <mysql/mysql.h>
+#include <mysql.h>
 #include "php_embed.h"
 
+#define ARGV_BLOCKSIZE 1024
+
 extern "C" {
     my_bool php_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
     void php_deinit(UDF_INIT *initid);
@@ -22,6 +25,7 @@
     int size;
 } rv_str;
 
+
 my_bool php_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
     rv_str *rv = NULL;
 
@@ -61,6 +65,8 @@
     rv_str *rv = (rv_str *) initid->ptr;
     zval *zv = NULL;
     char **argv;
+       size_t argv_size=0;
+       size_t argv_alloc=0;
     unsigned int i;
 
     is_null = NULL;
@@ -83,19 +89,28 @@
      * and then just process here the ones that change on a row-by-row basis
      */
 
+       argv_size = (size_t)args->arg_count * ARGV_BLOCKSIZE;
+       argv = (char **)malloc(argv_size+1);
+
     for (i = 0; i < args->arg_count; i++) {
         switch (args->arg_type[i]) {
         case STRING_RESULT:
-            argv[i] = new char[args->lengths[i] + 1];
-            strncpy(argv[i], args->args[i],args->lengths[i]);
+                       if (argv_alloc + args->lengths[i] > argv_size)
+                       {
+                               argv_size = argv_alloc + args->lengths[i] +1;
+                               argv = (char **)realloc(argv, argv_size);
+                       }
+                       argv_alloc += args->lengths[i];
+                       argv[i] = (char *) malloc(args->lengths[i] +1);
+            memcpy(argv[i], args->args[i],args->lengths[i]);
             argv[i][args->lengths[i]] = 0;
             break;
         case INT_RESULT:
-            argv[i] = new char[32]; 
+            argv[i] = (char *) malloc(sizeof(long long));
             sprintf(argv[i],"%lld",*(long long *) args->args[i]);
             break;
         case REAL_RESULT:
-            argv[i] = new char[32]; 
+            argv[i] = (char *) malloc(sizeof(double));
             sprintf(argv[i],"%f",*(double *)args->args[i]);
             break;
         }
@@ -111,9 +126,9 @@
      * were processed in php_init(), then just the non-constant ones would
      * be freed here; the constant ones would be freed in php_deinit()
      */
-    for (i = 0; i < args->arg_count; i++) {
-        delete argv[i];
-    }
+
+       if(argv)
+               free(argv);
 
     /* Set up the return value based on the type of the zval */
     switch(zv->type) {
--- orig/Makefile       Fri Oct 25 17:05:54 2002
+++ ./Makefile  Sat Nov  9 11:46:45 2002
@@ -1,8 +1,23 @@
-LIBS=-lphp4 -lstdc++ $(shell php-config --libs)
-INCLUDES=$(shell php-config --includes) 
-LIBDIRS=-L$(shell php-config --prefix)/lib
+PHP_LIBS=-lphp4 -lstdc++ $(shell /weblib/local/bin/php-config --libs)
+PHP_INCLUDES=$(shell /weblib/local/bin/php-config --includes) 
+PHP_LIBDIRS=-L$(shell /weblib/local/bin/php-config --prefix)/lib
+PHP_EXTRA_LIBS=-L/weblib/local/lib -L/home/mdev/local/lib -L/sql/lib/mysql
+MYSQL_FLAGS=$(shell mysql_config --cflags)
 CC=gcc
-CFLAGS=-g -Wall -shared -I/usr/local/mysql/include     
+CFLAGS=-g -Wall -shared 
+INSTALL=/usr/bin/install -C -D -D
 
-myphp: myphp.cc
+INCLUDES=$(PHP_INCLUDES) $(MYSQL_FLAGS)
+LIBDIRS=$(PHP_LIBDIRS)
+LIBS=$(PHP_LIBS) $(PHP_EXTRA_LIBS)
+
+all: myphp.so
+
+myphp.so: myphp.cc
        $(CC) $(CFLAGS) $(INCLUDES) $(LIBDIRS) myphp.cc $(LIBS) -o myphp.so
+
+clean:
+       rm -f myphp.so
+
+install: myphp.so
+       $(INSTALL) -o mysql -g mysql myphp.so /chroot/usr/lib
-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to