Not Finding the Symbols

Yesterday we released the new version of the MongoDB Driver for PHP, to coincide with the release of MongoDB 3.4. Not long after that, we received an issue through GitHub titled "Undefined Symbol php_json_serializable_ce in Unknown on Line 0".

TL;DR: Load the JSON extension before the MongoDB extension.

The newly released version of the driver has support for PHP's json_encode() through the JsonSerializable interface, to convert some of our internal BSON types (think MongoDB\BSON\Binary and MongoDB\BSON\UTCDateTime) directly to JSON. For this it uses functionality in PHP's JSON extension, and with that the php_json_serializable_ce symbol that this extension defines.

We run our test suite on many different distributions, but (nearly) always with our own compiled PHP binaries as we need to support so many versions of PHP (5.4-5.6, 7.0, and now 7.1), in various configurations (ZTS, or not; 32-bit or 64-bit). It came hence quite as a surprise that a self-compiled extension would not load for one of our users.

When compiling PHP from its source, by default the JSON extension becomes part of the binary. This means that the JSON extension, and the symbols it implements are always available. Linux distributions often split out each extension into their own package or shared object. Debian has php5-json (on which php5-cli depends), while Fedora has php-json. In order to make use of the JSON extension, you therefore need to install a separate package that provides the shared object (json.so) and a configuration file. Fedora installs the 20-json.ini file in /etc/php.d/. Debian installs the 20-json.ini file in /etc/php5/mods-available with a symlink to /etc/php5/cli/conf.d/20-json.ini. In both cases, they include the required extension=json.so line that instruct PHP to load the shared object and make its symbols (and PHP functions) available.

A normal PHP binary uses the dlopen system call to load a shared object, with the RTLD_LAZY flag. This flag means that symbols (such as php_json_serializable_ce) are only resolved lazily, when they are first used. This is important, because PHP extensions and the shared objects they live in, can depend on each other. The MongoDB extension depends on date, spl and json. After PHP has loaded all the shared extensions, it registers the classes and functions contained in them, in an order to satisfy this dependency graph. PHP makes sure that the classes and functions in the JSON extension are registered before the MongoDB extension, so that when the latter uses the php_json_serializable_ce symbol to declare that the MongoDB\\BSON\\UTCDateTime class implements the JsonSerializable interface the symbol is already available.

Distributions often want to harden their provided packages with additional security features. For that, they compile binaries with additional features and flags.

Debian patches PHP to replace the RTLD_LAZY flag with RTLD_NOW. Instead of resolving symbols when they are first used, this signals to the dlopen system call to resolve the symbols when the shared object is loaded. This means, that if the MongoDB extension is loaded before the JSON extension, the symbols are not available yet, and the linker throws the "Undefined Symbol php_json_serializable_ce in Unknown on Line 0" error from our bug report. This is not a problem that only related to PHP; TCL has similar issues for example.

With Fedora, the same issue is present, but shows through slightly different means. Instead of patching PHP to replace RTLD_LAZY with RTLD_NOW, it uses linker flags ("-Wl,-z,relro,-z,now") to force binaries to resolve symbols as soon as they are loaded process wide. This Built with BIND_NOW security feature goes hand in hand with Built with RELRO. The explanation on why these features are enabled on Fedora is well described on their wiki. Previously, this did expose an issue with an internal PHP API regarding creating a DateTime object.

But where does this leave us? The solution is fairly simple: You need to make sure that the JSON extension's shared object is loaded before the MongoDB extension's shared object. PECL's pecl install suggests to add the extension=mongodb.so line to the end of php.ini. Instead, on Debian, it would be much better to put the extension=mongodb.so line in a separate 99-mongodb.ini file under /etc/php5/mods-available, with a symlink to /etc/php5/cli/conf.d/99-mongodb.ini and /etc/php5/apache2/conf.d/99-mongodb.ini:

cat << EOF > /etc/php5/mods-available/mongodb.ini
; priority=99
extension=mongodb.so
EOF
php5enmod mongodb

On Fedora, you should add the extension=mongodb.so line to the new file /etc/php.d/50-mongodb.ini:

echo "extension=mongodb.so" > /etc/php.d/50-mongodb.ini

Alternatively, you can install the distribution's package for the MongoDB extension. Fedora currently has the updated 1.2.0 release for Rawhide (Fedora 26). Debian however, does not yet provide a package for the latest release yet, although an older version (1.1.7) is available in Debian unstable. At the time of this writing, Ubuntu only provides older versions for Xenial and Yakkety.

Shortlink

This article has a short URL available: https://drck.me/undefsym-cpv

Comments

Adding "extension=mongodb.so" at the end of php.ini didn't solve the issue but 99-mongodb.ini did! Thanks! BTW $ uname -a Linux titanic 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u2 (2016-10-19) x86_64 GNU/Linux

Thanks for the info, I tried just sticking extension=json.so one line above in the php.ini and that worked for me

Walking the Capital Ring - Section 15

Section 15

In this last section, we walked around London City airport. Well, sorta. Starting off at Beckton Park, and its Jake Russell Walk we started the last section of the Capital Ring. After Beckton Park, we walked through new Beckton Park as well, before coming to Cyprus DLR station.

The Capital Ring as mapped on OpenStreetMap, diverged from the route on the TFL site, and the signage on the ground. Instead of following the Royal Albert Way, it no goes through the University of East London and along the Royal Albert Dock for a while. I can imagine this being a little nicer than a dual carriage way.

At the end of the path along the dock, we had a little stint through an industrial estate, with a radar mast in sight at the end. The radar mast was straight on the Thames, and that point ended up being the furthest East on the Capital Ring: Galleons Point. The tide on the Thames was low, exposing loads of shopping trolleys and other rubbish.

From there, we crossed two sets of locks. A small one, and the much larger King George the 5th lock. Galleons Point is another new development. Now along the Thames, we passed by the Royal Victoria Gardens and ended up at North Woolwich.

The old station at North Woolwich at one time housed a museum, but that is now closed. Close behind it are Crossrail works, where a tunnel under the Thames for the new railway starts.

At this point, we could have taken the ferry across to Woolwich, and the end of the Capital Ring. Instead, we decided to walk through the Woolwich Foot Tunnel. This and the Greenwich Foot Tunnel are the only two pedestrian only tunnels under the Thames, built in the early 1900s. Apparently, photography is forbidden, but I only found that out while writing up this blog post!

At the other end of the tunnel, we walked the last 50 meters to the end of the section, and with that, the Capital Ring!

Route (with GPX)

Waymarked Trails

Time

1h 12m 14s

Distance

5.88 km

Average Heart Rate

105 bpm

Calories Burned

659 cal

For the full photo series, see my Flickr set.

Shortlink

This article has a short URL available: https://drck.me/cr15-cms

Comments

No comments yet

Walking the Capital Ring - Section 14

Section 14

Upon setting off on the penultimate section, we quickly looped around the Olympic Station, now the London Station, home of West Ham. There is a lot of new landscaping, that's not quite finished yet around here. We left the Lee soon enough, and walked towards Stratford High Street. There Crossrail work near Pudding Mill Lane station, where the Ring was diverted along an industrial estate. This was badly signposted. I've updated OpenStreetMap with the current route, but it will have to be redone once the works are over. Once they are, it should be easy enough to navigate from Victoria Walk to the Greenway.

In our case, we had to spend a little bit of time to fine the Greenway, but once we got there it was a very easy route. In fact, for 80% of this section, you walk in a straight line over the Greenway.

Near the start of the Greenway, the walk goes past the Abbey Mills Pumping Station, which has been pumping sewage around since the 1860s. As a matter of fact, the Greenway that we were walking on, is actually a long footpath and cycleway on top of the Northern Outfall Sewer. This then also explained the nice fragrances along this stretch of the route...

It was a long and monotonous walk along the Greenway, and we were pleased once we left it and could walk the last bit of this section through Beckton District Park. When coming out of the park, we had concluded this section. One more to go!

Route (with GPX)

Waymarked Trails

Time

1h 37m 38s

Distance

8.24 km

Average Heart Rate

108 bpm

Calories Burned

836 cal

For the full photo series, see my Flickr set.

Shortlink

This article has a short URL available: https://drck.me/cr14-cms

Comments

No comments yet

Walking the Capital Ring - Section 13

Section 13

This section starts at Stoke Newington going along some residential streets. After coming through Springfield Park, it follows the river Lea for the rest of the walk.

When crossing the bridge over the river, you have a fine view of the Lee Valley Marina, as well as the river itself. At the point where we crossed, there were many canal boats moored.

Note: I didn't misspell Lea or Lee. There is a naming confusion (caused by parliament in the 1760s). The distinction is made between natural features (Lea) or artificial features (Lee).

With the river Lea on the right, and the Walhamstow Marshes on the left, we had a pleasant stroll along the tow path, although it was rather busy. Combined with some inconsiderate cyclists it wasn't particularly a relaxing walk. As there is space enough, it would be better if there were two separate paths - one for cyclists, and one for pedestrians.

We walked underneath the A. V. Roe Arches, named after A.V. Roe, who built his first powered air planes here to fly over the nearby marshes. There is a blue plaque to dedicate this event. It is however slightly hidden, and you need to cross patches with nettles.

After the Lee Canal split off from the River Lea, the Walthamstow Marches were replaced by the Hackney Marches on our left. Apparently they are in the Guinness Book of Records as having the largest collection of football pitches.

The walk ends at the Olympic Park, or rather now, The Queen Elizabeth Olympic Park. It is still very much under development, but at least the park is open now. The section itself stops right at the Crate Brewery. Unfortunately we only found out after having left the canal, while enjoying a pint at Tap East.

Route (with GPX)

Waymarked Trails

Time

1h 08m 52s

Distance

6.35 km

Average Heart Rate

106 bpm

Calories Burned

571 cal

For the full photo series, see my Flickr set.

Shortlink

This article has a short URL available: https://drck.me/cr13-cmk

Comments

No comments yet

Walking the Capital Ring - Section 12

Section 12

We started at Highgate, and the first part of the walk was through Parkland Walk Local Nature Reserve. Probably for a good 2 miles. It used to be the site of an old railway line, and near Crouch End, you can still find the remains of former platforms. It is a lovely sheltered part, and where there are bridges, there is also graffiti. Some of it illegal and shit, but mostly pieces of art. When we came past, there were artists creating new pieces.

At the end of the Parkland walk, we crossed into Finsbury Park. The breeze there was very welcome, as it was another warm and humid day. I hadn't realized that it was such a large park!

Coming out of the park we followed the course of the New River: an artificial water way meant to supply London with fresh drinking water. Parts of it are lovely, but there was also a lot of rubbish floating around in it.

After crossing Seven Sisters Road, the walk looped back towards Finsbury Road and along the East and West Reservoirs. There were many new developments along this stretch, which resulted in the path (and Capital Ring) being diverted along some shiny new footpaths. There was also a shiny ball.

At the end of the path around the reservoirs, and before entering Clissold Park, we passed by a strange looking building — in the shape of a castle. This later turned out to be the Castle Climbing Centre. The park was very busy, which was no surprise as it was a lovely day.

The last part of the walk started out with a tedious stroll along Stoke Newington High Street, which I also ended up mapping in great detail. Leaving the busy High Street, we entered Abney Park. One of London's Magnificent Seven cemeteries. Unfortunately it's lovely chapel was hidden behind scaffolding.

The section ends when we got out of the park. A quick walk later we ended up at Stoke Newington station, to find our way home.

Route (with GPX)

Waymarked Trails

Time

1h 47m 16s

Distance

8.90 km

Average Heart Rate

104 bpm

Calories Burned

863 cal

For the full photo series, see my Flickr set.

Shortlink

This article has a short URL available: https://drck.me/cr12-cmi

Comments

No comments yet

Life Line