-
Notifications
You must be signed in to change notification settings - Fork 4
Description
Problem
The MapViewer crashes with a segmentation fault shortly after startup when a client (e.g. erdblick) requests the /sources endpoint. The crash happens within 1-3 seconds of the HTTP server becoming available.
How to Reproduce
- Start MapViewer with any data source config (e.g. a filestore or NDS.Live source)
- Open erdblick immediately (or have the browser auto-open on startup)
- Erdblick calls
/sourcesto discover available data sources - Container crashes with signal 11
The crash is intermittent β it depends on the timing between server startup and the first /sources request. Slower data sources (NDS.Live, large filestores) increase the window.
Observed Behavior
[2026-03-16 18:29:30.451] Config changed. Removing previous datasources.
[2026-03-16 18:29:30.451] Launching NDS.Live datasource for URI filestore:/data/0/map.ndslive
[2026-03-16 18:29:30.468] Webapp: /app/erdblick
[2026-03-16 18:29:30.571] Could not start HttpServer on 0.0.0.0:8089 (timeout)
[2026-03-16 18:29:31.039] ====== Running on port 8089 ======
NDS MapViewer is ready!
[2026-03-16 18:29:32.946] CRASH DETECTED in mapviewer
[2026-03-16 18:29:32.946] Signal: 11 (segmentation fault)
Stack trace points to Service::info() called from handleSourcesRequest():
#2 mapget::Service::info(...)
#3 mapget::HttpService::Impl::handleSourcesRequest(...)
#4 drogon::internal::HttpBinder<...>::run(...)
Quick investigation results:
The dataSourceInfo_ map in Service::Impl (service.cpp) has no mutex protection:
- Write β
addDataSource()(line ~464):dataSourceInfo_[dataSource] = info;β no lock held - Read β
getDataSourceInfos()(line ~543): iterates the same map β no lock held
The config subscription callback (service.cpp:400-423) calls addDataSource() in a loop, adding sources one by one. Meanwhile, the HTTP server is already accepting requests. A concurrent read+write on std::map is undefined behavior.
Additionally, addDataSource() inserts into the map (line ~464) before workers are fully created (lines ~476-480), so even a single-source config can hit this if the request arrives during worker setup.
/status returns HTTP 200 as soon as the HTTP server binds, before data sources finish loading, which makes it easy for clients to start requesting /sources too early.
A std::shared_mutex around dataSourceInfo_ access (write lock in add/remove, read lock in getDataSourceInfos/getStatistics) would fix the race.