pelias / spatial

ALPHA: geographic data service backed by spatialite
https://spatial.demo.geocode.earth
29 stars 6 forks source link

Segmentation fault at database creation #39

Closed Joxit closed 4 years ago

Joxit commented 4 years ago

Hey team!

I was using your awesome geocoding engine when I noticed something interesting. Let me tell you more about it.


Here's what I did :innocent:

npm install
npm run postinstall
npm run env_check

Here's what I got :scream_cat:

> ./bin/env_check

test/environment.js
  compile_options
    ✓ ENABLE_RTREE
    ✓ ENABLE_RTREE != 0
    ✓ ENABLE_COLUMN_METADATA
    ✓ ENABLE_COLUMN_METADATA != 0
    ✓ ENABLE_JSON1
    ✓ ENABLE_JSON1 != 0

 FAIL  test/environment.js 6 OK 1s
  command: node
  args:
    - -r
    - ./spatial/node_modules/esm/esm.js
    - test/environment.js
  exitCode: null
  signal: SIGSEGV

Suites:   1 failed, 1 of 1 completed
Asserts:  6 passed, of 6

It fails when I pass the statement PRAGMA main.table_info('spatial_ref_sys') here : https://github.com/pelias/spatial/blob/18bb5c7c5e813bedcc4c100b1fb8f6b704629f20/sqlite/SqliteIntrospect.js#L22-L29

More info :

This is on my laptop OS: Debian 10.3 (Buster) NodeJS: v10.19.0 and v12.16.1 packages: libspatialite 4.3.0a; libsqlite3 3.27.2; g++ & gcc 8.3.0; libicu-dev 63.1


How to reproduce the issue with docker ?

Run a debian:buster images docker run -ti --rm debian:buster Then run these commands inside the container

mkdir code
cd code/
apt update
apt install -y git libspatialite7 sqlite3 curl make g++ gcc python2 libspatialite-dev libsqlite3-mod-spatialite
git clone https://github.com/pelias/spatial
cd spatial
ls
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash
nvm install 10
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion
nvm i 10
npm install
npm run postinstall
# pipefail does not work on debian
npx tap --no-cov --reporter=specy test/environment.js

This may be caused by spatialite module... But IDK why.... :disappointed:

missinglink commented 4 years ago

I think the error is caused when you first load the spatialite extension into SQLite, which also makes sense from the output you posted.

I suspect the issue is due to a version mismatch between the SQLite version run by better-sqlite3 (sqlite-amalgamation-3280000 via postinstall) and the version which your libapatialite was compiled against.

I'll have a look and get back to you

missinglink commented 4 years ago

Looks like the Debian versions are super old (3.27.2-3) as 4.3.0 was released in 2015 and I'm using the latest 5.0.0-beta code cloned from the source repo.

I don't think we'll be able to support such old versions (plus the 5 release has loads of nice new things in it).

Ill have a crack at a dockerfile for you but it will probably require building the geo libraries from source since they all pretty much ancient in Ubuntu/Debian.

missinglink commented 4 years ago

See https://github.com/missinglink/gis

Joxit commented 4 years ago

Hum... Okay :disappointed: I will continue to use the pelias/spatial docker in dev mode... Or build all the libs... :thinking:

build/spatialite5.sh was written only for macOS ?

missinglink commented 4 years ago

Hmm yeah, I actually forgot I wrote that file ;)

The only thing in there that's specific to OSX are those dependency references at the top, the rest looks generic.

missinglink commented 4 years ago

One of the biggest challenges of this project is going to be getting this environment set up on different systems.

I was thinking of having a runtime environment inside docker and if it's possible, to use that for development, I'm just not sure how user friendly that would be, but it would allow development on Windows etc too.

I am super busy this week but I plan to make a second runtime environment in Ubuntu/Debian to complement the existing minimal Alpine image, it will be a nice reference for any future OS's.

I suspect, although I've not tried this, that you can simply copy the files from the Alpine docker image into any other posix image and it should 'just work' :man_shrugging:

missinglink commented 4 years ago

It's possible to see which shared libraries are used by spatialite as such:

docker run --rm -it --name spatialite missinglink/spatialite

in another window:

docker exec -it spatialite ldd /usr/bin/spatialite
    /lib/ld-musl-x86_64.so.1 (0x7fc81407c000)
    libspatialite.so.7 => /usr/lib/libspatialite.so.7 (0x7fc813529000)
    libreadline.so.7 => /usr/lib/libreadline.so.7 (0x7fc8132e6000)
    libsqlite3.so.0 => /usr/lib/libsqlite3.so.0 (0x7fc81300b000)
    libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7fc81407c000)
    libxml2.so.2 => /usr/lib/libxml2.so.2 (0x7fc812ce2000)
    librttopo.so.1 => /usr/lib/librttopo.so.1 (0x7fc812a6d000)
    libfreexl.so.1 => /usr/lib/libfreexl.so.1 (0x7fc812863000)
    libproj.so.15 => /usr/lib/libproj.so.15 (0x7fc812672000)
    libz.so.1 => /lib/libz.so.1 (0x7fc812658000)
    libgeos_c.so.1 => /usr/lib/libgeos_c.so.1 (0x7fc812629000)
    libncursesw.so.6 => /usr/lib/libncursesw.so.6 (0x7fc8123d1000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x7fc81207f000)
    libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x7fc811e6d000)
    libgeos-3.7.2.so => /usr/lib/libgeos-3.7.2.so (0x7fc811cf4000)

docker exec -it spatialite lsof -p 1
1   /usr/bin/spatialite /dev/pts/0
1   /usr/bin/spatialite /dev/pts/0
1   /usr/bin/spatialite /dev/pts/0
1   /usr/bin/spatialite /usr/share/proj/proj.db

note: some of these libraries are only used by the REPL

Joxit commented 4 years ago

Ok, I did some changes to work with Debian too ;)

Yep, I saw the SPATIALITE_EXTENSION_PATH variable

Okay, don't worry, I will try to find a workaround and if I can't, I will continue to use the alpine docker image for dev.

I also tried with missinglink/gis; here is the workflow

docker run -ti --rm missinglink/gis

sudo apt update
sudo apt install -y curl git python2
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash
nvm install 10
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion
git clone https://github.com/pelias/spatial .
npm install
npm run postinstall
export SPATIALITE_EXTENSION_PATH=/usr/local/lib/
npx tap --no-cov --reporter=specy test/environment.js

Same output... SIGSEGV

ldd inside the container:

$ ldd /usr/local/bin/spatialite
    linux-vdso.so.1 (0x00007ffd06348000)
    libspatialite.so.7 => /usr/local/lib/libspatialite.so.7 (0x00007fee3ad2c000)
    libsqlite3.so.0 => /usr/local/lib/libsqlite3.so.0 (0x00007fee3abc6000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fee3a9c8000)
    libxml2.so.2 => /lib/x86_64-linux-gnu/libxml2.so.2 (0x00007fee3a820000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fee3a7ff000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fee3a6b1000)
    librttopo.so.1 => /usr/local/lib/librttopo.so.1 (0x00007fee3a638000)
    libfreexl.so.1 => /usr/local/lib/libfreexl.so.1 (0x00007fee3a62d000)
    libproj.so.13 => /lib/x86_64-linux-gnu/libproj.so.13 (0x00007fee3a5b6000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fee3a59a000)
    libgeos_c.so.1 => /lib/x86_64-linux-gnu/libgeos_c.so.1 (0x00007fee3a565000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fee3a55f000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fee3b47c000)
    libicuuc.so.63 => /lib/x86_64-linux-gnu/libicuuc.so.63 (0x00007fee3a38e000)
    liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007fee3a367000)
    libgeos-3.7.1.so => /lib/x86_64-linux-gnu/libgeos-3.7.1.so (0x00007fee3a1c0000)
    libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fee39fde000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fee39fc4000)
    libicudata.so.63 => /lib/x86_64-linux-gnu/libicudata.so.63 (0x00007fee385d2000)
missinglink commented 4 years ago

I spent way too much time looking at this the last two days and I can get it working in buster but only in certain conditions which make no sense!

I'll clean up what I have and hand it over to you, I suspect that the issue is with better-sqlite3 although I can't definitively prove that!

tl;dr don't load libspatialite, load mod_spatialite (no path, no extension) using the loadExtension() function of better-sqlite3, the SELECT load_extension() SQL function always tells me I don't have access despite compiling it appropriately, I suspect it's disabled by better-sqlite3

This works for me when using missinglink/gis:buster as a base, but, and here's the kicker, but only when it tries to first load a bunch of invalid extension paths, if I remove these paths then it segfaults. I suspected a race condition but using a sleep didn't fix it.

So as long as you call db.loadExtension() loads of times on paths that don't exist or are not able to load, then finally run db.loadExtension("mod_spatialite") then it works.

Makes no sense but it is what it is :man_shrugging:

Also, don't try to load "mod_spatialite.so", that seems to always segfault for me despite referencing the same exact file which doesn't...

missinglink commented 4 years ago

This may be related https://github.com/valhalla/valhalla/issues/1437

missinglink commented 4 years ago

@Joxit this works for me https://github.com/pelias/spatial/pull/40

pecamardelli commented 3 years ago

I'm experiencing the same segmentation fault error when loading spatialite module on a test suite. I'm using Debian and Ubuntu and it seems to work fine with libc6 version 2.27, which is what Ubuntu 18.04 uses. For later versions (2.28 on Debian Buster, and 2.31 on Ubuntu 20.04) it produces the error. I've tried every combination of mod_spatialite and its dependencies with no success, only if libc6 version is 2.27 or lower it seems to work.

Joxit commented 3 years ago

What's your nodejs version ?

I'm on Debian 11 Bullseye and it seems to work well (libc 2.31). Try a new npm install, this will trigger a new spatialite build.

pecamardelli commented 3 years ago

What's your nodejs version ?

I'm on Debian 11 Bullseye and it seems to work well (libc 2.31). Try a new npm install, this will trigger a new spatialite build.

I'm using node version 14.17.0. And no luck at all... Only works on Ubuntu 18.04. It's such a puzzle.

missinglink commented 3 years ago

Hi @pecamardelli have you seen this guide? https://github.com/pelias/spatial/tree/master/runtime