daniel-j-h / libosrmc

Pure C bindings for libosrm
MIT License
18 stars 8 forks source link

libosrmc vs libosrm 5.12.0 #4

Closed rburcham closed 5 years ago

rburcham commented 7 years ago

Great work. This seems to be the most recently updated set of C wrappers, with python examples too.

I've built against latest libOSRM (5.12.0) and I get an undefined symbol when running the python example (I've prepared monaco.osm with osmosis):

Both libosrm and libosrmc were built on the same environment with

CXXFLAGS = -O2 -Wall -Wextra -pedantic -std=c++14 -fvisibility=hidden -fPIC -fno-rtti $(shell pkg-config --cflags libosrm)

Execution results in a missing symbol

$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib python ./osrm_python2.py monaco.osm
Traceback (most recent call last):
  File "./osrm_python2.py", line 8, in <module>
    from osrmcpy import OSRM, Coordinate
  File "/usr/src/libosrmc/bindings/osrmcpy.py", line 11, in <module>
    lib = c.cdll.LoadLibrary('libosrmc.so')
  File "/usr/lib64/python2.7/ctypes/__init__.py", line 438, in LoadLibrary
    return self._dlltype(name)
  File "/usr/lib64/python2.7/ctypes/__init__.py", line 360, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: /usr/local/lib/libosrmc.so: undefined symbol: _ZTIN3tbb4taskE
rburcham commented 7 years ago

So I went ahead and linked tbb and all the boost dependencies, and of course we're segfaulting now:

$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib python ./osrm_python2.py monaco.osm Segmentation fault (core dumped)

Editing the libosrmc/config.mk to include

LDLIBS = -lstdc++ -lboost_thread-mt -lboost_iostreams-mt -lboost_filesystem-mt -lboost_system-mt -lpthread -ltbb $(shell pkg-config --libs libosrm)

yields

$ ldd /usr/local/lib/libosrmc.so.5.4
ldd: warning: you do not have execution permission for `/usr/local/lib/libosrmc.so.5.4'
    linux-vdso.so.1 =>  (0x00007ffd98909000)
    libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fccf7a3e000)
    libboost_thread-mt.so.1.53.0 => /lib64/libboost_thread-mt.so.1.53.0 (0x00007fccf7826000)
    libboost_system-mt.so.1.53.0 => /lib64/libboost_system-mt.so.1.53.0 (0x00007fccf7622000)
    libboost_iostreams-mt.so.1.53.0 => /lib64/libboost_iostreams-mt.so.1.53.0 (0x00007fccf7408000)
    libboost_filesystem-mt.so.1.53.0 => /lib64/libboost_filesystem-mt.so.1.53.0 (0x00007fccf71f0000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fccf6fd4000)
    libtbb.so.2 => /lib64/libtbb.so.2 (0x00007fccf6d9f000)
    libm.so.6 => /lib64/libm.so.6 (0x00007fccf6a9c000)
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fccf6886000)
    libc.so.6 => /lib64/libc.so.6 (0x00007fccf64c5000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fccf7f0e000)
    librt.so.1 => /lib64/librt.so.1 (0x00007fccf62bc000)
    libbz2.so.1 => /lib64/libbz2.so.1 (0x00007fccf60ac000)
    libz.so.1 => /lib64/libz.so.1 (0x00007fccf5e96000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007fccf5c91000)

My guess is the boost dependencies are the problem? What should they be? I am using the same gcc used to build osrm,

gcc version 6.3.1 20170216 (Red Hat 6.3.1-3) (GCC)

daniel-j-h commented 7 years ago

Hm these bindings were written and tested against 5.4; in the meantime we had a few changes upstream, but the libosrm interface should have stayed the same.

I think you have a little mistake when call the example with

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib python ./osrm_python2.py monaco.osm

monaco.osm is a OpenStreetMap XML extract, right?

But libosrm requires a pre-processed road network and only provides the routing layer. You need to run osrm-extract and osrm-contract for the CH pipeline (or osrm-extract, osrm-partition, osrm-customize for the MLD pipeline). Make sure you're using these binaries from the osrm installation you're linking against libosrm - versions have to be in sync.

See the docs upstream, the Wiki and the node-osrm readme:

https://github.com/Project-OSRM/osrm-backend#open-source-routing-machine


Happy to guide you along if you want to run these ABI and API stable C wrappers (and Python wrappers on top of it) out; a good place to start with improvements is the existing route service interface and its response.

I would love to get this merged upstream eventually if there is need for it.

rburcham commented 7 years ago

I'm with you. The need for an optimal in-process call path at scale is gaining traction.

I did some more reading and quickly discovered my error. I've now used osrm-extract and the car.lua profile to prepare a monaco.osrm file:

# osrm-extract -p /usr/src/osrm-backend/profiles/car.lua monaco.osm.pbf 
[info] Using script /usr/src/osrm-backend/profiles/car.lua
[info] Input file: monaco.osm.pbf
[info] Profile: car.lua
[info] Threads: 1
[info] Parsing in progress..
[info] Using profile api version 2
[info] input file generated by osmconvert 0.7T
[info] timestamp: 2016-03-05T00:26:02Z
[info] Found 3 turn restriction tags:
[info]   motorcar
[info]   motor_vehicle
[info]   vehicle
[info] Parse relations ...
[info] Parse ways and nodes ...
[info] Parsing finished after 0.699091 seconds
[info] Raw input contains 180118 nodes, 27377 ways, and 0 relations
[info] Sorting used nodes        ... ok, after 0.001121s
[info] Erasing duplicate nodes   ... ok, after 3.9e-05s
[info] Sorting all nodes         ... ok, after 0.000344s
[info] Building node id map      ... ok, after 0.00027s
[info] setting number of nodes   ... ok
[info] Confirming/Writing used nodes     ... ok, after 0.001159s
[info] Writing barrier nodes     ... ok, after 0s
[info] Writing traffic light nodes     ... ok, after 0s
[info] Processed 15809 nodes
[info] Sorting edges by start    ... ok, after 0.001672s
[info] Setting start coords      ... ok, after 0.002651s
[info] Sorting edges by target   ... ok, after 0.001358s
[info] Computing edge weights    ... ok, after 0.024335s
[info] Sorting edges by renumbered start ... ok, after 0.001567s
[info] Writing used edges       ... ok, after 0.000392sProcessed 16280 edges
[info] Sorting used ways         ... ok, after 1.4e-05s
[info] Collecting start/end information on 27 restrictions...ok, after 6e-05s
[info] Collecting start/end information on 27 restrictions...ok, after 2.4e-05s
[info] writing street name index ... ok, after 0.000327s
[info] extraction finished after 0.783405s
[info] Generating edge-expanded graph representation
[info] Importing number_of_nodes new = 15809 nodes 
[info]  - 1 bollard nodes, 21 traffic lights
[info]  and 16280 edges 
[info] Graph loaded ok and has 16280 edges
[info] . 10% . 20% . 30% . 40% . 50% . 60% . 70% . 80% . 90% . 100%
[info] Node compression ratio: 0.131381
[info] Edge compression ratio: 0.156511
[info] Generating edge expanded nodes ... 
[info] . 10% . 20% . 30% . 40% . 50% . 60% . 70% . 80% . 90% . 100%
[info] Expanding via-way turn restrictions ... 
[info] 
[info] Generated 4045 nodes (0 of which are duplicates)  and 16280 segments in edge-expanded graph
[info] Generating edge-expanded edges 
[info] . 10% . 20% . 30% . 40% . 50% . 60% . 70% . 80% . 90% .
[info] Reunmbering turns
[info] Writing 0 conditional turn penalties...
[info] Created 20 entry classes and 849 Bearing Classes
[info] Writing Turn Lane Data to File...
[info] done.
[info] Generated 16280 edge based node segments
[info] Node-based graph contains 4045 edges
[info] Edge-expanded graph ...
[info]   contains 6601 edges
[info]   skips 0 turns, defined by 27 restrictions
[info]   skips 0 U turns
[info]   skips 0 turns over barriers
[info] Handled: 0 of 14 lanes: 0 %.
[info] Timing statistics for edge-expanded graph:
[info] Renumbering edges: 0.00013s
[info] Generating nodes: 0.004532s
[info] Generating edges: 0.645205s
[info] Geometry successfully removed:
  compressed edges: 5100
  compressed geometries: 32582
  longest chain length: 138
  cmpr ratio: 0.156528
  avg chain length: 6.38863
[info] Writing Intersection Classification Data
[info] ok, after 0.000252s
[info] Saving edge-based node weights to file.
[info] Done writing. (8.1e-05)
[info] Computing strictly connected components ...
[info] Found 98 SCC (1 large, 97 small)
[info] SCC run took: 0.000259898s
[info] Building r-tree ...
[info] Constructing r-tree of 16280 segments build on-top of 15809 coordinates
[info] finished r-tree construction in 0.018448 seconds
[info] Writing nodes for nodes-based and edges-based graphs ...
[info] Writing edge-based-graph edges       ... 
[info] ok, after 0.000107s
[info] Processed 6601 edges
[info] Expansion: 21470 nodes/sec and 5493 edges/sec
[info] To prepare the data for routing, run: ./osrm-contract "monaco.osrm"
[info] RAM: peak bytes used: 53428224
[root@localhost bindings]# ls -lart
total 3964
-rw-r--r-- 1 root root 1759101 Mar 10  2016 monaco.osm.pbf
-rw-r--r-- 1 root root     852 Apr  4  2016 monaco.poly
-rw-r--r-- 1 root root    2921 Sep 25 18:08 README.md
-rwxr-xr-x 1 root root    1359 Sep 25 18:08 osrm_python2.py
-rwxr-xr-x 1 root root    1925 Sep 25 18:08 osrm_or-tools.py
-rw-r--r-- 1 root root    3638 Sep 25 18:08 osrm_haskell.hs
-rwxr-xr-x 1 root root    4627 Sep 25 18:08 osrmcpy.py
-rw-r--r-- 1 root root    2543 Sep 25 18:08 osrm_c89.c
drwxr-xr-x 5 root root     121 Sep 25 18:08 ..
-rw-r--r-- 1 root root    4790 Sep 25 18:45 osrmcpy.pyc
-rw-r--r-- 1 root root  708912 Sep 26 08:47 monaco.osrm
-rw-r--r-- 1 root root      28 Sep 26 08:47 monaco.osrm.timestamp
-rw-r--r-- 1 root root    2352 Sep 26 08:47 monaco.osrm.properties
-rw-r--r-- 1 root root   10023 Sep 26 08:47 monaco.osrm.names
-rw-r--r-- 1 root root   40784 Sep 26 08:47 monaco.osrm.cnbg_to_ebg
-rw-r--r-- 1 root root   79212 Sep 26 08:47 monaco.osrm.turn_penalties_index
-rw-r--r-- 1 root root   13218 Sep 26 08:47 monaco.osrm.turn_weight_penalties
-rw-r--r-- 1 root root   13218 Sep 26 08:47 monaco.osrm.turn_duration_penalties
-rw-r--r-- 1 root root      36 Sep 26 08:47 monaco.osrm.tls
-rw-r--r-- 1 root root      16 Sep 26 08:47 monaco.osrm.tld
-rw-r--r-- 1 root root      16 Sep 26 08:47 monaco.osrm.restrictions
-rw-r--r-- 1 root root  331014 Sep 26 08:47 monaco.osrm.geometry
-rw-r--r-- 1 root root   46255 Sep 26 08:47 monaco.osrm.edges
-rw-r--r-- 1 root root   69328 Sep 26 08:47 monaco.osrm.icd
-rw-r--r-- 1 root root  167264 Sep 26 08:47 monaco.osrm.cnbg
-rw-r--r-- 1 root root   16196 Sep 26 08:47 monaco.osrm.enw
-rw-r--r-- 1 root root    1376 Sep 26 08:47 monaco.osrm.ramIndex
-rw-r--r-- 1 root root  191976 Sep 26 08:47 monaco.osrm.nbg_nodes
-rw-r--r-- 1 root root  325520 Sep 26 08:47 monaco.osrm.fileIndex
-rw-r--r-- 1 root root   56678 Sep 26 08:47 monaco.osrm.ebg_nodes
-rw-r--r-- 1 root root  132044 Sep 26 08:47 monaco.osrm.ebg
drwxr-xr-x 2 root root    4096 Sep 26 08:47 .

I do still segfault though:

$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib python ./osrm_python2.py
Usage: ./osrm_python2.py monaco.osrm
$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib python ./osrm_python2.py monaco.osrm
Segmentation fault (core dumped) 

But of course I need to run osrm-contract:

$ osrm-contract monaco.osrm
[info] Input file: monaco.osrm
[info] Threads: 1
[info] Reading node weights.
[info] Done reading node weights.
[info] Loading edge-expanded graph representation
[info] merged 30 edges out of 13202
[info] initializing node priorities... ok.
[info] preprocessing 3588 (88.7021%) nodes...
[info] . 10% . 20% . 30% . 40% . 50% . 60% .[renumbered] 70% . 80% . 90% 
[info] Getting edges of minimized graph . 10% . 20% . 30% . 40% . 50% . 60% . 70% . 80% . 90% . 100%
[info] initializing node priorities... ok.
[info] preprocessing 443 (10.9518%) nodes...
[info] [renumbered]. 10% . 20% . 30% . 40% . 50% . 60% . 70% . 80% . 90% . 100% 100% 
[info] Getting edges of minimized graph . 10% . 20% . 30% . 40% . 50% . 60% . 70% . 80% . 90% . 100%
[info] initializing node priorities... ok.
[info] preprocessing 443 (10.9518%) nodes...
[info] [renumbered]. 10% . 20% . 30% . 40% . 50% . 60% . 70% . 80% . 90% . 100% 100% 
[info] Getting edges of minimized graph . 10% . 20% . 30% . 40% . 50% . 60% . 70% . 80% . 90% . 100%
[info] initializing node priorities... ok.
[info] preprocessing 443 (10.9518%) nodes...
[info] [renumbered]. 10% . 20% . 30% . 40% . 50% . 60% . 70% . 80% . 90% . 100% 100% 
[info] Getting edges of minimized graph . 10% . 20% . 30% . 40% . 50% . 60% . 70% . 80% . 90% . 100%
[info] initializing node priorities... ok.
[info] preprocessing 443 (10.9518%) nodes...
[info] [renumbered]. 10% . 20% . 30% . 40% . 50% . 60% . 70% . 80% . 90% . 100% 100% 
[info] Getting edges of minimized graph . 10% . 20% . 30% . 40% . 50% . 60% . 70% . 80% . 90% . 100%
[info] Contracted graph has 13682 edges.
[info] Contraction took 1.1516 sec
[info] Preprocessing : 1.15392 seconds
[info] finished preprocessing
[info] RAM: peak bytes used: 70602752

which has resulted in the creation of

-rw-r--r-- 1 root root   66056 Sep 26 08:55 monaco.osrm.datasource_names
-rw-r--r-- 1 root root  289892 Sep 26 08:55 monaco.osrm.hsgr
-rw-r--r-- 1 root root      48 Sep 26 08:55 monaco.osrm.core

but no modification to the monaco.osrm file.

EDIT - also, strace output shows the segfault happening before the monaco.osrm file is referenced/opened.

rburcham commented 7 years ago

Okay well I can see now that from my stock build of osrm-backend from git on CentOS I don't have a libosrm shared object, I just have a libosrm static lib. Clearly something changed in the default build profile in the past year?

So the libosrmc link step needs a change...

EDIT - nah it's properly linking in the libosrm.a and resolving the route symbols properly.

rburcham commented 7 years ago

I've attached strace logs for two runs on two separate hosts, one centos and one gentoo, both of which segfault.

The centos host goes to stat an empty file and segfaults. The gentoo host goes to fstat /dev/shm/osrm-region (doesn't exist) and segfaults.

strace_output_centos.log strace_output_roblt3_python2.log

Interestingly, switching to python3 on the gento box results in

$ ./osrm_python3.py /home/rob/workspace/libosrmc/bindings/monaco.osrm 
Opening: /home/rob/workspace/libosrmc/bindings/monaco.osrm 
Traceback (most recent call last):
  File "./osrm_python3.py", line 53, in <module>
    main()
  File "./osrm_python3.py", line 17, in main
    osrm = OSRM(sys.argv[1])
  File "/home/rob/workspace/libosrmc/bindings/osrmcpy.py", line 120, in __init__
    _.config = lib.osrmc_config_construct(base_path)
ctypes.ArgumentError: argument 1: <class 'TypeError'>: wrong type
rburcham commented 7 years ago

And to be clear, the monaco data has been prepped with osrm-datastore:

$ sudo osrm-datastore ./monaco.osrm
[info] Loading data into REGION_1
[info] load names from: "./monaco.osrm.names"
[info] Allocating shared memory of 1258434 bytes
[info] All data loaded. Notify all client about new data in REGION_1 with timestamp 1
[info] All clients switched.
$ ls -la /dev/shm/
total 16
drwxrwxrwt  2 root root    60 Sep 26 15:07 .
drwxr-xr-x 18 root root  3720 Sep 26 15:03 ..
-rw-r--r--  1 root root 16392 Sep 26 15:07 osrm-region

Does that shared memory file look right? 16k?

I've also tried the osrm_c89 harness:

$ gcc -O2 -Wall -Wextra -pedantic -std=c89 osrm_c89.c -losrmc -o osrm_c89

$ ls -la osrm_c89
-rwxr-xr-x 1 rob rob 13192 Sep 26 14:24 osrm_c89
$ ldd osrm_c89
        linux-vdso.so.1 (0x00007fffaadae000)
        libosrmc.so.5 => /usr/local/lib64/libosrmc.so.5 (0x00007fe3b5c3e000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fe3b5884000)
        libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/libstdc++.so.6 (0x00007fe3b5482000)
        libtbb.so.2 => /usr/lib64/libtbb.so.2 (0x00007fe3b5254000)
        libboost_thread.so.1.63.0 => /usr/lib64/libboost_thread.so.1.63.0 (0x00007fe3b502c000)
        libboost_iostreams.so.1.63.0 => /usr/lib64/libboost_iostreams.so.1.63.0 (0x00007fe3b4e11000)
        libboost_filesystem.so.1.63.0 => /usr/lib64/libboost_filesystem.so.1.63.0 (0x00007fe3b4bf7000)
        libboost_system.so.1.63.0 => /usr/lib64/libboost_system.so.1.63.0 (0x00007fe3b49f3000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fe3b47d7000)
        libm.so.6 => /lib64/libm.so.6 (0x00007fe3b44db000)
        libgcc_s.so.1 => /usr/lib/gcc/x86_64-pc-linux-gnu/6.3.0/libgcc_s.so.1 (0x00007fe3b42c4000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fe3b5c1a000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007fe3b40be000)
        librt.so.1 => /lib64/librt.so.1 (0x00007fe3b3eb6000)
        libz.so.1 => /lib64/libz.so.1 (0x00007fe3b3c9f000)
        libbz2.so.1 => /lib64/libbz2.so.1 (0x00007fe3b3a8f000)

$ sudo ./osrm_c89 /home/rob/workspace/libosrmc/bindings/monaco.osrm
Segmentation fault
rburcham commented 7 years ago

Also

$ osrm-routed monaco.osrm &
[info] starting up engines, v5.12.0
[info] Threads: 8
[info] IP address: 0.0.0.0
[info] IP port: 5000
[info] load names from: "monaco.osrm.names"
[info] set checksum: 3756672125
[info] set checksum: 3756672125
[info] set checksum: 3756672125
[info] set checksum: 3756672125
[info] set checksum: 3756672125
[info] set checksum: 3756672125
[info] set checksum: 3756672125
[info] set checksum: 3756672125
[info] http 1.1 compression handled by zlib version 1.2.11
[info] Listening on: 0.0.0.0:5000
[info] running and waiting for requests

Runs without segfault, and then hitting it with curl returns successfully:

$ curl "http://127.0.0.1:5000/route/v1/driving/7.419758,43.731142;7.419505,43.736825?steps=true"
{"code":"Ok","routes":[{"geometry":"ch|iGuchl@mCeMi@eAc@Mc@HiAz@aHvBaG^oDk@Q?IRH`@fDrEbDhDfDpCdCUnEcAHNw@jE[nAQPoBo@yBf@Yx@WFqABqA[eCaCs@eD_CiD","legs":[{"steps":[{"intersections":[{"out":0,"entry":[true],"bearings":[68],"location":[7.419627,43.731377]}],"geometry":"ch|iGuchl@aAcF","mode":"driving","duration":14.3,"maneuver":{"bearing_after":68,"type":"depart","modifier":"right","bearing_before":0,"location":[7.419627,43.731377]},"weight":14.3,"distance":98.7,"name":"Tunnel Rocher Palais"},{"intersections":[{"out":0,"location":[7.420766,43.731709],"bearings":[60,75,255],"entry":[true,true,false],"in":2}],"geometry":"ej|iGyjhl@o@qC[oA[u@MOQGQEQBE@KBIFKHSRQLMFMBM@","mode":"driving","duration":32,"maneuver":{"bearing_after":64,"type":"fork","modifier":"slight left","bearing_before":67,"location":[7.420766,43.731709]},"weight":32,"distance":242.3,"name":"Tunnel Rocher Palais"},{"intersections":[{"out":2,"location":[7.421936,43.733172],"bearings":[150,180,345],"entry":[false,false,true],"in":1},{"out":2,"location":[7.421385,43.734428],"bearings":[165,270,345],"entry":[false,false,true],"in":0},{"out":2,"location":[7.421372,43.73448],"bearings":[165,270,345],"entry":[false,true,true],"in":0},{"out":0,"location":[7.42122,43.735437],"bearings":[0,180,270],"entry":[true,false,false],"in":1}],"geometry":"is|iGcrhl@UJ]NYLGBMFIDi@Nq@Rg@JI@IB{@JwAJa@BI@{@@E?m@C]Eg@K[OGC","mode":"driving","duration":21.2,"maneuver":{"bearing_after":337,"type":"turn","modifier":"straight","bearing_before":354,"location":[7.421936,43.733172]},"weight":21.2,"distance":383.9,"name":"Boulevard Albert 1er"},{"intersections":[{"out":0,"location":[7.421419,43.736532],"bearings":[0,30,195],"entry":[true,true,false],"in":2}],"geometry":"ih}iG{nhl@K?KAEAG?C@C@ABAB?BAD?D?DBFDL","mode":"driving","duration":2.5,"maneuver":{"bearing_after":1,"type":"fork","modifier":"slight left","bearing_before":16,"location":[7.421419,43.736532]},"weight":2.5,"distance":48.3,"name":"Rond-Point Sainte-D��vote"},{"intersections":[{"out":2,"location":[7.421158,43.736744],"bearings":[45,60,225],"entry":[false,false,true],"in":1},{"out":1,"location":[7.420993,43.736611],"bearings":[45,225,255],"entry":[false,true,true],"in":0},{"out":2,"location":[7.419447,43.73528],"bearings":[30,165,210],"entry":[false,true,true],"in":0},{"out":1,"location":[7.41925,43.735083],"bearings":[30,210,300],"entry":[false,true,true],"in":0},{"out":1,"location":[7.418635,43.734397],"bearings":[30,210,330],"entry":[false,true,false],"in":0},{"out":2,"location":[7.418518,43.734243],"bearings":[30,105,195,300],"entry":[false,true,true,true],"in":0},{"out":1,"location":[7.418498,43.734177],"bearings":[15,165,300],"entry":[false,true,false],"in":0},{"out":1,"location":[7.418626,43.733573],"bearings":[75,165,345],"entry":[true,true,false],"in":2},{"out":0,"location":[7.418893,43.732684],"bearings":[165,285,345],"entry":[true,true,false],"in":2}],"geometry":"si}iGgmhl@X`@p@bAzAlBrAvATTPRf@f@xBlBLJHFHFJFB@F@D@TC|AWdBYp@QXG\\O","mode":"driving","duration":33.5,"maneuver":{"bearing_after":220,"type":"turn","modifier":"slight left","bearing_before":243,"location":[7.421158,43.736744]},"weight":33.5,"distance":546.2,"name":"Rue Grimaldi"},{"intersections":[{"out":1,"location":[7.418966,43.732527],"bearings":[105,270,345],"entry":[false,true,false],"in":2}],"geometry":"io|iGq_hl@?D@B@@B@@@","mode":"driving","duration":4,"maneuver":{"exit":1,"bearing_after":262,"type":"roundabout","modifier":"right","bearing_before":160,"location":[7.418966,43.732527]},"weight":4,"distance":9.1,"name":"Avenue Prince Pierre"},{"intersections":[{"out":2,"location":[7.418894,43.732476],"bearings":[15,165,285],"entry":[false,true,true],"in":0},{"out":3,"location":[7.418047,43.732712],"bearings":[105,120,210,285],"entry":[false,true,true,true],"in":0},{"out":2,"location":[7.417614,43.733662],"bearings":[0,180,345],"entry":[true,false,true],"in":1}],"geometry":"_o|iGa_hl@Mp@Ml@QfAIb@Sv@GVEJKDG@QGi@UYOQCU@YH_@Ni@JGDEHKh@","mode":"driving","duration":17,"maneuver":{"exit":1,"bearing_after":291,"type":"exit roundabout","modifier":"right","bearing_before":188,"location":[7.418894,43.732476]},"weight":17,"distance":301.4,"name":"Avenue Prince Pierre"},{"intersections":[{"out":2,"location":[7.417132,43.734293],"bearings":[105,165,345],"entry":[false,true,true],"in":0}],"geometry":"iz|iGatgl@OBGB]@s@@i@Gg@SIEQMYWUUAA]]KMMQGOUgAGc@EWGQIQKOo@_Ak@w@MO","mode":"driving","duration":20.3,"maneuver":{"bearing_after":345,"type":"new name","modifier":"right","bearing_before":291,"location":[7.417132,43.734293]},"weight":20.3,"distance":369.8,"name":"Boulevard Rainier III"},{"intersections":[{"in":0,"entry":[true],"bearings":[217],"location":[7.419544,43.736803]}],"geometry":"_j}iGcchl@","mode":"driving","duration":0,"maneuver":{"bearing_after":0,"location":[7.419544,43.736803],"bearing_before":37,"type":"arrive"},"weight":0,"distance":0,"name":"Boulevard Rainier III"}],"distance":1999.8,"duration":144.8,"summary":"Tunnel Rocher Palais, Rue Grimaldi","weight":144.8}],"distance":1999.8,"duration":144.8,"weight_name":"routability","weight":144.8}],"waypoints":[{"hint":"cAAAgP___38PAAAAngAAAI0AAAAAAAAADwAAAJ4AAACNAAAAAAAAABUAAADrNnEAsUmbAm43cQDGSJsCAwBPBH1E6t8=","name":"Tunnel Rocher Palais","location":[7.419627,43.731377]},{"hint":"_wAAgKkCAIAFAAAAAQAAAMYAAAAAAAAABQAAAAEAAADGAAAAAAAAABUAAACYNnEA416bAnE2cQD5XpsCFwBfAn1E6t8=","name":"Boulevard Rainier III","location":[7.419544,43.736803]}]}
rburcham commented 7 years ago

According to gdb the segfault is happening in osrmc.cc, in osrmc_osrm_construct, when the call is made to

auto* out = new osrm::OSRM(*config_typed);

rburcham commented 7 years ago

So for sanity I went ahead and built the cpp example here

https://github.com/Project-OSRM/osrm-backend/blob/master/example/example.cpp

and aimed it at the monaco.osrm. It complains

$ ./example monaco.osrm
terminate called after throwing an instance of 'osrm::util::exception'
  what():  No shared memory block 'osrm-region' found, have you forgotten to run osrm-datastore?include/storage/shared_monitor.hpp:83
Aborted

which is confusing because the EngineConfig has

config.use_shared_memory = false;

The osrmc.cc similarly sets this to false. That said if I osrm-datastore it

$ sudo osrm-datastore ./monaco.osrm
Password: 
[info] Loading data into REGION_1
[info] load names from: "./monaco.osrm.names"
[info] Allocating shared memory of 1258434 bytes
[info] All data loaded. Notify all client about new data in REGION_1 with timestamp 1
[info] All clients switched.
$ ls -la /dev/shm/
total 16
drwxrwxrwt  2 root root    60 Sep 26 17:52 .
drwxr-xr-x 18 root root  3720 Sep 26 15:03 ..
-rw-r--r--  1 root root 16392 Sep 26 17:52 osrm-region
$ sudo ./example monaco.osrm
Segmentation fault

So this is confusing to me. I can get osrm-routed to work without shm.

The cpp example and wrapper seem to disable shm in the EngineConfig, but they complain at runtime until I prep a shm. Then they both segfault. There is something obvious I am missing here I'm sure.

daniel-j-h commented 7 years ago

Hm you are right - even though we always set use_shared_memory to false here:

https://github.com/daniel-j-h/libosrmc/blob/adad1e5e8e06ced68fd80c69085b2eda0e45bd4e/libosrmc/osrmc.cc#L40

which will then get passed to the constructor here

https://github.com/daniel-j-h/libosrmc/blob/adad1e5e8e06ced68fd80c69085b2eda0e45bd4e/libosrmc/osrmc.cc#L51

I just used a debugger and could see the use_shared_memory having a value of 255 in the OSRM object's constructor body:

https://github.com/daniel-j-h/libosrmc/blob/adad1e5e8e06ced68fd80c69085b2eda0e45bd4e/libosrmc/osrmc.cc#L52

https://github.com/Project-OSRM/osrm-backend/blob/master/src/osrm/osrm.cpp#L19

Hm :wave: @oxidase do you know if something here could be Undefined Behavior, otherwise I can't explain why we're use_shared_memory is not always false here.

rburcham commented 7 years ago

FWIW I get segfault upon OSRM instatiation whether or not use_shared_memory is true or false. So effectively the c wrapper and c++ example are no go atm.

oxidase commented 7 years ago

@rburcham if OSRM built and installed as a static library only then you need to configure as $(shell pkg-config --static --libs libosrm) or other way is to build OSRM with shared libraries with cmake -DBUILD_SHARED_LIBS=On option

/dev/shm/osrm-region is a shared memory control block and it is always 16392 bytes on the "current" Linux-based operating systems. The real shared memory block can be found in ipcs -m list.

@daniel-j-h i have some fixes, but can not push. for me it works with a shared memory block and with direct loding :sunglasses:

make -C ../libosrmc clean libosrmc.so  && python ./osrm_python2.py
make: Entering directory '/home/miha/mapbox/libosrmc/libosrmc'
g++ -O2 -Wall -Wextra -pedantic -std=c++11 -fvisibility=hidden -fPIC -fno-rtti -std=c++14 -DBOOST_TEST_DYN_LINK -DBOOST_SPIRIT_USE_PHOENIX_V3 -DBOOST_RESULT_OF_USE_DECLTYPE -DBOOST_FILESYSTEM_NO_DEPRECATED -I/home/miha/foss/boost -I/home/miha/foss/tbb-2018_U1/include -I/usr/include/lua5.2 -I/usr/local/include -I/usr/local/include/osrm   -c -o osrmc.o osrmc.cc
g++ -shared -Wl,-soname,libosrmc.so.5 -o libosrmc.so osrmc.o -lstdc++ -L/usr/local/lib -losrm -fuse-ld=gold -Wl,--disable-new-dtags -Wl,--gc-sections -Wl,-O1 -Wl,--hash-style=gnu -Wl,--sort-common
make: Leaving directory '/home/miha/mapbox/libosrmc/libosrmc'
Distance: 2000 meters
Duration: 145 seconds
Table
0s  54s 40s 79s 223s    229s    90s 203s    51s 275s    
172s    0s  150s    157s    281s    288s    148s    262s    179s    334s    
90s 107s    0s  51s 197s    203s    67s 178s    104s    249s    
152s    169s    155s    0s  259s    265s    128s    239s    165s    311s    
196s    213s    199s    153s    0s  113s    172s    20s 209s    159s    
209s    226s    212s    166s    132s    0s  185s    113s    222s    78s 
99s 41s 26s 66s 209s    215s    0s  190s    37s 261s    
176s    193s    179s    133s    19s 93s 152s    0s  189s    139s    
62s 77s 63s 30s 172s    178s    39s 153s    0s  224s    
130s    148s    134s    116s    180s    186s    107s    160s    144s    0s  
rburcham commented 7 years ago

@oxidase Thanks for the tip on making the so. I rebuilt libosrmc and osrm_python2.py still segfaults in osrmc.cc at

auto* out = new osrm::OSRM(*config_typed);

Rebuilding and relinking osrm_c89 and the c++ example both still complain

$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib ./example monaco.osrm
terminate called after throwing an instance of 'osrm::util::exception'
  what():  No shared memory block 'osrm-region' found, have you forgotten to run osrm-datastore?include/storage/shared_monitor.hpp:83
Aborted

despite the feature being explicitly set to false in the config. Then as before if I go ahead and prep the shm

$ sudo osrm-datastore ./monaco.osrm
[info] Loading data into REGION_1
[info] load names from: "./monaco.osrm.names"
[info] Allocating shared memory of 1258434 bytes
[info] All data loaded. Notify all client about new data in REGION_1 with timestamp 1
[info] All clients switched.

it segfaults. With the c_89 test harness it seems to be the call to route that segfaults. With the python harness it seems to be the instantiation of the OSRM object.

daniel-j-h commented 7 years ago

@rburcham could you try again with master after we merged https://github.com/daniel-j-h/libosrmc/pull/6#pullrequestreview-67732350.

rburcham commented 7 years ago

I applied the patches and things are somewhat cleaner. The error propagation now has the python wrapper exhibiting the same behavior as the c++ and c89 examples, that is, it complains that there is no shm block (even though we have it explicitly disabled in the config)

$ ./osrm_python2.py monaco.osrm
Traceback (most recent call last):
  File "./osrm_python2.py", line 54, in <module>
    main()
  File "./osrm_python2.py", line 17, in main
    osrm = OSRM(sys.argv[1] if len(sys.argv) >= 2 else None)
  File "/home/rob/workspace/libosrmc/bindings/osrmcpy.py", line 162, in __init__
    _.osrm = lib.osrmc_osrm_construct(_.config, c.byref(osrmc_error()))
  File "/home/rob/workspace/libosrmc/bindings/osrmcpy.py", line 28, in osrmc_error_errcheck
    raise RuntimeError(arguments[-1]._obj)
RuntimeError: No shared memory block 'osrm-region' found, have you forgotten to run osrm-datastore?include/storage/shared_monitor.hpp:83

And then segfaults when I go ahead and make one with osrm-datastore. I suspect the root cause for this is my TBB library version (2017.20170226), or possibly my boost (1.65.0), given that @oxidase is using custom builds for both. I'll next try to pull down a bleeding edge TBB and link libosrm against that.

daniel-j-h commented 7 years ago

What I can recommend doing is writing a Dockerfile with Ubuntu 16.04 as a base; see instructions here

then we can check what's going on in a reproducible way.

rburcham commented 7 years ago

Ok it was TBB. I updated to 2018_U1 (had to create an ebuild) and I am no longer segfaulting, and all bindings are working as expected.