Hi all,

I'm having some issues with some custom embedding of the PHP sapi. I'm
trying to call PHP from Ruby and I'd like to be able to pass data back
and forth freely, but I'm running into segfaults. It works well enough
for small values, but for some large values, it crashes on me.
Currently my most immediate issue is when I'm passing a large string
to call_user_function, which itself is calling token_get_all. The file
I'm parsing is pretty big, so the hash table returned is also pretty
big (~500 records). But each time I loop through it, it segfaults half
way through, even if I don't touch the records at all. I ran gdb on it
and it tells me one of the internal hash pointers is invalid, which
I'm not sure how this could have happened, since I'm only iterating
through it. I've included a version of the function doing this below
[2], and a sample of the gdb session I used as well [3]. If you'd like
to see the original, plus the context of this operation, you can check
it out here [1].

I have a hunch the problem lies in the way I'm allocating (or not
allocating) the PHP variables involved. I did follow some of the
guidelines in the book "Extending and Embedding PHP", but found that
my code worked without all of the conventions, so instead I just
omitted it when it didn't seem necessary.. And now I'm here :) If it
is down to my bad memory handling habits, it would really be helpful
if someone could point out, on what particular line, I'm doing things
wrong. Then I could probably figure it out from there.

Thanks,
- Farley

[1] 
http://github.com/farleyknight/ionize/blob/f1ee49f2c0f8a331bd77d59243bf8392615c7eca/etc/php_eval_string/php_eval_string.c

[2] Code sample:

VALUE zval2rb_hsh_(zval zhash) {
  VALUE rbhash = rb_hash_new();

  char *string_key;
  ulong num_key;

  zval key, **value;
  VALUE rbkey, rbvalue;

  zend_hash_internal_pointer_reset(Z_ARRVAL(zhash));

  printf("This hash table has %d entries\n",
zend_hash_num_elements(Z_ARRVAL(zhash)));

  int current = 0;

  while (zend_hash_get_current_data(Z_ARRVAL(zhash), (void**)&value)
== SUCCESS) {
    current++;
    printf("Currently on entry %d\n", current);
    if (zend_hash_move_forward(Z_ARRVAL(zhash)) == SUCCESS)
      printf("Done moving hash forward. Result was successful\n");
    else
      printf("Done moving hash forward. Result was a failure\n");
  }

  return rbhash;
}

[3] gdb session:

 gdb ruby
GNU gdb 6.8-debian
Copyright (C) 2008 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 "i486-linux-gnu"...
(gdb) run test.rb
Starting program: /usr/local/bin/ruby test.rb
[Thread debugging using libthread_db enabled]
Error while reading shared library symbols:
Cannot find new threads: generic error
Cannot find new threads: generic error
(gdb) continue
Continuing.
calling phpversion
5.2.9
calling token get all, medium input
This hash table has 429 entries
Currently on entry 1
Done moving hash forward. Result was successful
Currently on entry 2
....
....
Done moving hash forward. Result was successful
Currently on entry 291
Done moving hash forward. Result was successful
[New Thread 0xb7d846b0 (LWP 13069)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb7d846b0 (LWP 13069)]
zend_hash_get_current_data_ex (ht=0x817fc48, pData=0xbfa3acb8,
pos=0x0) at /home/robinhoode/Desktop/php-5.2.9/Zend/zend_hash.c:1163
1163      *pData = p->pData;
(gdb) quit
The program is running.  Exit anyway? (y or n) y

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to