phpv8 / v8js

V8 Javascript Engine for PHP — This PHP extension embeds the Google V8 Javascript Engine
http://pecl.php.net/package/v8js
MIT License
1.83k stars 200 forks source link

std::out_of_range when trying to access PHP classes or functions #326

Closed danieleratti closed 7 years ago

danieleratti commented 7 years ago

I successfully installed v8js on php7, both on a server running the latest php7 non-thread-safe and on a php7.3 compiled with zts.

It works perfectly running Javascript which doesn't interact with PHP and also when I try access PHP variables using PHP.varname but, when I try to access a Class or a Function as read in the documentation I get:

`terminate called after throwing an instance of 'std::out_of_range' what(): map::at Received signal 6

==== C stack trace ===============================

[0x7f4fe9a95be4] [0x7f4ff08ac4b0] [0x7f4ff08ac428] [0x7f4ff08ae02a] [0x7f4ff3a6c84d] [0x7f4ff3a6a6b6] [0x7f4ff3a6a701] [0x7f4ff3a6a919] [0x7f4ff3a932cf] [0x7f4fe93ad91e] [0x7f4fe93ab9ed] [0x7f4fe93acfb1] [0x7f4fe939c9e1] [0x7f4fe9392542] [0x000000d01e31] [0x000000d380f8] [0x7f4fe95e0b3a] [0x000000d3a14f] [0x000000c38a80] [0x000000b6f552] [0x000000d3cff5] [0x000000d3e487] [0x7f4ff0897830] [0x000000446479] [end of stack trace] Aborted (core dumped)`

I used the following code (taken from this README) but also tried many other codes like initializing V8Js with $v8 = new V8Js('PHP', array('add' => 'add')); but I always get the error above.

<?php class Foo { var $bar = null; } $v8 = new V8Js(); $v8->foo = new Foo; // This prints "no" $v8->executeString('print( "bar" in PHP.foo ? "yes" : "no" );'); ?>

stesie commented 7 years ago

PHP 7.3!? You mean git master?

danieleratti commented 7 years ago

Yes, I tried both PHP 7.1 installed from apt and the very latest compiled directly from the git repo php-src but I get the same error.

stesie commented 7 years ago

Which V8 version are you on?

I supposed you're using a pretty new one, hence I picked 6.3.90.0, ... but I cannot reproduce the problem you describe.

Here my output with the example code you provided/referenced, Ubuntu Trusty with PHP 7.1.9 NTS from distro with self-compiled V8 6.3.90.0 with snapshots enabled and otherwise common

vagrant@vagrant-base-trusty-amd64:/data/build$ php --version
PHP 7.1.9-1+ubuntu14.04.1+deb.sury.org+1 (cli) (built: Sep  2 2017 06:17:11) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.1.9-1+ubuntu14.04.1+deb.sury.org+1, Copyright (c) 1999-2017, by Zend Technologies
vagrant@vagrant-base-trusty-amd64:/data/build$ php -a -d extension=modules/v8js.so
Interactive mode enabled

php > class Foo { var $bar = null; } 
php > $v8 = new V8Js();
php > $v8->foo = new Foo;
php > $v8->executeString('print( "bar" in PHP.foo ? "yes" : "no" );');
no
php > 

Please elaborate on your environment.

danieleratti commented 7 years ago

This is what I get on PHP 7.0.22 from apt

ubuntu@ip-172-30-0-88:~$ php --version
PHP 7.0.22-0ubuntu0.16.04.1 (cli) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.0.22-0ubuntu0.16.04.1, Copyright (c) 1999-2017, by Zend Technologies
ubuntu@ip-172-30-0-88:~$ php -a
Interactive mode enabled

php > class Foo { var $bar = null; }
php > $v8 = new V8Js();
php > $v8->foo = new Foo;
terminate called after throwing an instance of 'std::out_of_range'
  what():  map::at
Received signal 6

==== C stack trace ===============================

 [0x7f2f18578be4]
 [0x7f2f1ade94b0]
 [0x7f2f1ade9428]
 [0x7f2f1adeb02a]
 [0x7f2f1883784d]
 [0x7f2f188356b6]
 [0x7f2f18835701]
 [0x7f2f18835919]
 [0x7f2f1885e2cf]
 [0x7f2f17db8549]
 [0x7f2f17db235b]
 [0x7f2f17dae051]
 [0x008dcb018de4]
 [0x008dcaff723b]
 [0x008dcb04b867]
 [0x008dcafa80cf]
 [0x7f2f14db9557]
 [0x008dcb04d2f3]
 [0x008dcae387b4]
 [0x7f2f1add4830]
 [0x008dcae388f9]
[end of stack trace]
Aborted (core dumped)

And I get the same on PHP 7.3.0-dev:

ubuntu@ip-172-30-0-137:~$ php --version
PHP 7.3.0-dev (cli) (built: Sep 10 2017 09:26:39) ( ZTS DEBUG )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.3.0-dev, Copyright (c) 1998-2017 Zend Technologies
ubuntu@ip-172-30-0-137:~$ php -a
Interactive shell

php > class Foo { var $bar = null; }
php > $v8 = new V8Js();
php > $v8->foo = new Foo;
terminate called after throwing an instance of 'std::out_of_range'
  what():  map::at
Received signal 6

==== C stack trace ===============================

 [0x7f3b548ffbe4]
 [0x7f3b5b7164b0]
 [0x7f3b5b716428]
 [0x7f3b5b71802a]
 [0x7f3b5e8d684d]
 [0x7f3b5e8d46b6]
 [0x7f3b5e8d4701]
 [0x7f3b5e8d4919]
 [0x7f3b5e8fd2cf]
 [0x7f3b541ad91e]
 [0x7f3b541ab9ed]
 [0x7f3b541acfb1]
 [0x7f3b5419c9e1]
 [0x7f3b54192542]
 [0x000000d01e31]
 [0x000000d380f8]
 [0x7f3b543e0b3a]
 [0x000000d3a14f]
 [0x000000c1cb80]
 [0x0000008bc599]
 [0x000000d3cfdb]
 [0x000000d3e487]
 [0x7f3b5b701830]
 [0x000000446479]
[end of stack trace]
Aborted (core dumped)

In both cases I was running on Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-1032-aws x86_64) and V8JS 6.1 (with PHP 7.0.22) and 6.3 (with PHP 7.3-dev). If I don't use PHP classes or methods, v8js works fine!

stesie commented 7 years ago

Which version of v8 do you use? Self compiled or package from someone else?

danieleratti commented 7 years ago

The latest version: I've just redone everything from scratch by setting up a brand new Ubuntu 16.04 LTS machine from AWS, installing php7.0-dev from apt and executing step by step the "Compile V8 5.6 and newer (using GN)" and "Compile php-v8js itself" sections in the README.Linux.md of this repo.

I still get the exact same error:

ubuntu@ip-172-30-0-226:/etc/php/7.0/cli$ php --version
PHP 7.0.22-0ubuntu0.16.04.1 (cli) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.0.22-0ubuntu0.16.04.1, Copyright (c) 1999-2017, by Zend Technologies
ubuntu@ip-172-30-0-226:/etc/php/7.0/cli$ php -a
Interactive mode enabled

php > class Foo { var $bar = null; }
php > $v8 = new V8Js();
php > $v8->foo = new Foo;
terminate called after throwing an instance of 'std::out_of_range'
  what():  map::at
Received signal 6

==== C stack trace ===============================

 [0x7f1f90029be4]
 [0x7f1f9289a4b0]
 [0x7f1f9289a428]
 [0x7f1f9289c02a]
 [0x7f1f902e884d]
 [0x7f1f902e66b6]
 [0x7f1f902e6701]
 [0x7f1f902e6919]
 [0x7f1f9030f2cf]
 [0x7f1f8f9b8549]
 [0x7f1f8f9b235b]
 [0x7f1f8f9ae051]
 [0x00cf2ed5dde4]
 [0x00cf2ed3c23b]
 [0x00cf2ed90867]
 [0x00cf2eced0cf]
 [0x7f1f8c8ca557]
 [0x00cf2ed922f3]
 [0x00cf2eb7d7b4]
 [0x7f1f92885830]
 [0x00cf2eb7d8f9]
[end of stack trace]
Aborted (core dumped)
danieleratti commented 7 years ago

I get the exact same error on PHP 7.1.9-1+ubuntu16.04.1+deb.sury.org+1 (cli) (built: Sep 2 2017 05:56:43) ( NTS ).

When I run make test it fails many tests, as attached: phpv8-errors.txt

Could maybe be the operative system? I'm running Ubuntu 16.04

danieleratti commented 7 years ago

Today I tried on Ubuntu 14.04 and I got a different error but referred to the same problem:

ubuntu@ip-172-30-0-60:/tmp/v8js$ php -v
PHP 7.1.9-1+ubuntu14.04.1+deb.sury.org+1 (cli) (built: Sep  2 2017 06:17:11) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.1.9-1+ubuntu14.04.1+deb.sury.org+1, Copyright (c) 1999-2017, by Zend Technologies

ubuntu@ip-172-30-0-60:/tmp/v8js$ php -i | grep "v8"
v8js
v8js.compat_php_exceptions => 0 => 0
v8js.flags => no value => no value
v8js.icudtl_dat_path => no value => no value
v8js.use_array_access => 0 => 0
v8js.use_date => 0 => 0
PWD => /tmp/v8js
$_SERVER['PWD'] => /tmp/v8js

ubuntu@ip-172-30-0-60:/tmp/v8js$ php -a
Interactive mode enabled

php > class Foo { var $bar = null; }
php > $v8 = new V8Js();
php > $v8->foo = new Foo;
php: symbol lookup error: /usr/lib/php/20160303/v8js.so: undefined symbol: _ZSt20__throw_out_of_rangePKc

Am I doing something wrong? I just install php7.1-dev (or other version), compile v8 and php-v8js (following the guide) and it partially doesn't work.

virgofx commented 7 years ago

@stesie Maybe this will help --- I believe these errors are related ... when running V8JS against latest 3 major versions of libv8. (not related to PHP version)

My current tests show that [ Ubuntu 16.0.4 ] [ PHP7.1 from PPA ] [ V8JS/master ] against libv8 6.1, 6.2 and 6.3, the tests all fail 50% with errors above. Last successful libv8 is 6.0. Using pinepain's libv8 PPA makes it easy to install all the different libv8 libraries and quickly make clean and then phpize, configure --with proper dir, make, and make install where the tests will fail starting on libv8 6.1

pinepain commented 7 years ago

Hi!

Is the issue reproducible in raw C++ using V8 API (outside PHP extension?)? If so it may be worth to share that snippet with v8 team in v8-users or v8-dev mailing list to hear back.

danieleratti commented 7 years ago

I just got the same problem using libv8 6.1.561

danieleratti commented 7 years ago

I also tried libv8-6.0 but the tests still fail. More specifically:

sudo apt install -y php7.0-dev

sudo add-apt-repository ppa:pinepain/libv8-6.0
sudo apt-get update
sudo apt-get install libv8-6.0-dev

git clone https://github.com/phpv8/v8js.git
cd v8js
phpize
./configure --with-v8js=/opt/libv8-6.0
make
make test

...
Number of tests :  166               165
Tests skipped   :    1 (  0.6%) --------
Tests warned    :    0 (  0.0%) (  0.0%)
Tests failed    :   80 ( 48.2%) ( 48.5%)
Expected fail   :    0 (  0.0%) (  0.0%)
Tests passed    :   85 ( 51.2%) ( 51.5%)
virgofx commented 7 years ago

Can you test php7.1 and confirm my results above ? Worked perfectly for me on 6.1. Errors present in 6.2 and 6.3

danieleratti commented 7 years ago

Still not work. Am I doing something wrong?

#Run ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-20170721 (ami-785db401 @ AWS EC2 t2.xlarge)

sudo add-apt-repository ppa:pinepain/libv8-6.1
sudo add-apt-repository -y ppa:ondrej/php

sudo apt-get update -y
sudo apt upgrade -y

sudo apt-get install -y python-software-properties

sudo apt install -y php7.1-dev
sudo apt install -y libv8-6.1-dev

php -v
#PHP 7.1.9-1+ubuntu16.04.1+deb.sury.org+1 (cli) (built: Sep  2 2017 05:56:43) ( NTS )

cd /tmp
git clone https://github.com/phpv8/v8js.git
cd v8js
phpize
./configure --with-v8js=/opt/libv8-6.1
make
make test

...
Number of tests :  166               165
Tests skipped   :    1 (  0.6%) --------
Tests warned    :    0 (  0.0%) (  0.0%)
Tests failed    :   80 ( 48.2%) ( 48.5%)
Expected fail   :    0 (  0.0%) (  0.0%)
Tests passed    :   85 ( 51.2%) ( 51.5%)
virgofx commented 7 years ago

Did you run a make clean To clean previous builds before trying latest?

danieleratti commented 7 years ago

I always setted up / destroyed a brand new machine to avoid interferences of different builds

virgofx commented 7 years ago

@DanieleRatti Looks like 6.0 is the last working one for me. I must have reported based off of memory above.

danieleratti commented 7 years ago

For me, not even 6.0.

stesie commented 7 years ago

So I'm finally on vacation now \o/ ... hope I can catch up here a little

First step, I packaged current version of V8, php-v8js and php-v8 for NixOS, using V8 version 6.2.414.15 and it just passes the whole test suite fine :thinking:

Will try on Ubuntu now ...

stesie commented 7 years ago

Seems like weird stuff is going on with Ubuntu ... The error above is thrown in v8js_object_export.cc line 821, immediately below there is a catch statement for std::out_of_range ... yet it doesn't catch that exception

It can be solved by passing -lstdc++ to LDFLAGS like so

./configure --with-v8js=/where/ever/libv8/is LDFLAGS="-lstdc++"

With that I'm down to four failed tests:

=====================================================================
FAILED TEST SUMMARY
---------------------------------------------------------------------
Test V8::executeString() : Object passed from PHP [tests/object.phpt]
Test V8::executeString() : Property visibility - enumerate [tests/property_visibility-enumerate.phpt]
Test V8::executeString() : Check timezone handling [tests/timezones.phpt]
Test V8::executeString() : var_dump [tests/var_dump.phpt]
=====================================================================

... which however seem to be caused by property enumeration changes to V8 itself

danieleratti commented 7 years ago

Great, just tried and got the tests passed with the same only 4 errors.

virgofx commented 7 years ago

@stesie do you think it would be possible to have the [autodetect] for libv8 portion from PECL install attempt to detect any libraries in the /opt/libv8-X.Y folders? This would allow provisioners (like Salt) that have built-in PECL modules ... to work correctly as they don't allow for stdin/stdout options which is required when using pinepain's libv8 PPAs (since it's in different directory).

stesie commented 7 years ago

@DanieleRatti thanks for your feedback, those four other tests are fixed by pull request #328 which I've merged just now

@virgofx I think implicitly using stuff from /opt is a bit odd, but generally should be possible and feasible. Would you like to work on that? Anyways, feel free to open a different issue for that one

colinmollenhour commented 6 years ago

I'm experiencing this issue but my extension is built with pecl install v8js. It seems the LDFLAGS="-lstdc++" part needs to be made the default so that it applies to the pecl builds as well, right?